diff --git a/.github/labeler.yml b/.github/labeler.yml deleted file mode 100644 index 2a8192036..000000000 --- a/.github/labeler.yml +++ /dev/null @@ -1,29 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -# Pull request labeler Github Action Configuration: https://github.com/marketplace/actions/labeler -INFRA: - - changed-files: - - any-glob-to-any-file: [ - ".github/workflows/**/*", - ".github/labeler.yml", - ".asf.yaml", - ".gitattributes", - ".gitignore", - ".pre-commit-config.yaml", - "dev/**/*" - ] diff --git a/.github/workflows/go-release-docs.yml b/.github/workflows/go-release-docs.yml deleted file mode 100644 index 4574571dd..000000000 --- a/.github/workflows/go-release-docs.yml +++ /dev/null @@ -1,66 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# - -name: Website - -on: - push: - branches: - - main - pull_request: - branches: - - main - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} - cancel-in-progress: true - -permissions: - contents: read - -jobs: - build: - runs-on: ubuntu-slim - permissions: - contents: write - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Setup mdBook - uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2 - with: - mdbook-version: '0.4.36' - - - name: Build - working-directory: website - run: mdbook build - - - name: Copy file - run: | - cp .asf.yaml ./website/book/.asf.yaml - - - name: Deploy to gh-pages - uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 - if: github.event_name == 'push' && github.ref_name == 'main' - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: website/book - publish_branch: gh-pages diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml deleted file mode 100644 index 16aac23a5..000000000 --- a/.github/workflows/labeler.yml +++ /dev/null @@ -1,33 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# - -name: "Pull Request Labeler" -on: pull_request_target # zizmor: ignore[dangerous-triggers] - -permissions: - contents: read - pull-requests: write - -jobs: - triage: - runs-on: ubuntu-slim - steps: - - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6 - with: - sync-labels: true diff --git a/.github/workflows/license_check.yml b/.github/workflows/license_check.yml deleted file mode 100644 index 033461f30..000000000 --- a/.github/workflows/license_check.yml +++ /dev/null @@ -1,32 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -name: "Run License Check" -on: pull_request - -permissions: - contents: read - -jobs: - rat: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - run: | - dev/check-license diff --git a/.github/workflows/rc.yml b/.github/workflows/rc.yml deleted file mode 100644 index ae04b99fb..000000000 --- a/.github/workflows/rc.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -name: RC -on: - push: - tags: - - '*-rc*' - -concurrency: - group: ${{ github.repository }}-${{ github.head_ref || github.sha }}-${{ github.workflow }} - cancel-in-progress: true -permissions: - contents: read - -jobs: - archive: - name: Archive - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - name: Prepare for tag - run: | - # Remove the 'v' prefix and any '-rc' suffix from the tag name to isolate the version number - # For a tag like 'v0.1.0-rc1', this will result in '0.1.0' - version=${GITHUB_REF_NAME#v} - version=${version%-rc*} - # Finds the last occurrence of `-rc` and returns everything after it - # For a tag like 'v0.1.0-rc1', this will result in '1' - rc=${GITHUB_REF_NAME##*-rc} - echo "VERSION=${version}" >> ${GITHUB_ENV} - echo "RC=${rc}" >> ${GITHUB_ENV} - echo "VERSION=${version}" - echo "RC=${rc}" - - name: Archive - run: | - # tar.gz file has the format apache-iceberg-go--rc.tar.gz - # and contains a directory named apache-iceberg-go- with the source - dir="apache-iceberg-go-${VERSION}" - tar_gz="apache-iceberg-go-${VERSION}-rc${RC}.tar.gz" - git archive HEAD --prefix "${dir}/" --output "${tar_gz}" - sha512sum "${tar_gz}" > "${tar_gz}.sha512" - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: archive - path: | - apache-iceberg-go-* - - upload: - name: upload - needs: - - archive - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: archive - - name: Upload - run: | - # TODO: Add support for release notes - gh release create ${GITHUB_REF_NAME} \ - --prerelease \ - --title "Apache Iceberg Go ${GITHUB_REF_NAME}" \ - --generate-notes \ - --verify-tag \ - apache-iceberg-go-*.tar.gz \ - apache-iceberg-go-*.tar.gz.sha* - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/DataDog.md b/DataDog.md new file mode 100644 index 000000000..998bcf649 --- /dev/null +++ b/DataDog.md @@ -0,0 +1,31 @@ +# iceberg-go fork + +This fork of [iceberg-go](https://github.com/apache/iceberg-go) exists because it has a dependency on +[gocloud.dev](https://github.com/google/go-cloud) which has been problematic enough with many API breaking changes +that blocked important dependency upgrades in repos like [dd-go](https://github.com/DataDog/dd-go) and +[dd-source](https://github.com/DataDog/dd-source). + +Because of this, [the guideline](https://datadoghq.atlassian.net/wiki/spaces/ENG/pages/5335876583/Blob+storage+in+Go) +was put in place for anything that depends on gocloud.dev to vendor that dependency and +prevent it leaking through in our main repositories. + +# Synch with upstream +This README comes with tooling that will: +* Add the `go mod replace` directive to allow this fork to compile without any iceberg-go import changes +* Add `gocloud.dev` as a git subtree +* Rewrite `gocloud.dev` import paths + +This commit should include all that's needed to recreate a working fork from a fresh copy of iceberg-go. The idea being +that we could always just `git reset --hard` from the upstream repository, cherry-pick this commit and re-run the +`./initialize-fork.sh` to get the repo back to a up-to-date working state. Note that this approach would involve +rewriting git history and might be reserved in case the merging/rebasing from upstream is too messy or involved. + +To find the fork-initializing commit, look up the commit by the tag: +```shell +git rev-list -n 1 fork-initialization +``` + +# The Path To Irrelevance + +If [iceberg-go](https://github.com/apache/iceberg-go) ever breaks free from [gocloud.dev](https://github.com/google/go-cloud), we could potentially remove the +need for this fork and go back to the upstream repo. \ No newline at end of file diff --git a/catalog/catalog.go b/catalog/catalog.go index bfa573503..0bcc55ddb 100644 --- a/catalog/catalog.go +++ b/catalog/catalog.go @@ -35,9 +35,9 @@ import ( "maps" "strings" - "github.com/apache/iceberg-go" - iceinternal "github.com/apache/iceberg-go/internal" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + iceinternal "github.com/DataDog/iceberg-go/internal" + "github.com/DataDog/iceberg-go/table" ) type Type string diff --git a/catalog/example_multi_table_transaction_test.go b/catalog/example_multi_table_transaction_test.go index 8deff9161..a89ab3e77 100644 --- a/catalog/example_multi_table_transaction_test.go +++ b/catalog/example_multi_table_transaction_test.go @@ -23,9 +23,9 @@ import ( "fmt" "iter" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/table" ) // exampleCatalog is a minimal Catalog + TransactionalCatalog stub diff --git a/catalog/glue/glue.go b/catalog/glue/glue.go index bd95d3eba..2f74904f2 100644 --- a/catalog/glue/glue.go +++ b/catalog/glue/glue.go @@ -27,12 +27,12 @@ import ( "strings" _ "unsafe" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/internal" - "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/utils" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/internal" + "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/utils" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" @@ -560,7 +560,7 @@ func (c *Catalog) LoadNamespaceProperties(ctx context.Context, namespace table.I // avoid circular dependency while still avoiding having to export the getUpdatedPropsAndUpdateSummary function // so that we can re-use it in the catalog implementations without duplicating the code. -//go:linkname getUpdatedPropsAndUpdateSummary github.com/apache/iceberg-go/catalog.getUpdatedPropsAndUpdateSummary +//go:linkname getUpdatedPropsAndUpdateSummary github.com/DataDog/iceberg-go/catalog.getUpdatedPropsAndUpdateSummary func getUpdatedPropsAndUpdateSummary(currentProps iceberg.Properties, removals []string, updates iceberg.Properties) (iceberg.Properties, catalog.PropertiesUpdateSummary, error) // UpdateNamespaceProperties updates the properties of an Iceberg namespace in the Glue catalog. diff --git a/catalog/glue/glue_test.go b/catalog/glue/glue_test.go index f115720db..b83279f81 100644 --- a/catalog/glue/glue_test.go +++ b/catalog/glue/glue_test.go @@ -29,10 +29,10 @@ import ( "testing" "time" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - _ "github.com/apache/iceberg-go/io/gocloud" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + _ "github.com/DataDog/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go/table" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/glue" diff --git a/catalog/glue/schema.go b/catalog/glue/schema.go index 84916a15c..ab28bcdf1 100644 --- a/catalog/glue/schema.go +++ b/catalog/glue/schema.go @@ -24,8 +24,8 @@ import ( "strconv" "strings" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/glue/types" ) diff --git a/catalog/glue/schema_test.go b/catalog/glue/schema_test.go index 04f5dd74f..96855d74d 100644 --- a/catalog/glue/schema_test.go +++ b/catalog/glue/schema_test.go @@ -20,8 +20,8 @@ package glue import ( "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/glue/types" "github.com/stretchr/testify/assert" diff --git a/catalog/hive/hive.go b/catalog/hive/hive.go index ff2f40818..d7481b30e 100644 --- a/catalog/hive/hive.go +++ b/catalog/hive/hive.go @@ -26,12 +26,12 @@ import ( "strings" _ "unsafe" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/internal" - "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/view" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/internal" + "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/view" "github.com/beltran/gohive/hive_metastore" ) @@ -774,7 +774,7 @@ func (c *Catalog) LoadNamespaceProperties(ctx context.Context, namespace table.I return props, nil } -//go:linkname getUpdatedPropsAndUpdateSummary github.com/apache/iceberg-go/catalog.getUpdatedPropsAndUpdateSummary +//go:linkname getUpdatedPropsAndUpdateSummary github.com/DataDog/iceberg-go/catalog.getUpdatedPropsAndUpdateSummary func getUpdatedPropsAndUpdateSummary(currentProps iceberg.Properties, removals []string, updates iceberg.Properties) (iceberg.Properties, catalog.PropertiesUpdateSummary, error) // UpdateNamespaceProperties updates the properties for a namespace. diff --git a/catalog/hive/hive_integration_test.go b/catalog/hive/hive_integration_test.go index 199aaa9ca..a35f0f0b1 100644 --- a/catalog/hive/hive_integration_test.go +++ b/catalog/hive/hive_integration_test.go @@ -27,10 +27,10 @@ import ( "testing" "time" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/view" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/view" "github.com/stretchr/testify/require" ) diff --git a/catalog/hive/hive_test.go b/catalog/hive/hive_test.go index f0d2b3b20..2d3bbaf6d 100644 --- a/catalog/hive/hive_test.go +++ b/catalog/hive/hive_test.go @@ -24,10 +24,10 @@ import ( "strings" "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/view" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/view" "github.com/beltran/gohive/hive_metastore" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" diff --git a/catalog/hive/options.go b/catalog/hive/options.go index e38643387..2c4c1b6ed 100644 --- a/catalog/hive/options.go +++ b/catalog/hive/options.go @@ -21,7 +21,7 @@ import ( "strconv" "time" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" ) const ( diff --git a/catalog/hive/schema.go b/catalog/hive/schema.go index 310d7c7f8..f90681150 100644 --- a/catalog/hive/schema.go +++ b/catalog/hive/schema.go @@ -22,7 +22,7 @@ import ( "fmt" "strings" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/beltran/gohive/hive_metastore" ) diff --git a/catalog/internal/utils.go b/catalog/internal/utils.go index 6e1f2b393..4ebb8b632 100644 --- a/catalog/internal/utils.go +++ b/catalog/internal/utils.go @@ -31,11 +31,11 @@ import ( "strconv" "strings" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/internal" - icebergio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/internal" + icebergio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" "github.com/google/uuid" ) diff --git a/catalog/multi_table_transaction.go b/catalog/multi_table_transaction.go index f5829cc13..21c289c69 100644 --- a/catalog/multi_table_transaction.go +++ b/catalog/multi_table_transaction.go @@ -24,7 +24,7 @@ import ( "slices" "strings" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go/table" ) // MultiTableTransaction collects changes across multiple tables and diff --git a/catalog/multi_table_transaction_test.go b/catalog/multi_table_transaction_test.go index 147505bd6..c1cdaa9e1 100644 --- a/catalog/multi_table_transaction_test.go +++ b/catalog/multi_table_transaction_test.go @@ -23,8 +23,8 @@ import ( "iter" "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/catalog/registry.go b/catalog/registry.go index 58b921aa2..80c2b9313 100644 --- a/catalog/registry.go +++ b/catalog/registry.go @@ -26,8 +26,8 @@ import ( "strings" "sync" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/config" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/config" ) type registry map[string]Registrar diff --git a/catalog/registry_test.go b/catalog/registry_test.go index 5bf7d67cb..038ae19d6 100644 --- a/catalog/registry_test.go +++ b/catalog/registry_test.go @@ -25,11 +25,11 @@ import ( "net/url" "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - _ "github.com/apache/iceberg-go/catalog/glue" - "github.com/apache/iceberg-go/catalog/rest" - "github.com/apache/iceberg-go/config" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + _ "github.com/DataDog/iceberg-go/catalog/glue" + "github.com/DataDog/iceberg-go/catalog/rest" + "github.com/DataDog/iceberg-go/config" "github.com/stretchr/testify/assert" ) diff --git a/catalog/rest/options.go b/catalog/rest/options.go index 2cfbb5911..5d571136d 100644 --- a/catalog/rest/options.go +++ b/catalog/rest/options.go @@ -22,7 +22,7 @@ import ( "net/http" "net/url" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/aws/aws-sdk-go-v2/aws" ) diff --git a/catalog/rest/rest.go b/catalog/rest/rest.go index 3c4736845..f17908f06 100644 --- a/catalog/rest/rest.go +++ b/catalog/rest/rest.go @@ -36,11 +36,11 @@ import ( "strings" "time" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/view" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/view" "github.com/aws/aws-sdk-go-v2/aws" v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/config" diff --git a/catalog/rest/rest_integration_test.go b/catalog/rest/rest_integration_test.go index c0a7d2179..d6f8f32b2 100644 --- a/catalog/rest/rest_integration_test.go +++ b/catalog/rest/rest_integration_test.go @@ -28,13 +28,13 @@ import ( "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/rest" - "github.com/apache/iceberg-go/io" - _ "github.com/apache/iceberg-go/io/gocloud" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/view" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/rest" + "github.com/DataDog/iceberg-go/io" + _ "github.com/DataDog/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/view" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" ) diff --git a/catalog/rest/rest_test.go b/catalog/rest/rest_test.go index 8cba0ea49..70006d131 100644 --- a/catalog/rest/rest_test.go +++ b/catalog/rest/rest_test.go @@ -29,11 +29,11 @@ import ( "strconv" "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/rest" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/view" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/rest" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/view" "github.com/google/uuid" "github.com/stretchr/testify/suite" ) diff --git a/catalog/rest/vended_creds.go b/catalog/rest/vended_creds.go index 958a2db2d..45eb0e9a7 100644 --- a/catalog/rest/vended_creds.go +++ b/catalog/rest/vended_creds.go @@ -24,8 +24,8 @@ import ( "strings" "time" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" "golang.org/x/sync/semaphore" ) diff --git a/catalog/rest/vended_creds_test.go b/catalog/rest/vended_creds_test.go index 2fdf08769..44948d83e 100644 --- a/catalog/rest/vended_creds_test.go +++ b/catalog/rest/vended_creds_test.go @@ -26,8 +26,8 @@ import ( "testing" "time" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/sync/semaphore" diff --git a/catalog/sql/sql.go b/catalog/sql/sql.go index 03fab31ea..7a4e9f280 100644 --- a/catalog/sql/sql.go +++ b/catalog/sql/sql.go @@ -29,12 +29,12 @@ import ( "sync" _ "unsafe" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/internal" - "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/view" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/internal" + "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/view" "github.com/uptrace/bun" "github.com/uptrace/bun/dialect/feature" "github.com/uptrace/bun/dialect/mssqldialect" @@ -749,7 +749,7 @@ func (c *Catalog) ListNamespaces(ctx context.Context, parent table.Identifier) ( // avoid circular dependency while still avoiding having to export the getUpdatedPropsAndUpdateSummary function // so that we can re-use it in the catalog implementations without duplicating the code. -//go:linkname getUpdatedPropsAndUpdateSummary github.com/apache/iceberg-go/catalog.getUpdatedPropsAndUpdateSummary +//go:linkname getUpdatedPropsAndUpdateSummary github.com/DataDog/iceberg-go/catalog.getUpdatedPropsAndUpdateSummary func getUpdatedPropsAndUpdateSummary(currentProps iceberg.Properties, removals []string, updates iceberg.Properties) (iceberg.Properties, catalog.PropertiesUpdateSummary, error) func (c *Catalog) UpdateNamespaceProperties(ctx context.Context, namespace table.Identifier, removals []string, updates iceberg.Properties) (catalog.PropertiesUpdateSummary, error) { diff --git a/catalog/sql/sql_integration_test.go b/catalog/sql/sql_integration_test.go index 82f83bbac..f5c002fc6 100644 --- a/catalog/sql/sql_integration_test.go +++ b/catalog/sql/sql_integration_test.go @@ -30,12 +30,12 @@ import ( "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/sql" - "github.com/apache/iceberg-go/io" - _ "github.com/apache/iceberg-go/io/gocloud" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/sql" + "github.com/DataDog/iceberg-go/io" + _ "github.com/DataDog/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/suite" ) diff --git a/catalog/sql/sql_test.go b/catalog/sql/sql_test.go index feac9308c..e0882b467 100644 --- a/catalog/sql/sql_test.go +++ b/catalog/sql/sql_test.go @@ -32,12 +32,12 @@ import ( "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/internal" - sqlcat "github.com/apache/iceberg-go/catalog/sql" - _ "github.com/apache/iceberg-go/io/gocloud" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/internal" + sqlcat "github.com/DataDog/iceberg-go/catalog/sql" + _ "github.com/DataDog/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "github.com/uptrace/bun/driver/sqliteshim" diff --git a/cmd/iceberg/compact.go b/cmd/iceberg/compact.go index dd9ee553e..def458c80 100644 --- a/cmd/iceberg/compact.go +++ b/cmd/iceberg/compact.go @@ -23,9 +23,9 @@ import ( "os" "strconv" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/table/compaction" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/table/compaction" "github.com/pterm/pterm" ) diff --git a/cmd/iceberg/main.go b/cmd/iceberg/main.go index 617405255..4d143e23d 100644 --- a/cmd/iceberg/main.go +++ b/cmd/iceberg/main.go @@ -29,14 +29,14 @@ import ( "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/parquet/file" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/glue" - "github.com/apache/iceberg-go/catalog/hive" - "github.com/apache/iceberg-go/catalog/rest" - "github.com/apache/iceberg-go/config" - _ "github.com/apache/iceberg-go/io/gocloud" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/glue" + "github.com/DataDog/iceberg-go/catalog/hive" + "github.com/DataDog/iceberg-go/catalog/rest" + "github.com/DataDog/iceberg-go/config" + _ "github.com/DataDog/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go/table" awsconfig "github.com/aws/aws-sdk-go-v2/config" "github.com/docopt/docopt-go" diff --git a/cmd/iceberg/output.go b/cmd/iceberg/output.go index 695ba28d9..72bdef255 100644 --- a/cmd/iceberg/output.go +++ b/cmd/iceberg/output.go @@ -26,8 +26,8 @@ import ( "strconv" "strings" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" "github.com/google/uuid" "github.com/pterm/pterm" diff --git a/cmd/iceberg/output_test.go b/cmd/iceberg/output_test.go index 3cb20196e..dbeb4a373 100644 --- a/cmd/iceberg/output_test.go +++ b/cmd/iceberg/output_test.go @@ -22,7 +22,7 @@ import ( "os" "testing" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go/table" "github.com/pterm/pterm" "github.com/stretchr/testify/assert" ) diff --git a/cmd/iceberg/utils.go b/cmd/iceberg/utils.go index 05014dbb6..b6a0f41da 100644 --- a/cmd/iceberg/utils.go +++ b/cmd/iceberg/utils.go @@ -21,8 +21,8 @@ import ( "fmt" "strings" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" ) func parseProperties(propStr string) (iceberg.Properties, error) { diff --git a/cmd/iceberg/utils_test.go b/cmd/iceberg/utils_test.go index ce1868b6a..29f7336a6 100644 --- a/cmd/iceberg/utils_test.go +++ b/cmd/iceberg/utils_test.go @@ -21,8 +21,8 @@ import ( "maps" "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/require" ) diff --git a/exprs_test.go b/exprs_test.go index 1bb9c3f09..4d4b483bb 100644 --- a/exprs_test.go +++ b/exprs_test.go @@ -22,7 +22,7 @@ import ( "strconv" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/go-cloud/.codecov.yml b/go-cloud/.codecov.yml new file mode 100644 index 000000000..0c7faa375 --- /dev/null +++ b/go-cloud/.codecov.yml @@ -0,0 +1,15 @@ +codecov: + token: 47dfd1fc-dc72-4d25-b608-eca6508efd05 + +coverage: + status: + project: + default: + target: 0 + threshold: null + base: auto + patch: + default: + target: 0 + threshold: null + base: auto diff --git a/go-cloud/.gitattributes b/go-cloud/.gitattributes new file mode 100644 index 000000000..53379ace9 --- /dev/null +++ b/go-cloud/.gitattributes @@ -0,0 +1,8 @@ +* text eol=lf +*.png -text +samples/order/testdata/* -text +/internal/website/data/examples.json linguist-generated=true +**/testdata/**/*.yaml linguist-generated=true +**/testdata/**/*.replay linguist-generated=true +*.replay binary + diff --git a/go-cloud/.github/ISSUE_TEMPLATE/bug_report.md b/go-cloud/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..bef5b38c8 --- /dev/null +++ b/go-cloud/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,32 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +Please use a title starting with the name of the affected package, or \"all\", +followed by a colon, followed by a short summary of the issue. Example: +`blob/gcsblob: not blobby enough`. + +You can use `go bug` to have a cool, automatically filled out bug template, or +fill out the template below. + +### Describe the bug + +A clear and concise description of what the bug is. + +### To Reproduce + +Steps to reproduce the behavior. + +## Expected behavior + +A clear and concise description of what you expected to happen. + +### Version + +Which version(s) of the Go Cloud modules are you seeing the bug with? + +### Additional context + +Add any other context about the problem here. diff --git a/go-cloud/.github/ISSUE_TEMPLATE/feature_request.md b/go-cloud/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..c44b7206e --- /dev/null +++ b/go-cloud/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,27 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +Please use a title starting with the name of the affected package, or \"all\", +followed by a colon, followed by a short summary of the feature request. +Example: `blob/gcsblob: add support for more blobbing`. + +### Is your feature request related to a problem? Please describe. + +A clear and concise description of what the problem is. Ex. I'm always +frustrated when [...] + +### Describe the solution you'd like + +A clear and concise description of what you want to happen. + +### Describe alternatives you've considered + +A clear and concise description of any alternative solutions or features you've +considered. + +### Additional context + +Add any other context or screenshots about the feature request here. diff --git a/go-cloud/.github/pull_request_template.md b/go-cloud/.github/pull_request_template.md new file mode 100644 index 000000000..ca9c445db --- /dev/null +++ b/go-cloud/.github/pull_request_template.md @@ -0,0 +1,9 @@ +Please use a title starting with the name of the affected package, or \"all\", +followed by a colon, followed by a short summary of the issue. Example: +`blob/gcsblob: fix typo in documentation`. + +Please reference any Issue related to this Pull Request. Example: `Fixes #1`. + +See +[here](https://blog.github.com/2015-01-21-how-to-write-the-perfect-pull-request/) +for tips on good Pull Request description. diff --git a/go-cloud/.github/workflows/tests.yml b/go-cloud/.github/workflows/tests.yml new file mode 100644 index 000000000..953944c75 --- /dev/null +++ b/go-cloud/.github/workflows/tests.yml @@ -0,0 +1,51 @@ +# Copyright 2021 The Go Cloud Development Kit 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 +# +# https://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. + +name: tests +on: [push, pull_request] +jobs: + build: + strategy: + fail-fast: false + matrix: + # Note: we used to include windows-latest, but it's super + # flaky on Github runners, lots of OOMs. + os: [ubuntu-latest, macos-latest] + # When updating this, make sure to also update the + # latest_go_version variable in internal/testing/runchecks.sh. + go-version: [1.24.x] + include: + - go-version: 1.23.x + os: ubuntu-latest + + runs-on: ${{ matrix.os }} + steps: + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go-version }} + - name: Checkout code + uses: actions/checkout@v2 + with: + fetch-depth: 2 # required for codecov + - name: Run Tests + shell: bash + run: 'internal/testing/runchecks.sh' + - if: matrix.os == 'ubuntu-latest' + name: Build for dragonfly + run: | + go install ./... + env: + GOARCH: amd64 + GOOS: dragonfly diff --git a/go-cloud/.gitignore b/go-cloud/.gitignore new file mode 100644 index 000000000..b43b3ddee --- /dev/null +++ b/go-cloud/.gitignore @@ -0,0 +1,82 @@ +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib +/internal/contributebot/contributebot +/internal/cmd/gocdk/gocdk +/internal/website/gatherexamples/gatherexamples +/internal/website/public/ +/internal/testing/test-summary/test-summary +/samples/gocdk-blob/gocdk-blob +/samples/gocdk-docstore/gocdk-docstore +/samples/gocdk-pubsub/gocdk-pubsub +/samples/gocdk-runtimevar/gocdk-runtimevar +/samples/gocdk-secrets/gocdk-secrets +/samples/guestbook/guestbook +/samples/guestbook/gcp/guestbook +/samples/tutorial/tutorial +/samples/tutorial/upload + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ + +# Go vendor directory +vendor/ + +# Populated config files +/internal/contributebot/dev/ +/internal/contributebot/webhook/app.yaml +/tests/gcp/app/gcp-test.yaml + +# Cryptographic keys +*.pem + +# Terraform Temporary Files +*.tfstate +*.tfstate.* +.terraform/ +terraform.tfvars + +# OSX leaves these everywhere on SMB shares +._* + +# OSX stuff +.DS_Store + +# Eclipse files +.classpath +.project +.settings/** + +# Files generated by JetBrains IDEs, e.g. Goland +.idea/ +*.iml + +# VSCode files +.vscode + +# Emacs save files +*~ +\#*\# +.\#* + +# Vim-related files +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +*.un~ +Session.vim +.netrwhist + +# Mercurial files +**/.hg +**/.hg* + +# runtimevar/etcdvar tests create this directory. +runtimevar/etcdvar/default.etcd diff --git a/go-cloud/.vscode/settings.json b/go-cloud/.vscode/settings.json new file mode 100644 index 000000000..a462222da --- /dev/null +++ b/go-cloud/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "search.exclude": { + "**/*.replay": true, + "**/testdata/**/*.yaml": true + } +} \ No newline at end of file diff --git a/go-cloud/.vscode/tasks.json b/go-cloud/.vscode/tasks.json new file mode 100644 index 000000000..9067a19f5 --- /dev/null +++ b/go-cloud/.vscode/tasks.json @@ -0,0 +1,16 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Test", + "type": "shell", + "command": "internal/testing/runchecks.sh", + "group": { + "kind": "test", + "isDefault": true + } + } + ] +} diff --git a/go-cloud/AUTHORS b/go-cloud/AUTHORS new file mode 100644 index 000000000..6337384cd --- /dev/null +++ b/go-cloud/AUTHORS @@ -0,0 +1,24 @@ +# This is the official list of Go Cloud Development Kit authors for copyright +# purposes. +# This file is distinct from the CONTRIBUTORS files. +# See the latter for an explanation. + +# Names should be added to this file as one of +# Organization's name +# Individual's name +# Individual's name +# See CONTRIBUTORS for the meaning of multiple email addresses. + +# Please keep the list sorted. + +Andrey Chernov +Ben Hinchley +Boris Popovschi +Gerasimos (Makis) Maropoulos +Google LLC +Oleg Kovalov +oliverpool +Sendil Kumar N +Steve Jiang +Vishal Saroopchand +Zachary Romero diff --git a/go-cloud/CODE_OF_CONDUCT.md b/go-cloud/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..3a8545ecc --- /dev/null +++ b/go-cloud/CODE_OF_CONDUCT.md @@ -0,0 +1,10 @@ +# Code of Conduct + +This project is covered under the [Go Code of Conduct][]. In summary: + +- Treat everyone with respect and kindness. +- Be thoughtful in how you communicate. +- Don’t be destructive or inflammatory. +- If you encounter an issue, please mail conduct@golang.org. + +[Go Code of Conduct]: https://golang.org/conduct diff --git a/go-cloud/CONTRIBUTING.md b/go-cloud/CONTRIBUTING.md new file mode 100644 index 000000000..f77062b1a --- /dev/null +++ b/go-cloud/CONTRIBUTING.md @@ -0,0 +1,217 @@ +# How to Contribute + +We would love to accept your patches and contributions to this project. Here is +how you can help. + +## Filing issues + +Filing issues is an important way you can contribute to the Go Cloud Development +Kit. We want your feedback on things like bugs, desired API changes, or just +anything that isn't working for you. + +### Bugs + +If your issue is a bug, open one +[here](https://github.com/google/go-cloud/issues/new). The easiest way to file +an issue with all the right information is to run `go bug`. `go bug` will print +out a handy template of questions and system information that will help us get +to the root of the issue quicker. Please start the title of your bug with the +name of the affected package, followed by a colon, followed by a short summary +of the issue, like "blob/gcsblob: not blobby enough". + +### Changes + +Unlike the core Go project, we do not have a formal proposal process for +changes. If you have a change you would like to see in the Go CDK, please file +an issue with the necessary details. + +### Triaging + +The Go CDK team triages issues at least every two weeks, but usually within two +business days. Issues that we would like to address, but do not have time for +are placed into the [Unplanned][] milestone. + +[Unplanned]: https://github.com/google/go-cloud/milestone/2 + +## Contributing Code + +We love accepting contributions! If your change is minor, please feel free +to submit a [pull request](https://help.github.com/articles/about-pull-requests/). +If your change is larger, or adds a feature, please file an issue beforehand so +that we can discuss the change. You're welcome to file an implementation pull +request immediately as well, although we generally lean towards discussing the +change and then reviewing the implementation separately. + +Be sure to take a look at the [internal docs][], which include more information +about conventions and design patterns found in the project. + +[internal docs]: internal/docs/README.md + +### Finding something to work on + +If you want to write some code, but don't know where to start or what you might +want to do, take a look at the [Good First Issue] label and our [Unplanned][] +milestone. The latter is where you can find issues we would like to address, but +can't currently find time for. See if any of the latest ones look interesting! +If you need help before you can start work, you can comment on the issue, and we +will try to help as best we can. + +[Good First Issue]: https://github.com/google/go-cloud/labels/good%20first%20issue + +### Contributor License Agreement + +Contributions to this project can only be made by those who have signed Google's +Contributor License Agreement. You (or your employer) retain the copyright to +your contribution, so this simply gives us permission to use and redistribute your +contributions as part of the project. Head over to + to see your current agreements on file or +to sign a new one. + +As a personal contributor, you only need to sign the Google CLA once across all +Google projects. If you've already signed the CLA, there is no need to do it +again. If you are submitting code on behalf of your employer, there's +[a separate corporate CLA that your employer manages for you](https://opensource.google.com/docs/cla/#external-contributors). + +### A Warning About Tests + +Tests that interact with cloud providers are written using a replay method, +where the test is run and actually performs the operations, and the +requests/results of the operations are stored in a replay file. This replay file +is then read back in unit tests on Travis, so the tests get to operate with real +data. Unfortunately, while the Go CDK team can generate these replay files +against our test cloud infrastructure, it is not yet possible for external +contributors to do the same. We want to improve this process in the future and +are researching how we can do this. If you have any ideas, please +[file an issue](https://github.com/google/go-cloud/issues/new)! + +#### Writing and running tests against a cloud environment + +If you can create cloud resources, setup your authentication using either `aws` +or `gcloud` and set the default project as the test project. Most tests will +have constants defining the resource names they use (for example, for `blob` +tests, the bucket name); update the constant and then run `go test -record`. New +replay files will be generated. This uses API quota and will create and delete +cloud resources. Replay files scrub sensitive information. +[Send your PR](#making-a-pull-request) without the replay files, and we can +generate new ones to be used by others. + +### Dependencies + +The Go CDK has a policy to depend only on code licensed under one of the +[`notice`][notice licenses], [`permissive`][permissive licenses], or +[`unencumbered`][unencumbered licenses] categories in the +[Google Open Source Licenses][] documentation. This is enforced with a +Travis build check that verifies that every dependency is in the +[`alldeps` file][]. Do not add new direct or indirect dependencies to the Go CDK +unless you have verified that the dependency is released under an acceptable +license. + +[`alldeps` file]: https://github.com/google/go-cloud/blob/master/internal/testing/alldeps +[notice licenses]: https://opensource.google.com/docs/thirdparty/licenses/#notice +[permissive licenses]: https://opensource.google.com/docs/thirdparty/licenses/#permissive +[unencumbered licenses]: https://opensource.google.com/docs/thirdparty/licenses/#unencumbered +[Google Open Source Licenses]: https://opensource.google.com/docs/thirdparty/licenses/ + +## Making a pull request + +* Follow the normal + [pull request flow](https://help.github.com/articles/creating-a-pull-request/). +* Build your changes using Go 1.11 with Go modules enabled. The Go CDK's + continuous integration uses Go modules in order to ensure + [reproducible builds](https://research.swtch.com/vgo-repro). +* Test your changes using `go test ./...`. Please add tests that show the + change does what it says it does, even if there wasn't a test in the first + place. Don't add the replay files to your commits. +* Feel free to make as many commits as you want; we will squash them all into + a single commit before merging your change. +* Check the diffs, write a useful description (including something like + `Fixes #123` if it's fixing a bug) and send the PR out. Please start the + title of your pull request with the name of the affected package, followed + by a colon, followed by a short summary of the change, like "blob/gcsblob: + add more tests". +* [Travis CI](http://travis-ci.com) will run tests against the PR. This should + happen within 10 minutes or so. If a test fails, go back to the coding stage + and try to fix the test and push the same branch again. You won't need to + make a new pull request, the changes will be rolled directly into the PR you + already opened. Wait for Travis again. There is no need to assign a reviewer + to the PR, the project team will assign someone for review during the + standard [triage](#triaging) process. + +## Code review + +All submissions, including submissions by project members, require review. It is +almost never the case that a pull request is accepted without some changes +requested, so please do not be offended! + +When you have finished making requested changes to your pull request, please +make a comment containing "PTAL" (Please Take Another Look) on your pull +request. GitHub notifications can be noisy, and it is unfortunately easy for +things to be lost in the shuffle. + +Once your PR is approved (hooray!), the reviewer will squash your commits into a +single commit and then merge the commit onto the Go CDK master branch. Thank +you! + +## Github code review workflow conventions + +(For project members and frequent contributors.) + +As a contributor: + +- Try hard to make each Pull Request as small and focused as possible. In + particular, this means that if a reviewer asks you to do something that is + beyond the scope of the Pull Request, the best practice is to file another + issue and reference it from the Pull Request rather than just adding more + commits to the existing PR. +- Adding someone as a Reviewer means "please feel free to look and comment"; + the review is optional. Choose as many Reviewers as you'd like. +- Adding someone as an Assignee means that the Pull Request should not be + submitted until they approve. If you choose multiple Assignees, wait until + all of them approve. It is fine to ask someone if they are OK with being + removed as an Assignee. + - Note that if you don't select any assignees, ContributeBot will turn all + of your Reviewers into Assignees. +- Make as many commits as you want locally, but try not to push them to Github + until you've addressed comments; this allows the email notification about + the push to be a signal to reviewers that the PR is ready to be looked at + again. +- When there may be confusion about what should happen next for a PR, be + explicit; add a "PTAL" comment if it is ready for review again, or a "Please + hold off on reviewing for now" if you are still working on addressing + comments. +- "Resolve" comments that you are sure you've addressed; let your reviewers + resolve ones that you're not sure about. +- Do not use `git push --force`; this can cause comments from your reviewers + that are associated with a specific commit to be lost. This implies that + once you've sent a Pull Request, you should use `git merge` instead of `git + rebase` to incorporate commits from the master branch. +- Travis checks will fail if you haven't run `gofmt -w -s`. +- Travis checks will fail if your PR has backwards-incompatible changes, + unless one of your commits has the strings `BREAKING_CHANGE_OK` in the first + line of the commit message. + +As a reviewer: + +- Be timely in your review process, especially if you are an Assignee. +- Try to use `Start a Review` instead of single comments, to reduce email + spam. +- "Resolve" your own comments if they have been addressed. +- If you want your review to be blocking, and are not currently an Assignee, + add yourself as an Assignee. + +When squashing-and-merging: + +- Ensure that **all** of the Assignees have approved. +- Do a final review of the one-line PR summary, ensuring that it meets the + guidelines (e.g., "blob: add more blobbing") and accurately describes the + change. +- Mark breaking changes with `BREAKING_CHANGE` in the commit message (e.g., + "blob: BREAKING_CHANGE remove old blob"). + - If the PR includes a breaking change, it will be declared via a commit + with `BREAKING_CHANGE_OK` in it (see Contributor section above). + - You can omit the marker if the change is technically breaking, but not + expected to affect users (e.g., it's a breaking change to an object that + wasn't in the last tagged release, or it's a change to a portable API + function that's only expected to be used by driver implementations). +- Delete the automatically added commit lines; these are generally not + interesting and make commit history harder to read. diff --git a/go-cloud/CONTRIBUTORS b/go-cloud/CONTRIBUTORS new file mode 100644 index 000000000..af7af3a52 --- /dev/null +++ b/go-cloud/CONTRIBUTORS @@ -0,0 +1,49 @@ +# This is the official list of people who can contribute +# (and typically have contributed) code to the Go CDK repository. +# The AUTHORS file lists the copyright holders; this file +# lists people. For example, Google employees are listed here +# but not in AUTHORS, because Google holds the copyright. +# +# Names should be added to this file only after verifying that +# the individual or the individual's organization has agreed to +# the appropriate Contributor License Agreement, found here: +# +# http://code.google.com/legal/individual-cla-v1.0.html +# http://code.google.com/legal/corporate-cla-v1.0.html +# +# The agreement for individuals can be filled out on the web. +# +# When adding J Random Contributor's name to this file, +# either J's name or J's organization's name should be +# added to the AUTHORS file, depending on whether the +# individual or corporate CLA was used. + +# Names should be added to this file like so: +# Individual's name +# Individual's name +# +# An entry with multiple email addresses specifies that the +# first address should be used in the submit logs and +# that the other addresses should be recognized as the +# same person when interacting with Git. + +# Please keep the list sorted. + +Andrey Chernov +Ben Hinchley +Boris Popovschi +Chris Lewis +Eno Compton +Gerasimos (Makis) Maropoulos +Issac Trotts +Oleg Kovalov +oliverpool +Robert van Gent +Ross Light +Sendil Kumar N +Steve Jiang +Tuo Shan +Tyler Bui-Palsulich <26876514+tbpg@users.noreply.github.com> +Vishal Saroopchand +Vivek Sekhar +Zachary Romero diff --git a/go-cloud/LICENSE b/go-cloud/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/go-cloud/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/go-cloud/README.md b/go-cloud/README.md new file mode 100644 index 000000000..40277c098 --- /dev/null +++ b/go-cloud/README.md @@ -0,0 +1,147 @@ +# The Go Cloud Development Kit (Go CDK) + +_Write once, run on any cloud ☁️_ + +[![Build Status](https://github.com/google/go-cloud/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/google/go-cloud/actions) +[![Go Report Card](https://goreportcard.com/badge/github.com/google/go-cloud)](https://goreportcard.com/report/github.com/google/go-cloud) +[![PkgGoDev](https://pkg.go.dev/badge/mod/gocloud.dev)][PkgGoDev] +[![Coverage](https://codecov.io/gh/google/go-cloud/branch/master/graph/badge.svg)](https://codecov.io/gh/google/go-cloud) +![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/google/go-cloud) +[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) + +

+ +

+ +The Go Cloud Development Kit (Go CDK) allows Go application developers to +seamlessly deploy cloud applications on any combination of cloud providers. It +does this by providing stable, idiomatic interfaces for common uses like storage +and databases. Think `database/sql` for cloud products. + +Imagine writing this to read from blob storage (like Google Cloud Storage or +S3): + +```go +ctx := context.Background() +bucket, err := blob.OpenBucket(ctx, "s3://my-bucket") +if err != nil { + return err +} +defer bucket.Close() +blobReader, err := bucket.NewReader(ctx, "my-blob", nil) +if err != nil { + return err +} +``` + +and being able to run that code on any cloud you want, avoiding all the ceremony +of cloud-specific authorization, tracing, SDKs and all the other code required +to make an application portable across cloud platforms. + +The project works well with a code generator called +[Wire](https://github.com/google/wire/blob/master/README.md). It creates +human-readable code that only imports the cloud SDKs for services you use. This +allows the Go CDK to grow to support any number of cloud services, without +increasing compile times or binary sizes, and avoiding any side effects from +`init()` functions. + +You can learn more about the project from our [announcement blog post][], or our +talk at Next 2018: + +[![Video: Building Go Applications for the Open Cloud (Cloud Next '18)](https://img.youtube.com/vi/_2ZwhvIkgek/0.jpg)][video] + +[announcement blog post]: https://blog.golang.org/go-cloud +[PkgGoDev]: https://pkg.go.dev/mod/gocloud.dev +[travis]: https://travis-ci.com/google/go-cloud +[video]: https://www.youtube.com/watch?v=_2ZwhvIkgek + +## Installation + +```shell +# First "cd" into your project directory if you have one to ensure "go get" uses +# Go modules (or not) appropriately. See "go help modules" for more info. +go get gocloud.dev +``` + +The Go CDK builds at the latest stable release of Go. Previous Go versions may +compile but are not supported. + +## Documentation + +Documentation for the project lives primarily on https://gocloud.dev/, including +[tutorials][]. + +You can also browse Go package reference on [pkg.go.dev][PkgGoDev]. + +[tutorials]: https://gocloud.dev/tutorials/ + +## Project status + +The APIs are still in alpha, but we think they are production-ready and are +actively looking for feedback from early adopters. If you have comments or +questions please open an issue. + +At this time we prefer to focus on maintaining the existing APIs and drivers, +and are unlikely to accept new ones into the `go-cloud` repository. The modular +nature of the Go CDK makes it simple to host new APIs and drivers for existing +APIs externally, in separate repositories. + +If you have a new API or driver that you believe are important and mature enough +to be included, feel free to open an issue to discuss this; our default will +likely be to suggest starting in a separate repository. We'll also be happy +to maintain a list of such external APIs and drivers in this README. + +## Current features + +The Go CDK provides generic APIs for: + +* Unstructured binary (blob) storage +* Publish/Subscribe (pubsub) +* Variables that change at runtime (runtimevar) +* Connecting to MySQL (including MariaDB) and PostgreSQL databases (mysql, postgres) +* Server startup and diagnostics: request logging, tracing, and health + checking (server) + +## Contributing + +Thank you for your interest in contributing to the Go Cloud Development +Kit! :heart: + +Everyone is welcome to contribute, whether it's in the form of code, +documentation, bug reports, feature requests, or anything else. We encourage you +to experiment with the Go CDK and make contributions to help evolve it to meet +your needs! + +The GitHub repository at [google/go-cloud][go-cloud] contains some driver +implementations for each portable API. We intend to include +[Google Cloud Platform][gcp], [Amazon Web Services][aws], and [Azure][azure] +implementations, as well as prominent open source services and at least one +implementation suitable for use in local testing. Unfortunately, we cannot +support every service directly from the project; however, we encourage +contributions in separate repositories. + +If you create a repository that implements the Go CDK interfaces for other +services, let us know! We would be happy to link to it here and give you a +heads-up before making any breaking changes. + +See [the contributing guide](./CONTRIBUTING.md) for more details. + +[go-cloud]: https://github.com/google/go-cloud +[gcp]: http://cloud.google.com +[aws]: http://aws.amazon.com +[azure]: https://azure.microsoft.com/ + +## Community + +This project is covered by the Go [Code of Conduct][]. + +[Code of Conduct]: ./CODE_OF_CONDUCT.md + +## Legal disclaimer + +The Go CDK is open-source and released under an [Apache 2.0 +License](https://github.com/google/go-cloud/blob/master/LICENSE). Copyright © +2018–2019 The Go Cloud Development Kit Authors. + +If you are looking for the website of GoCloud Systems, which is unrelated to the +Go CDK, visit https://gocloud.systems. diff --git a/go-cloud/allmodules b/go-cloud/allmodules new file mode 100644 index 000000000..82157eeb1 --- /dev/null +++ b/go-cloud/allmodules @@ -0,0 +1,22 @@ +# This file lists all the modules in our repository; it's used by scripts that +# have to perform operations for each module. +# +# Any line that doesn't begin with a '#' character and isn't empty is treated +# as a path relative to the top of the repository that has a module in it. +# The 'released' field specifies whether this is a module we release and tag (a +# module importable by users). +# +# Note: another file that lists all the modules in our repo is +# the VSCode workspace gocloud.code-workspace - for now it has to be updated +# manually whenever this file changes. + +# module-directory released +. yes +docstore/mongodocstore yes +internal/website no +pubsub/kafkapubsub yes +pubsub/natspubsub yes +pubsub/rabbitpubsub yes +runtimevar/etcdvar yes +samples no +secrets/hashivault yes diff --git a/go-cloud/aws/aws.go b/go-cloud/aws/aws.go new file mode 100644 index 000000000..6c9d16b4d --- /dev/null +++ b/go-cloud/aws/aws.go @@ -0,0 +1,287 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 aws provides fundamental Wire providers for Amazon Web Services (AWS). +package aws // import "gocloud.dev/aws" + +import ( + "context" + "fmt" + "net/url" + "strconv" + + awsv2 "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/ratelimit" + "github.com/aws/aws-sdk-go-v2/aws/retry" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/endpoints" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/google/wire" +) + +// DefaultSession is a Wire provider set that provides a *session.Session using +// the default options. +var DefaultSession = wire.NewSet( + SessionConfig, + ConfigCredentials, + NewDefaultSession, + wire.Bind(new(client.ConfigProvider), new(*session.Session)), +) + +// NewDefaultSession returns a *session.Session using the default options. +func NewDefaultSession() (*session.Session, error) { + return session.NewSessionWithOptions(session.Options{SharedConfigState: session.SharedConfigEnable}) +} + +// SessionConfig returns sess.Config. +func SessionConfig(sess *session.Session) *aws.Config { + return sess.Config +} + +// ConfigCredentials returns cfg.Credentials. +func ConfigCredentials(cfg *aws.Config) *credentials.Credentials { + return cfg.Credentials +} + +// ConfigOverrider implements client.ConfigProvider by overlaying a list of +// configurations over a base configuration provider. +type ConfigOverrider struct { + Base client.ConfigProvider + Configs []*aws.Config +} + +// ClientConfig calls the base provider's ClientConfig method with co.Configs +// followed by the arguments given to ClientConfig. +func (co ConfigOverrider) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config { + cfgs = append(co.Configs[:len(co.Configs):len(co.Configs)], cfgs...) + return co.Base.ClientConfig(serviceName, cfgs...) +} + +// ConfigFromURLParams returns an aws.Config initialized based on the URL +// parameters in q. It is intended to be used by URLOpeners for AWS services. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// It returns an error if q contains any unknown query parameters; callers +// should remove any query parameters they know about from q before calling +// ConfigFromURLParams. +// +// The following query options are supported: +// - region: The AWS region for requests; sets aws.Config.Region. +// - endpoint: The endpoint URL (hostname only or fully qualified URI); sets aws.Config.Endpoint. +// - disable_ssl (or disableSSL): A value of "true" disables SSL when sending requests; sets aws.Config.DisableSSL. +// - s3_force_path_style (or s3ForcePathStyle): A value of "true" forces the request to use path-style addressing; sets aws.Config.S3ForcePathStyle. +// - dualstack: A value of "true" enables dual stack (IPv4 and IPv6) endpoints +// - fips: A value of "true" enables the use of FIPS endpoints +func ConfigFromURLParams(q url.Values) (*aws.Config, error) { + var cfg aws.Config + for param, values := range q { + value := values[0] + switch param { + case "region": + cfg.Region = aws.String(value) + case "endpoint": + cfg.Endpoint = aws.String(value) + case "disable_ssl", "disableSSL": + b, err := strconv.ParseBool(value) + if err != nil { + return nil, fmt.Errorf("invalid value for query parameter %q: %v", param, err) + } + cfg.DisableSSL = aws.Bool(b) + case "s3_force_path_style", "s3ForcePathStyle": + b, err := strconv.ParseBool(value) + if err != nil { + return nil, fmt.Errorf("invalid value for query parameter %q: %v", param, err) + } + cfg.S3ForcePathStyle = aws.Bool(b) + case "dualstack": + b, err := strconv.ParseBool(value) + if err != nil { + return nil, fmt.Errorf("invalid value for query parameter %q: %v", param, err) + } + cfg.UseDualStack = aws.Bool(b) + case "fips": + b, err := strconv.ParseBool(value) + if err != nil { + return nil, fmt.Errorf("invalid value for query parameter %q: %v", param, err) + } + if b { + cfg.UseFIPSEndpoint = endpoints.FIPSEndpointStateEnabled + } + case "awssdk": + // ignore, should be handled before this + default: + return nil, fmt.Errorf("unknown query parameter %q", param) + } + } + return &cfg, nil +} + +// NewSessionFromURLParams returns an session.Session with session.Options initialized based on the URL +// parameters in q. It is intended to be used by URLOpeners for AWS services. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/session/#Session +// +// It should be used before ConfigFromURLParams as it strips the query +// parameters it knows about +// +// The following query options are supported: +// - profile: The AWS profile to use from the AWS configs (shared config file and +// shared credentials file) +func NewSessionFromURLParams(q url.Values) (*session.Session, url.Values, error) { + // always enable shared config (~/.aws/config by default) + opts := session.Options{SharedConfigState: session.SharedConfigEnable} + rest := url.Values{} + for param, values := range q { + value := values[0] + switch param { + case "profile": + opts.Profile = value + case "awssdk": + // ignore, should be handled before this + default: + rest.Add(param, value) + } + } + sess, err := session.NewSessionWithOptions(opts) + if err != nil { + return nil, nil, fmt.Errorf("couldn't create session %w", err) + } + return sess, rest, nil +} + +// UseV2 returns true iff the URL parameters indicate that the provider +// should use the AWS SDK v2. +// +// "awssdk=v1" will force V1. +// "awssdk=v2" will force V2. +// No "awssdk" parameter (or any other value) will return the default, currently V2. +func UseV2(q url.Values) bool { + if values, ok := q["awssdk"]; ok { + if values[0] == "v1" || values[0] == "V1" { + return false + } + } + return true +} + +// NewDefaultV2Config returns a aws.Config for AWS SDK v2, using the default options. +func NewDefaultV2Config(ctx context.Context) (awsv2.Config, error) { + return config.LoadDefaultConfig(ctx) +} + +// V2ConfigFromURLParams returns an aws.Config for AWS SDK v2 initialized based on the URL +// parameters in q. It is intended to be used by URLOpeners for AWS services if +// UseV2 returns true. +// +// https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Config +// +// It returns an error if q contains any unknown query parameters; callers +// should remove any query parameters they know about from q before calling +// V2ConfigFromURLParams. +// +// The following query options are supported: +// - region: The AWS region for requests; sets WithRegion. +// - anonymous: A value of "true" forces use of anonymous credentials. +// - profile: The shared config profile to use; sets SharedConfigProfile. +// - endpoint: The AWS service endpoint to send HTTP request. +// - hostname_immutable: Make the hostname immutable, only works if endpoint is also set. +// - dualstack: A value of "true" enables dual stack (IPv4 and IPv6) endpoints. +// - fips: A value of "true" enables the use of FIPS endpoints. +// - rate_limiter_capacity: A integer value configures the capacity of a token bucket used +// in client-side rate limits. If no value is set, the client-side rate limiting is disabled. +// See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/retries-timeouts/#client-side-rate-limiting. +func V2ConfigFromURLParams(ctx context.Context, q url.Values) (awsv2.Config, error) { + var endpoint string + var hostnameImmutable bool + var rateLimitCapacity int64 + var opts []func(*config.LoadOptions) error + for param, values := range q { + value := values[0] + switch param { + case "hostname_immutable": + var err error + hostnameImmutable, err = strconv.ParseBool(value) + if err != nil { + return awsv2.Config{}, fmt.Errorf("invalid value for hostname_immutable: %w", err) + } + case "region": + opts = append(opts, config.WithRegion(value)) + case "endpoint": + endpoint = value + case "profile": + opts = append(opts, config.WithSharedConfigProfile(value)) + case "dualstack": + dualStack, err := strconv.ParseBool(value) + if err != nil { + return awsv2.Config{}, fmt.Errorf("invalid value for dualstack: %w", err) + } + if dualStack { + opts = append(opts, config.WithUseDualStackEndpoint(awsv2.DualStackEndpointStateEnabled)) + } + case "fips": + fips, err := strconv.ParseBool(value) + if err != nil { + return awsv2.Config{}, fmt.Errorf("invalid value for fips: %w", err) + } + if fips { + opts = append(opts, config.WithUseFIPSEndpoint(awsv2.FIPSEndpointStateEnabled)) + } + case "rate_limiter_capacity": + var err error + rateLimitCapacity, err = strconv.ParseInt(value, 10, 32) + if err != nil { + return awsv2.Config{}, fmt.Errorf("invalid value for capacity: %w", err) + } + case "anonymous": + anon, err := strconv.ParseBool(value) + if err != nil { + return awsv2.Config{}, fmt.Errorf("invalid value for anonymous: %w", err) + } + if anon { + opts = append(opts, config.WithCredentialsProvider(awsv2.AnonymousCredentials{})) + } + case "awssdk": + // ignore, should be handled before this + default: + return awsv2.Config{}, fmt.Errorf("unknown query parameter %q", param) + } + } + if endpoint != "" { + customResolver := awsv2.EndpointResolverWithOptionsFunc( + func(service, region string, options ...any) (awsv2.Endpoint, error) { + return awsv2.Endpoint{ + PartitionID: "aws", + URL: endpoint, + SigningRegion: region, + HostnameImmutable: hostnameImmutable, + }, nil + }) + opts = append(opts, config.WithEndpointResolverWithOptions(customResolver)) + } + + var rateLimiter retry.RateLimiter + rateLimiter = ratelimit.None + if rateLimitCapacity > 0 { + rateLimiter = ratelimit.NewTokenRateLimit(uint(rateLimitCapacity)) + } + opts = append(opts, config.WithRetryer(func() awsv2.Retryer { + return retry.NewStandard(func(so *retry.StandardOptions) { + so.RateLimiter = rateLimiter + }) + })) + + return config.LoadDefaultConfig(ctx, opts...) +} diff --git a/go-cloud/aws/aws_test.go b/go-cloud/aws/aws_test.go new file mode 100644 index 000000000..43ba10022 --- /dev/null +++ b/go-cloud/aws/aws_test.go @@ -0,0 +1,247 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 aws_test + +import ( + "context" + "net/url" + "reflect" + "testing" + + awsv2 "github.com/aws/aws-sdk-go-v2/aws" + awsv2retry "github.com/aws/aws-sdk-go-v2/aws/retry" + "github.com/aws/aws-sdk-go/aws" + "github.com/google/go-cmp/cmp" + gcaws "github.com/DataDog/iceberg-go/go-cloud/aws" +) + +func TestConfigFromURLParams(t *testing.T) { + tests := []struct { + name string + query url.Values + wantCfg *aws.Config + wantErr bool + }{ + { + name: "No overrides", + query: url.Values{}, + wantCfg: &aws.Config{}, + }, + { + name: "Invalid query parameter", + query: url.Values{"foo": {"bar"}}, + wantErr: true, + }, + { + name: "Region", + query: url.Values{"region": {"my_region"}}, + wantCfg: &aws.Config{Region: aws.String("my_region")}, + }, + { + name: "Endpoint", + query: url.Values{"endpoint": {"foo"}}, + wantCfg: &aws.Config{Endpoint: aws.String("foo")}, + }, + { + name: "disable_ssl true", + query: url.Values{"disable_ssl": {"true"}}, + wantCfg: &aws.Config{DisableSSL: aws.Bool(true)}, + }, + { + name: "DisableSSL true", + query: url.Values{"disableSSL": {"true"}}, + wantCfg: &aws.Config{DisableSSL: aws.Bool(true)}, + }, + { + name: "DisableSSL false", + query: url.Values{"disableSSL": {"false"}}, + wantCfg: &aws.Config{DisableSSL: aws.Bool(false)}, + }, + { + name: "DisableSSL false", + query: url.Values{"disableSSL": {"invalid"}}, + wantErr: true, + }, + { + name: "s3_force_path_style true", + query: url.Values{"s3_force_path_style": {"true"}}, + wantCfg: &aws.Config{S3ForcePathStyle: aws.Bool(true)}, + }, + { + name: "S3ForcePathStyle true", + query: url.Values{"s3ForcePathStyle": {"true"}}, + wantCfg: &aws.Config{S3ForcePathStyle: aws.Bool(true)}, + }, + { + name: "S3ForcePathStyle false", + query: url.Values{"s3ForcePathStyle": {"false"}}, + wantCfg: &aws.Config{S3ForcePathStyle: aws.Bool(false)}, + }, + { + name: "S3ForcePathStyle false", + query: url.Values{"s3ForcePathStyle": {"invalid"}}, + wantErr: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := gcaws.ConfigFromURLParams(test.query) + if (err != nil) != test.wantErr { + t.Errorf("got err %v want error %v", err, test.wantErr) + } + if err != nil { + return + } + if diff := cmp.Diff(got, test.wantCfg); diff != "" { + t.Errorf("opener.forParams(...) diff (-want +got):\n%s", diff) + } + }) + } +} + +func TestUseV2(t *testing.T) { + tests := []struct { + name string + query url.Values + want bool + }{ + { + name: "No overrides", + query: url.Values{}, + want: true, + }, + { + name: "unused param", + query: url.Values{"foo": {"bar"}}, + want: true, + }, + { + name: "force v1", + query: url.Values{"awssdk": {"v1"}}, + want: false, + }, + { + name: "force v1 cap", + query: url.Values{"awssdk": {"V1"}}, + }, + { + name: "force v2", + query: url.Values{"awssdk": {"v2"}}, + want: true, + }, + { + name: "force v2 cap", + query: url.Values{"awssdk": {"V2"}}, + want: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := gcaws.UseV2(test.query) + if test.want != got { + t.Errorf("got %v, want %v", got, test.want) + } + }) + } +} + +func TestV2ConfigFromURLParams(t *testing.T) { + const service = "s3" + const region = "us-east-1" + const partitionID = "aws" + ctx := context.Background() + tests := []struct { + name string + query url.Values + wantRegion string + wantErr bool + wantEndpoint *awsv2.Endpoint + }{ + { + name: "No overrides", + query: url.Values{}, + }, + { + name: "Invalid query parameter", + query: url.Values{"foo": {"bar"}}, + wantErr: true, + }, + { + name: "Region", + query: url.Values{"region": {"my_region"}}, + wantRegion: "my_region", + }, + { + name: "Endpoint and hostname immutable", + query: url.Values{"endpoint": {"foo"}, "hostname_immutable": {"true"}}, + wantEndpoint: &awsv2.Endpoint{ + PartitionID: partitionID, + SigningRegion: region, + URL: "foo", + HostnameImmutable: true, + }, + }, + { + name: "FIPS and dual stack", + query: url.Values{"fips": {"true"}, "dualstack": {"true"}}, + }, + { + name: "anonymous", + query: url.Values{"anonymous": {"true"}}, + }, + { + name: "Rate limit capacity", + query: url.Values{"rate_limiter_capacity": {"500"}}, + }, + // Can't test "profile", since AWS validates that the profile exists. + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := gcaws.V2ConfigFromURLParams(ctx, test.query) + if (err != nil) != test.wantErr { + t.Errorf("got err %v want error %v", err, test.wantErr) + return + } + if err != nil { + return + } + if test.wantRegion != "" && got.Region != test.wantRegion { + t.Errorf("got region %q, want %q", got.Region, test.wantRegion) + } + + if test.wantEndpoint != nil { + if got.EndpointResolverWithOptions == nil { + t.Fatalf("expected an EndpointResolverWithOptions, got nil") + } + gotE, err := got.EndpointResolverWithOptions.ResolveEndpoint(service, region) + if err != nil { + return + } + if !reflect.DeepEqual(gotE, *test.wantEndpoint) { + t.Errorf("got endpoint %+v, want %+v", gotE, *test.wantEndpoint) + } + } + + // Unfortunately, we can't look at the options set for the rate limiter. + r, ok := got.Retryer().(*awsv2retry.Standard) + if !ok { + t.Errorf("expected a standard retryer, got %v, expected awsv2retry.Standard", r) + } + }) + } +} diff --git a/go-cloud/aws/awscloud/awscloud.go b/go-cloud/aws/awscloud/awscloud.go new file mode 100644 index 000000000..c6d924699 --- /dev/null +++ b/go-cloud/aws/awscloud/awscloud.go @@ -0,0 +1,53 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awscloud contains Wire providers for AWS services. +package awscloud // import "gocloud.dev/aws/awscloud" + +import ( + "net/http" + + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/aws" + "github.com/DataDog/iceberg-go/go-cloud/aws/rds" + "github.com/DataDog/iceberg-go/go-cloud/blob/s3blob" + "github.com/DataDog/iceberg-go/go-cloud/docstore/awsdynamodb" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/awssnssqs" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/awsparamstore" + "github.com/DataDog/iceberg-go/go-cloud/secrets/awskms" + "github.com/DataDog/iceberg-go/go-cloud/server/xrayserver" +) + +// AWS is a Wire provider set that includes all Amazon Web Services interface +// implementations in the Go CDK and authenticates using the default session. +var AWS = wire.NewSet( + Services, + aws.DefaultSession, + aws.NewDefaultV2Config, + wire.Value(http.DefaultClient), +) + +// Services is a Wire provider set that includes the default wiring for all +// Amazon Web Services interface implementations in the Go CDK but unlike the +// AWS set, does not include credentials. Individual services may require +// additional configuration. +var Services = wire.NewSet( + s3blob.Set, + awssnssqs.Set, + awsparamstore.Set, + awskms.Set, + rds.CertFetcherSet, + awsdynamodb.Set, + xrayserver.Set, +) diff --git a/go-cloud/aws/awscloud/example_test.go b/go-cloud/aws/awscloud/example_test.go new file mode 100644 index 000000000..d1c8e1d89 --- /dev/null +++ b/go-cloud/aws/awscloud/example_test.go @@ -0,0 +1,76 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awscloud_test + +import ( + "context" + "fmt" + "log" + "net/http" + + "github.com/google/wire" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "github.com/DataDog/iceberg-go/go-cloud/aws/awscloud" + "github.com/DataDog/iceberg-go/go-cloud/server" + "github.com/DataDog/iceberg-go/go-cloud/server/health" +) + +// This is an example of how to bootstrap an HTTP server running on +// Amazon Web Services (AWS). The code in this function would be +// placed in main(). +func Example() { + // Connect and authenticate to AWS. + srv, cleanup, err := setup(context.Background()) + if err != nil { + log.Fatal(err) + } + defer cleanup() + + // Set up the HTTP routes. + http.HandleFunc("/", greet) + + // Run the server. This behaves much like http.ListenAndServe, + // including that passing a nil handler will use http.DefaultServeMux. + log.Fatal(srv.ListenAndServe(":8080")) +} + +// setup is a Wire injector function that creates an HTTP server +// configured to send diagnostics to AWS X-Ray. The second return +// value is a clean-up function that can be called to shut down any +// resources created by setup. +// +// The body of this function will be filled in by running Wire. While +// the name of the function does not matter, the signature signals to +// Wire what provider functions to call. See +// https://github.com/google/wire/blob/master/docs/guide.md#injectors +// for more details. +func setup(ctx context.Context) (*server.Server, func(), error) { + wire.Build( + // The AWS set includes all the default wiring for AWS, including + // for *server.Server. + awscloud.AWS, + // Providing nil instructs the server to use the default sampling policy. + wire.Value(sdktrace.Sampler(nil)), + // Health checks can be added to delay your server reporting healthy + // to the load balancer before critical dependencies are available. + wire.Value([]health.Checker(nil)), + ) + return nil, nil, nil +} + +// greet is an ordinary http.HandleFunc. +func greet(w http.ResponseWriter, req *http.Request) { + fmt.Fprintln(w, "Hello, World!") +} diff --git a/go-cloud/aws/rds/rds.go b/go-cloud/aws/rds/rds.go new file mode 100644 index 000000000..8a25def69 --- /dev/null +++ b/go-cloud/aws/rds/rds.go @@ -0,0 +1,102 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 rds contains Wire providers that are common across RDS. +package rds // import "gocloud.dev/aws/rds" + +import ( + "context" + "crypto/x509" + "encoding/pem" + "fmt" + "io" + "net/http" + + "github.com/google/wire" + "golang.org/x/net/context/ctxhttp" +) + +// CertFetcherSet is a Wire provider set that provides the RDS certificate pool +// by pulling from Amazon's servers. +var CertFetcherSet = wire.NewSet( + wire.Struct(new(CertFetcher), "Client"), + wire.Bind(new(CertPoolProvider), new(*CertFetcher)), +) + +// A CertPoolProvider obtains a certificate pool that contains the RDS CA certificate. +type CertPoolProvider interface { + RDSCertPool(context.Context) (*x509.CertPool, error) +} + +// caBundleURL is the URL to the public RDS Certificate Authority keys. +const caBundleURL = "https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem" + +// CertFetcher pulls the RDS CA certificates from Amazon's servers. The zero +// value will fetch certificates using the default HTTP client. +type CertFetcher struct { + // Client is the HTTP client used to make requests. If nil, then + // http.DefaultClient is used. + Client *http.Client +} + +// RDSCertPool fetches the RDS CA certificates and places them into a pool. +// It is safe to call from multiple goroutines. +func (cf *CertFetcher) RDSCertPool(ctx context.Context) (*x509.CertPool, error) { + certs, err := cf.Fetch(ctx) + if err != nil { + return nil, err + } + certPool := x509.NewCertPool() + for _, c := range certs { + certPool.AddCert(c) + } + return certPool, nil +} + +// Fetch fetches the RDS CA certificates. It is safe to call from multiple goroutines. +func (cf *CertFetcher) Fetch(ctx context.Context) ([]*x509.Certificate, error) { + client := cf.Client + if client == nil { + client = http.DefaultClient + } + resp, err := ctxhttp.Get(ctx, client, caBundleURL) + if err != nil { + return nil, fmt.Errorf("fetch RDS certificates: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("fetch RDS certificates: HTTP %s", resp.Status) + } + pemData, err := io.ReadAll(&io.LimitedReader{R: resp.Body, N: 1 << 20}) // limit to 1MiB + if err != nil { + return nil, fmt.Errorf("fetch RDS certificates: %v", err) + } + var certs []*x509.Certificate + for len(pemData) > 0 { + var block *pem.Block + block, pemData = pem.Decode(pemData) + if block == nil { + break + } + if block.Type != "CERTIFICATE" || len(block.Headers) != 0 { + continue + } + c, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, fmt.Errorf("fetch RDS certificates: %v", err) + } + certs = append(certs, c) + } + return certs, nil +} diff --git a/go-cloud/azure/azurecloud/azurecloud.go b/go-cloud/azure/azurecloud/azurecloud.go new file mode 100644 index 000000000..1b853989c --- /dev/null +++ b/go-cloud/azure/azurecloud/azurecloud.go @@ -0,0 +1,30 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 azurecloud contains Wire providers for Azure services. +package azurecloud // import "gocloud.dev/azure/azurecloud" + +import ( + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/blob/azureblob" + "github.com/DataDog/iceberg-go/go-cloud/secrets/azurekeyvault" +) + +// Azure is a Wire provider set that includes the default wiring for all +// Microsoft Azure services in this repository, but does not include +// credentials. Individual services may require additional configuration. +var Azure = wire.NewSet( + azurekeyvault.Set, + azureblob.Set, +) diff --git a/go-cloud/azure/azuredb/azuredb.go b/go-cloud/azure/azuredb/azuredb.go new file mode 100644 index 000000000..610039717 --- /dev/null +++ b/go-cloud/azure/azuredb/azuredb.go @@ -0,0 +1,93 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 azuredb contains Wire providers that are common across Azure Database. +package azuredb + +import ( + "context" + "crypto/x509" + "encoding/pem" + "fmt" + "io" + "net/http" + + "golang.org/x/net/context/ctxhttp" +) + +const caBundleURL = "https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot.crt.pem" + +// A CertPoolProvider returns a certificate pool that contains the Azure CA certificate. +type CertPoolProvider interface { + AzureCertPool(context.Context) (*x509.CertPool, error) +} + +// CertFetcher pulls the Azure CA certificates from Digicert's servers. The zero +// value will fetch certificates using the default HTTP client. +type CertFetcher struct { + // Client is the HTTP client used to make requests. If nil, then + // http.DefaultClient is used. + Client *http.Client +} + +// AzureCertPool fetches the Azure CA certificates and places them into a pool. +// It is safe to call from multiple goroutines. +func (cf *CertFetcher) AzureCertPool(ctx context.Context) (*x509.CertPool, error) { + certs, err := cf.Fetch(ctx) + if err != nil { + return nil, err + } + certPool := x509.NewCertPool() + for _, c := range certs { + certPool.AddCert(c) + } + return certPool, nil +} + +// Fetch fetches the Azure CA certificates. It is safe to call from multiple goroutines. +func (cf *CertFetcher) Fetch(ctx context.Context) ([]*x509.Certificate, error) { + client := cf.Client + if client == nil { + client = http.DefaultClient + } + resp, err := ctxhttp.Get(ctx, client, caBundleURL) + if err != nil { + return nil, fmt.Errorf("fetch Azure certificates: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("fetch Azure certificates: HTTP %s", resp.Status) + } + pemData, err := io.ReadAll(&io.LimitedReader{R: resp.Body, N: 1 << 20}) // limit to 1MiB + if err != nil { + return nil, fmt.Errorf("fetch Azure certificates: %v", err) + } + var certs []*x509.Certificate + for len(pemData) > 0 { + var block *pem.Block + block, pemData = pem.Decode(pemData) + if block == nil { + break + } + if block.Type != "CERTIFICATE" || len(block.Headers) != 0 { + continue + } + c, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, fmt.Errorf("fetch Azure certificates: %v", err) + } + certs = append(certs, c) + } + return certs, nil +} diff --git a/go-cloud/blob/azureblob/azureblob.go b/go-cloud/blob/azureblob/azureblob.go new file mode 100644 index 000000000..bf6c37e3c --- /dev/null +++ b/go-cloud/blob/azureblob/azureblob.go @@ -0,0 +1,1026 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 azureblob provides a blob implementation that uses Azure Storage’s +// BlockBlob. Use OpenBucket to construct a *blob.Bucket. +// +// NOTE: SignedURLs for PUT created with this package are not fully portable; +// they will not work unless the PUT request includes a "x-ms-blob-type" header +// set to "BlockBlob". +// See https://stackoverflow.com/questions/37824136/put-on-sas-blob-url-without-specifying-x-ms-blob-type-header. +// +// # URLs +// +// For blob.OpenBucket, azureblob registers for the scheme "azblob". +// +// The default URL opener will use environment variables to generate +// credentials and a service URL; see +// https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/storage/azblob +// for a more complete descriptions of each approach. +// - AZURE_STORAGE_ACCOUNT: The service account name. Required if used along with AZURE_STORAGE KEY, because it defines +// authentication mechanism to be azblob.NewSharedKeyCredential, which creates immutable shared key credentials. +// Otherwise, "storage_account" in the URL query string parameter can be used. +// - AZURE_STORAGE_KEY: To use a shared key credential. The service account +// name and key are passed to NewSharedKeyCredential and then the +// resulting credential is passed to NewClientWithSharedKeyCredential. +// - AZURE_STORAGE_CONNECTION_STRING or AZURE_STORAGEBLOB_CONNECTIONSTRING: To use a connection string, passed to +// NewClientFromConnectionString. +// - AZURE_STORAGE_SAS_TOKEN: To use a SAS token. The SAS token is added +// as a URL parameter to the service URL, and passed to +// NewClientWithNoCredential. +// - If none of the above are provided, azureblob defaults to +// azidentity.NewDefaultAzureCredential: +// https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#NewDefaultAzureCredential. +// See the documentation there for the credential types it supports, including +// CLI creds, environment variables like AZURE_CLIENT_ID, AZURE_TENANT_ID, etc. +// +// In addition, the environment variables AZURE_STORAGE_ACCOUNT, AZURE_STORAGE_DOMAIN, +// AZURE_STORAGE_PROTOCOL, AZURE_STORAGE_IS_CDN, and AZURE_STORAGE_IS_LOCAL_EMULATOR +// can be used to configure how the default URLOpener generates the Azure +// Service URL via ServiceURLOptions. These can all be configured via URL +// parameters as well. See ServiceURLOptions and NewDefaultServiceURL +// for more details. +// +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # Escaping +// +// Go CDK supports all UTF-8 strings; to make this work with services lacking +// full UTF-8 support, strings must be escaped (during writes) and unescaped +// (during reads). The following escapes are performed for azureblob: +// - Blob keys: ASCII characters 0-31, 34 ("\""), 35 ("#"), 37 ("%"), 63 ("?"), +// 92 ("\"), and 127 are escaped to "__0x__". +// Additionally, the "/" in "../" and a trailing "/" in a key (e.g., "foo/") are escaped in the same way. +// - Metadata keys: Per https://docs.microsoft.com/en-us/azure/storage/blobs/storage-properties-metadata, +// Azure only allows C# identifiers as metadata keys. Therefore, characters +// other than "[a-z][A-z][0-9]_" are escaped using "__0x__". In addition, +// characters "[0-9]" are escaped when they start the string. +// URL encoding would not work since "%" is not valid. +// - Metadata values: Escaped using URL encoding. +// +// # As +// +// azureblob exposes the following types for As: +// - Bucket: *container.Client +// - Error: *azcore.ResponseError. You can use bloberror.HasCode directly though. +// - ListObject: container.BlobItem for objects, container.BlobPrefix for "directories" +// - ListOptions.BeforeList: *container.ListBlobsHierarchyOptions +// - Reader: azblobblob.DownloadStreamResponse +// - Reader.BeforeRead: *azblob.DownloadStreamOptions +// - Attributes: azblobblob.GetPropertiesResponse +// - CopyOptions.BeforeCopy: *azblobblob.StartCopyFromURLOptions +// - WriterOptions.BeforeWrite: *azblob.UploadStreamOptions +// - SignedURLOptions.BeforeSign: *sas.BlobPermissions +package azureblob + +import ( + "context" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + "sort" + "strconv" + "strings" + "sync" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" + azblobblob "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blockblob" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/sas" + "github.com/Azure/go-autorest/autorest/to" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + + "github.com/DataDog/iceberg-go/go-cloud/internal/escape" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/useragent" +) + +const ( + defaultPageSize = 1000 // default page size for ListPaged (Azure default is 5000) + defaultUploadBuffers = 5 // configure the number of rotating buffers that are used when uploading (for degree of parallelism) + defaultUploadBlockSize = 8 * 1024 * 1024 // configure the upload buffer size +) + +func init() { + blob.DefaultURLMux().RegisterBucket(Scheme, new(lazyOpener)) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + NewDefaultServiceURLOptions, + NewServiceURL, + NewDefaultClient, +) + +// Options sets options for constructing a *blob.Bucket backed by Azure Blob. +type Options struct{} + +// ServiceURL represents an Azure service URL. +type ServiceURL string + +// ContainerName represents an Azure blob container name. +type ContainerName string + +// ServiceURLOptions sets options for constructing a service URL for Azure Blob. +type ServiceURLOptions struct { + // AccountName is the account name the credentials are for. + AccountName string + + // SASToken will be appended to the service URL. + // See https://docs.microsoft.com/en-us/azure/storage/common/storage-dotnet-shared-access-signature-part-1#shared-access-signature-parameters. + SASToken string + + // StorageDomain can be provided to specify an Azure Cloud Environment + // domain to target for the blob storage account (i.e. public, government, china). + // Defaults to "blob.core.windows.net". Possible values will look similar + // to this but are different for each cloud (i.e. "blob.core.govcloudapi.net" for USGovernment). + // Check the Azure developer guide for the cloud environment where your bucket resides. + // See the docstring for NewServiceURL to see examples of how this is used + // along with the other Options fields. + StorageDomain string + + // Protocol can be provided to specify protocol to access Azure Blob Storage. + // Protocols that can be specified are "http" for local emulator and "https" for general. + // Defaults to "https". + // See the docstring for NewServiceURL to see examples of how this is used + // along with the other Options fields. + Protocol string + + // IsCDN can be set to true when using a CDN URL pointing to a blob storage account: + // https://docs.microsoft.com/en-us/azure/cdn/cdn-create-a-storage-account-with-cdn + // See the docstring for NewServiceURL to see examples of how this is used + // along with the other Options fields. + IsCDN bool + + // IsLocalEmulator should be set to true when targeting Local Storage Emulator (Azurite). + // See the docstring for NewServiceURL to see examples of how this is used + // along with the other Options fields. + IsLocalEmulator bool +} + +// NewDefaultServiceURLOptions generates a ServiceURLOptions based on environment variables. +func NewDefaultServiceURLOptions() *ServiceURLOptions { + isCDN, _ := strconv.ParseBool(os.Getenv("AZURE_STORAGE_IS_CDN")) + isLocalEmulator, _ := strconv.ParseBool(os.Getenv("AZURE_STORAGE_IS_LOCAL_EMULATOR")) + accountName := os.Getenv("AZURE_STORAGE_ACCOUNT") + protocol := os.Getenv("AZURE_STORAGE_PROTOCOL") + connectionString := os.Getenv("AZURE_STORAGE_CONNECTION_STRING") + if connectionString == "" { + connectionString = os.Getenv("AZURE_STORAGEBLOB_CONNECTIONSTRING") + } + if connectionString != "" { + // Parse the connection string to get a default account name and protocol. + // Format: DefaultEndpointsProtocol=https;AccountName=some-account;AccountKey=very-secure;EndpointSuffix=core.windows.net + for _, part := range strings.Split(connectionString, ";") { + keyval := strings.Split(part, "=") + if len(keyval) == 2 { + if accountName == "" && keyval[0] == "AccountName" { + accountName = keyval[1] + } else if protocol == "" && keyval[0] == "DefaultEndpointsProtocol" { + protocol = keyval[1] + } + } + } + } + return &ServiceURLOptions{ + AccountName: accountName, + SASToken: os.Getenv("AZURE_STORAGE_SAS_TOKEN"), + StorageDomain: os.Getenv("AZURE_STORAGE_DOMAIN"), + Protocol: protocol, + IsCDN: isCDN, + IsLocalEmulator: isLocalEmulator, + } +} + +// withOverrides returns o with overrides from urlValues. +// See URLOpener for supported overrides. +func (o *ServiceURLOptions) withOverrides(urlValues url.Values) (*ServiceURLOptions, error) { + retval := *o + for param, values := range urlValues { + if len(values) > 1 { + return nil, fmt.Errorf("multiple values of %v not allowed", param) + } + value := values[0] + switch param { + case "domain": + retval.StorageDomain = value + case "protocol": + retval.Protocol = value + case "cdn": + isCDN, err := strconv.ParseBool(value) + if err != nil { + return nil, err + } + retval.IsCDN = isCDN + case "localemu": + isLocalEmulator, err := strconv.ParseBool(value) + if err != nil { + return nil, err + } + retval.IsLocalEmulator = isLocalEmulator + case "storage_account": + retval.AccountName = value + default: + return nil, fmt.Errorf("unknown query parameter %q", param) + } + } + return &retval, nil +} + +// NewServiceURL generates a URL for addressing an Azure Blob service +// account. It uses several parameters, each of which can be specified +// via ServiceURLOptions. +// +// The generated URL is "://." +// with the following caveats: +// - If opts.SASToken is provided, it is appended to the URL as a query +// parameter. +// - If opts.IsCDN is true, the part is dropped. +// - If opts.IsLocalEmulator is true, or the domain starts with "localhost" +// or "127.0.0.1", the account name and domain are flipped, e.g.: +// http://127.0.0.1:10000/myaccount +func NewServiceURL(opts *ServiceURLOptions) (ServiceURL, error) { + if opts == nil { + opts = &ServiceURLOptions{} + } + accountName := opts.AccountName + if accountName == "" { + return "", errors.New("azureblob: Options.AccountName is required") + } + domain := opts.StorageDomain + if domain == "" { + domain = "blob.core.windows.net" + } + protocol := opts.Protocol + if protocol == "" { + protocol = "https" + } else if protocol != "http" && protocol != "https" { + return "", fmt.Errorf("invalid protocol %q", protocol) + } + var svcURL string + if strings.HasPrefix(domain, "127.0.0.1") || strings.HasPrefix(domain, "localhost") || opts.IsLocalEmulator { + svcURL = fmt.Sprintf("%s://%s/%s", protocol, domain, accountName) + } else if opts.IsCDN { + svcURL = fmt.Sprintf("%s://%s", protocol, domain) + } else { + svcURL = fmt.Sprintf("%s://%s.%s", protocol, accountName, domain) + } + if opts.SASToken != "" { + svcURL += "?" + opts.SASToken + } + return ServiceURL(svcURL), nil +} + +// lazyOpener obtains credentials and creates a client on the first call to OpenBucketURL. +type lazyOpener struct { + init sync.Once + opener *URLOpener +} + +func (o *lazyOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) { + o.init.Do(func() { + credInfo := newCredInfoFromEnv() + opts := NewDefaultServiceURLOptions() + o.opener = &URLOpener{ + MakeClient: credInfo.NewClient, + ServiceURLOptions: *opts, + } + }) + return o.opener.OpenBucketURL(ctx, u) +} + +type credTypeEnumT int + +const ( + credTypeDefault credTypeEnumT = iota + credTypeSharedKey + credTypeSASViaNone + credTypeConnectionString +) + +type credInfoT struct { + CredType credTypeEnumT + + // For credTypeSharedKey. + AccountName string + AccountKey string + + // For credTypeConnectionString + ConnectionString string +} + +func newCredInfoFromEnv() *credInfoT { + accountName := os.Getenv("AZURE_STORAGE_ACCOUNT") + accountKey := os.Getenv("AZURE_STORAGE_KEY") + sasToken := os.Getenv("AZURE_STORAGE_SAS_TOKEN") + connectionString := os.Getenv("AZURE_STORAGE_CONNECTION_STRING") + if connectionString == "" { + connectionString = os.Getenv("AZURE_STORAGEBLOB_CONNECTIONSTRING") + } + credInfo := &credInfoT{ + AccountName: accountName, + } + if accountName != "" && accountKey != "" { + credInfo.CredType = credTypeSharedKey + credInfo.AccountKey = accountKey + } else if sasToken != "" { + credInfo.CredType = credTypeSASViaNone + } else if connectionString != "" { + credInfo.CredType = credTypeConnectionString + credInfo.ConnectionString = connectionString + } else { + credInfo.CredType = credTypeDefault + } + return credInfo +} + +func (i *credInfoT) NewClient(svcURL ServiceURL, containerName ContainerName) (*container.Client, error) { + // Set the ApplicationID. + azClientOpts := &container.ClientOptions{} + azClientOpts.Telemetry = policy.TelemetryOptions{ + ApplicationID: useragent.AzureUserAgentPrefix("blob"), + } + + containerURL, err := url.JoinPath(string(svcURL), string(containerName)) + if err != nil { + return nil, err + } + switch i.CredType { + case credTypeDefault: + cred, err := azidentity.NewDefaultAzureCredential(nil) + if err != nil { + return nil, fmt.Errorf("failed azidentity.NewDefaultAzureCredential: %v", err) + } + return container.NewClient(containerURL, cred, azClientOpts) + case credTypeSharedKey: + sharedKeyCred, err := azblob.NewSharedKeyCredential(i.AccountName, i.AccountKey) + if err != nil { + return nil, fmt.Errorf("failed azblob.NewSharedKeyCredential: %v", err) + } + return container.NewClientWithSharedKeyCredential(containerURL, sharedKeyCred, azClientOpts) + case credTypeSASViaNone: + return container.NewClientWithNoCredential(containerURL, azClientOpts) + case credTypeConnectionString: + return container.NewClientFromConnectionString(i.ConnectionString, string(containerName), azClientOpts) + default: + return nil, errors.New("internal error, unknown cred type") + } +} + +// Scheme is the URL scheme gcsblob registers its URLOpener under on +// blob.DefaultMux. +const Scheme = "azblob" + +// URLOpener opens Azure URLs like "azblob://mybucket". +// +// The URL host is used as the bucket name. +// +// The following query options are supported: +// - domain: Overrides Options.StorageDomain. +// - protocol: Overrides Options.Protocol. +// - cdn: Overrides Options.IsCDN. +// - localemu: Overrides Options.IsLocalEmulator. +type URLOpener struct { + // MakeClient must be set to a non-nil value. + MakeClient func(svcURL ServiceURL, containerName ContainerName) (*container.Client, error) + + // ServiceURLOptions specifies default options for generating the service URL. + // Some options can be overridden in the URL as described above. + ServiceURLOptions ServiceURLOptions + + // Options specifies the options to pass to OpenBucket. + Options Options +} + +// OpenBucketURL opens a blob.Bucket based on u. +func (o *URLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) { + opts, err := o.ServiceURLOptions.withOverrides(u.Query()) + if err != nil { + return nil, err + } + svcURL, err := NewServiceURL(opts) + if err != nil { + return nil, err + } + client, err := o.MakeClient(svcURL, ContainerName(u.Host)) + if err != nil { + return nil, err + } + return OpenBucket(ctx, client, &o.Options) +} + +// bucket represents a Azure Storage Account Container, which handles read, +// write and delete operations on objects within it. +// See https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction. +type bucket struct { + client *container.Client + opts *Options +} + +// NewDefaultClient returns an Azure Blob container client +// with credentials from the environment as described in the package +// docstring. +func NewDefaultClient(svcURL ServiceURL, containerName ContainerName) (*container.Client, error) { + return newCredInfoFromEnv().NewClient(svcURL, containerName) +} + +// OpenBucket returns a *blob.Bucket backed by Azure Storage Account. See the package +// documentation for an example and +// https://godoc.org/github.com/Azure/azure-storage-blob-go/azblob +// for more details. +func OpenBucket(ctx context.Context, client *container.Client, opts *Options) (*blob.Bucket, error) { + b, err := openBucket(ctx, client, opts) + if err != nil { + return nil, err + } + return blob.NewBucket(b), nil +} + +func openBucket(ctx context.Context, client *container.Client, opts *Options) (*bucket, error) { + if client == nil { + return nil, errors.New("azureblob.OpenBucket: client is required") + } + if opts == nil { + opts = &Options{} + } + return &bucket{ + client: client, + opts: opts, + }, nil +} + +// Close implements driver.Close. +func (b *bucket) Close() error { + return nil +} + +// Copy implements driver.Copy. +func (b *bucket) Copy(ctx context.Context, dstKey, srcKey string, opts *driver.CopyOptions) error { + dstKey = escapeKey(dstKey, false) + dstBlobClient := b.client.NewBlobClient(dstKey) + srcKey = escapeKey(srcKey, false) + srcBlobClient := b.client.NewBlobClient(srcKey) + copyOptions := &azblobblob.StartCopyFromURLOptions{} + if opts.BeforeCopy != nil { + asFunc := func(i any) bool { + switch v := i.(type) { + case **azblobblob.StartCopyFromURLOptions: + *v = copyOptions + return true + } + return false + } + if err := opts.BeforeCopy(asFunc); err != nil { + return err + } + } + resp, err := dstBlobClient.StartCopyFromURL(ctx, srcBlobClient.URL(), copyOptions) + if err != nil { + return err + } + nErrors := 0 + copyStatus := *resp.CopyStatus + for copyStatus == azblobblob.CopyStatusTypePending { + // Poll until the copy is complete. + time.Sleep(500 * time.Millisecond) + propertiesResp, err := dstBlobClient.GetProperties(ctx, nil) + if err != nil { + // A GetProperties failure may be transient, so allow a couple + // of them before giving up. + nErrors++ + if ctx.Err() != nil || nErrors == 3 { + return err + } + } + copyStatus = *propertiesResp.CopyStatus + } + if copyStatus != azblobblob.CopyStatusTypeSuccess { + return fmt.Errorf("Copy failed with status: %s", copyStatus) + } + return nil +} + +// Delete implements driver.Delete. +func (b *bucket) Delete(ctx context.Context, key string) error { + key = escapeKey(key, false) + blobClient := b.client.NewBlobClient(key) + _, err := blobClient.Delete(ctx, nil) + return err +} + +// reader reads an azblob. It implements io.ReadCloser. +type reader struct { + body io.ReadCloser + attrs driver.ReaderAttributes + raw *azblobblob.DownloadStreamResponse +} + +func (r *reader) Read(p []byte) (int, error) { + return r.body.Read(p) +} + +func (r *reader) Close() error { + return r.body.Close() +} + +func (r *reader) Attributes() *driver.ReaderAttributes { + return &r.attrs +} + +func (r *reader) As(i any) bool { + p, ok := i.(*azblobblob.DownloadStreamResponse) + if !ok { + return false + } + *p = *r.raw + return true +} + +// NewRangeReader implements driver.NewRangeReader. +func (b *bucket) NewRangeReader(ctx context.Context, key string, offset, length int64, opts *driver.ReaderOptions) (driver.Reader, error) { + key = escapeKey(key, false) + blobClient := b.client.NewBlobClient(key) + downloadOpts := azblob.DownloadStreamOptions{} + if offset != 0 { + downloadOpts.Range.Offset = offset + } + if length >= 0 { + downloadOpts.Range.Count = length + } + if opts.BeforeRead != nil { + asFunc := func(i any) bool { + if p, ok := i.(**azblobblob.DownloadStreamOptions); ok { + *p = &downloadOpts + return true + } + return false + } + if err := opts.BeforeRead(asFunc); err != nil { + return nil, err + } + } + blobDownloadResponse, err := blobClient.DownloadStream(ctx, &downloadOpts) + if err != nil { + return nil, err + } + attrs := driver.ReaderAttributes{ + ContentType: to.String(blobDownloadResponse.ContentType), + Size: getSize(blobDownloadResponse.ContentLength, to.String(blobDownloadResponse.ContentRange)), + ModTime: *blobDownloadResponse.LastModified, + } + var body io.ReadCloser + if length == 0 { + body = http.NoBody + } else { + body = blobDownloadResponse.Body + } + return &reader{ + body: body, + attrs: attrs, + raw: &blobDownloadResponse, + }, nil +} + +func getSize(contentLength *int64, contentRange string) int64 { + var size int64 + // Default size to ContentLength, but that's incorrect for partial-length reads, + // where ContentLength refers to the size of the returned Body, not the entire + // size of the blob. ContentRange has the full size. + if contentLength != nil { + size = *contentLength + } + if contentRange != "" { + // Sample: bytes 10-14/27 (where 27 is the full size). + parts := strings.Split(contentRange, "/") + if len(parts) == 2 { + if i, err := strconv.ParseInt(parts[1], 10, 64); err == nil { + size = i + } + } + } + return size +} + +// As implements driver.As. +func (b *bucket) As(i any) bool { + p, ok := i.(**container.Client) + if !ok { + return false + } + *p = b.client + return true +} + +// As implements driver.ErrorAs. +func (b *bucket) ErrorAs(err error, i any) bool { + switch v := err.(type) { + case *azcore.ResponseError: + if p, ok := i.(**azcore.ResponseError); ok { + *p = v + return true + } + } + return false +} + +func (b *bucket) ErrorCode(err error) gcerrors.ErrorCode { + if bloberror.HasCode(err, bloberror.BlobNotFound) { + return gcerrors.NotFound + } + if bloberror.HasCode(err, bloberror.AuthenticationFailed) { + return gcerrors.PermissionDenied + } + var rErr *azcore.ResponseError + if errors.As(err, &rErr) { + code := bloberror.Code(rErr.ErrorCode) + if code == bloberror.BlobNotFound || rErr.StatusCode == 404 { + return gcerrors.NotFound + } + if code == bloberror.AuthenticationFailed { + return gcerrors.PermissionDenied + } + } + if strings.Contains(err.Error(), "no such host") { + // This happens with an invalid storage account name; the host + // is something like invalidstorageaccount.blob.core.windows.net. + return gcerrors.NotFound + } + return gcerrors.Unknown +} + +// Attributes implements driver.Attributes. +func (b *bucket) Attributes(ctx context.Context, key string) (*driver.Attributes, error) { + key = escapeKey(key, false) + blobClient := b.client.NewBlobClient(key) + blobPropertiesResponse, err := blobClient.GetProperties(ctx, nil) + if err != nil { + return nil, err + } + + md := make(map[string]string, len(blobPropertiesResponse.Metadata)) + for k, v := range blobPropertiesResponse.Metadata { + // See the package comments for more details on escaping of metadata + // keys & values. + if v != nil { + md[escape.HexUnescape(k)] = escape.URLUnescape(*v) + } + } + var eTag string + if blobPropertiesResponse.ETag != nil { + eTag = string(*blobPropertiesResponse.ETag) + } + return &driver.Attributes{ + CacheControl: to.String(blobPropertiesResponse.CacheControl), + ContentDisposition: to.String(blobPropertiesResponse.ContentDisposition), + ContentEncoding: to.String(blobPropertiesResponse.ContentEncoding), + ContentLanguage: to.String(blobPropertiesResponse.ContentLanguage), + ContentType: to.String(blobPropertiesResponse.ContentType), + Size: to.Int64(blobPropertiesResponse.ContentLength), + CreateTime: *blobPropertiesResponse.CreationTime, + ModTime: *blobPropertiesResponse.LastModified, + MD5: blobPropertiesResponse.ContentMD5, + ETag: eTag, + Metadata: md, + AsFunc: func(i any) bool { + p, ok := i.(*azblobblob.GetPropertiesResponse) + if !ok { + return false + } + *p = blobPropertiesResponse + return true + }, + }, nil +} + +// ListPaged implements driver.ListPaged. +func (b *bucket) ListPaged(ctx context.Context, opts *driver.ListOptions) (*driver.ListPage, error) { + pageSize := opts.PageSize + if pageSize == 0 { + pageSize = defaultPageSize + } + + var marker *string + if len(opts.PageToken) > 0 { + pt := string(opts.PageToken) + marker = &pt + } + + pageSize32 := int32(pageSize) + prefix := escapeKey(opts.Prefix, true) + azOpts := container.ListBlobsHierarchyOptions{ + MaxResults: &pageSize32, + Prefix: &prefix, + Marker: marker, + } + if opts.BeforeList != nil { + asFunc := func(i any) bool { + p, ok := i.(**container.ListBlobsHierarchyOptions) + if !ok { + return false + } + *p = &azOpts + return true + } + if err := opts.BeforeList(asFunc); err != nil { + return nil, err + } + } + azPager := b.client.NewListBlobsHierarchyPager(escapeKey(opts.Delimiter, true), &azOpts) + resp, err := azPager.NextPage(ctx) + if err != nil { + return nil, err + } + page := &driver.ListPage{} + page.Objects = []*driver.ListObject{} + segment := resp.ListBlobsHierarchySegmentResponse.Segment + for _, blobPrefix := range segment.BlobPrefixes { + blobPrefix := blobPrefix // capture loop variable for use in AsFunc + page.Objects = append(page.Objects, &driver.ListObject{ + Key: unescapeKey(to.String(blobPrefix.Name)), + Size: 0, + IsDir: true, + AsFunc: func(i any) bool { + v, ok := i.(*container.BlobPrefix) + if ok { + *v = *blobPrefix + } + return ok + }, + }) + } + for _, blobInfo := range segment.BlobItems { + blobInfo := blobInfo // capture loop variable for use in AsFunc + page.Objects = append(page.Objects, &driver.ListObject{ + Key: unescapeKey(to.String(blobInfo.Name)), + ModTime: *blobInfo.Properties.LastModified, + Size: *blobInfo.Properties.ContentLength, + MD5: blobInfo.Properties.ContentMD5, + IsDir: false, + AsFunc: func(i any) bool { + v, ok := i.(*container.BlobItem) + if ok { + *v = *blobInfo + } + return ok + }, + }) + } + if resp.NextMarker != nil { + page.NextPageToken = []byte(*resp.NextMarker) + } + if len(segment.BlobPrefixes) > 0 && len(segment.BlobItems) > 0 { + sort.Slice(page.Objects, func(i, j int) bool { + return page.Objects[i].Key < page.Objects[j].Key + }) + } + return page, nil +} + +// SignedURL implements driver.SignedURL. +func (b *bucket) SignedURL(ctx context.Context, key string, opts *driver.SignedURLOptions) (string, error) { + if opts.ContentType != "" || opts.EnforceAbsentContentType { + return "", gcerr.New(gcerr.Unimplemented, nil, 1, "azureblob: does not enforce Content-Type on PUT") + } + + key = escapeKey(key, false) + blobClient := b.client.NewBlobClient(key) + perms := sas.BlobPermissions{} + switch opts.Method { + case http.MethodGet: + perms.Read = true + case http.MethodPut: + perms.Create = true + perms.Write = true + case http.MethodDelete: + perms.Delete = true + default: + return "", fmt.Errorf("unsupported Method %s", opts.Method) + } + + if opts.BeforeSign != nil { + asFunc := func(i any) bool { + v, ok := i.(**sas.BlobPermissions) + if ok { + *v = &perms + } + return ok + } + if err := opts.BeforeSign(asFunc); err != nil { + return "", err + } + } + start := time.Now().UTC() + expiry := start.Add(opts.Expiry) + return blobClient.GetSASURL(perms, expiry, &azblobblob.GetSASURLOptions{StartTime: &start}) +} + +type writer struct { + ctx context.Context + client *blockblob.Client + uploadOpts *azblob.UploadStreamOptions + + // Ends of an io.Pipe, created when the first byte is written. + pw *io.PipeWriter + pr *io.PipeReader + + // Alternatively, upload is set to true when Upload was + // used to upload data. + upload bool + + donec chan struct{} // closed when done writing + // The following fields will be written before donec closes: + err error +} + +// escapeKey does all required escaping for UTF-8 strings to work with Azure. +// isPrefix indicates whether the key is a full key, or a prefix/delimiter. +func escapeKey(key string, isPrefix bool) string { + return escape.HexEscape(key, func(r []rune, i int) bool { + c := r[i] + switch { + // Azure does not work well with backslashes in blob names. + case c == '\\': + return true + // Azure doesn't handle these characters (determined via experimentation). + case c < 32 || c == 34 || c == 35 || c == 37 || c == 63 || c == 127: + return true + // Escape trailing "/" for full keys, otherwise Azure can't address them + // consistently. + case !isPrefix && i == len(key)-1 && c == '/': + return true + // For "../", escape the trailing slash. + case i > 1 && r[i] == '/' && r[i-1] == '.' && r[i-2] == '.': + return true + } + return false + }) +} + +// unescapeKey reverses escapeKey. +func unescapeKey(key string) string { + return escape.HexUnescape(key) +} + +// NewTypedWriter implements driver.NewTypedWriter. +func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType string, opts *driver.WriterOptions) (driver.Writer, error) { + key = escapeKey(key, false) + blobClient := b.client.NewBlockBlobClient(key) + if opts.BufferSize == 0 { + opts.BufferSize = defaultUploadBlockSize + } + if opts.MaxConcurrency == 0 { + opts.MaxConcurrency = defaultUploadBuffers + } + + md := make(map[string]*string, len(opts.Metadata)) + for k, v := range opts.Metadata { + // See the package comments for more details on escaping of metadata + // keys & values. + e := escape.HexEscape(k, func(runes []rune, i int) bool { + c := runes[i] + switch { + case i == 0 && c >= '0' && c <= '9': + return true + case escape.IsASCIIAlphanumeric(c): + return false + case c == '_': + return false + } + return true + }) + if _, ok := md[e]; ok { + return nil, fmt.Errorf("duplicate keys after escaping: %q => %q", k, e) + } + escaped := escape.URLEscape(v) + md[e] = &escaped + } + uploadOpts := &azblob.UploadStreamOptions{ + BlockSize: int64(opts.BufferSize), + Concurrency: opts.MaxConcurrency, + Metadata: md, + HTTPHeaders: &azblobblob.HTTPHeaders{ + BlobCacheControl: &opts.CacheControl, + BlobContentDisposition: &opts.ContentDisposition, + BlobContentEncoding: &opts.ContentEncoding, + BlobContentLanguage: &opts.ContentLanguage, + BlobContentMD5: opts.ContentMD5, + BlobContentType: &contentType, + }, + } + if opts.IfNotExist { + etagAny := azcore.ETagAny + uploadOpts.AccessConditions = &azblob.AccessConditions{ + ModifiedAccessConditions: &azblobblob.ModifiedAccessConditions{ + IfNoneMatch: &etagAny, + }, + } + } + if opts.BeforeWrite != nil { + asFunc := func(i any) bool { + p, ok := i.(**azblob.UploadStreamOptions) + if !ok { + return false + } + *p = uploadOpts + return true + } + if err := opts.BeforeWrite(asFunc); err != nil { + return nil, err + } + } + return &writer{ + ctx: ctx, + client: blobClient, + uploadOpts: uploadOpts, + donec: make(chan struct{}), + }, nil +} + +// Write appends p to w.pw. User must call Close to close the w after done writing. +func (w *writer) Write(p []byte) (int, error) { + // Avoid opening the pipe for a zero-length write; + // the concrete can do these for empty blobs. + if len(p) == 0 { + return 0, nil + } + if w.pw == nil { + // We'll write into pw and use pr as an io.Reader for the + // Upload call to Azure. + w.pr, w.pw = io.Pipe() + w.open(w.pr, true) + } + return w.pw.Write(p) +} + +// Upload reads from r. Per the driver, it is guaranteed to be the only +// write call for this writer. +func (w *writer) Upload(r io.Reader) error { + w.upload = true + w.open(r, false) + return nil +} + +// r may be nil if we're Closing and no data was written. +// If closePipeOnError is true, w.pr will be closed if there's an +// error uploading to Azure. +func (w *writer) open(r io.Reader, closePipeOnError bool) { + go func() { + defer close(w.donec) + + if r == nil { + r = http.NoBody + } + _, w.err = w.client.UploadStream(w.ctx, r, w.uploadOpts) + if w.err != nil { + if closePipeOnError { + w.pr.CloseWithError(w.err) + w.pr = nil + } + } + }() +} + +// Close completes the writer and closes it. Any error occurring during write will +// be returned. If a writer is closed before any Write is called, Close will +// create an empty file at the given key. +func (w *writer) Close() error { + if !w.upload { + if w.pr != nil { + defer w.pr.Close() + } + if w.pw == nil { + // We never got any bytes written. We'll write an http.NoBody. + w.open(nil, false) + } else if err := w.pw.Close(); err != nil { + return err + } + } + <-w.donec + return w.err +} diff --git a/go-cloud/blob/azureblob/azureblob_test.go b/go-cloud/blob/azureblob/azureblob_test.go new file mode 100644 index 000000000..0e2d150d7 --- /dev/null +++ b/go-cloud/blob/azureblob/azureblob_test.go @@ -0,0 +1,677 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 azureblob + +import ( + "context" + "encoding/base64" + "errors" + "fmt" + "net/http" + "net/url" + "os" + "strings" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" + azblobblob "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/sas" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/blob/drivertest" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" +) + +// Prerequisites for -record mode +// 1. Sign-in to your Azure Subscription at http://portal.azure.com. +// +// 2. Create a Storage Account. +// +// 3. Locate the Access Key (Primary or Secondary) under your Storage Account > Settings > Access Keys. +// +// 4. Set the environment variables AZURE_STORAGE_ACCOUNT, AZURE_STORAGE_KEY to +// the storage account name and your access key. +// +// 5. Create a container in your Storage Account > Blob. Update the bucketName +// constant to your container name. +// +// Here is a step-by-step walkthrough using the Azure Portal +// https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-portal +// +// 5. Run the tests with -record. + +const ( + bucketName = "go-cloud-bucket" + accountName = "gocloudblobtests" +) + +type harness struct { + clientFn func(bucketName string) (*container.Client, error) + closer func() + httpClient *http.Client +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + var key string + if *setup.Record { + name := os.Getenv("AZURE_STORAGE_ACCOUNT") + if name != accountName { + t.Fatalf("Please update the accountName constant to match your settings file so future records work (%q vs %q)", name, accountName) + } + key = os.Getenv("AZURE_STORAGE_KEY") + } else { + // In replay mode, we use fake credentials. + key = base64.StdEncoding.EncodeToString([]byte("FAKECREDS")) + } + credential, err := azblob.NewSharedKeyCredential(accountName, key) + if err != nil { + return nil, err + } + httpClient, done := setup.NewAzureTestBlobClient(ctx, t) + // Hack to work around the fact that SignedURLs for PUTs are not fully + // portable; they require a "x-ms-blob-type" header. Intercept all + // requests, and insert that header where needed. + httpClient.Transport = &requestInterceptor{httpClient.Transport} + clientOptions := container.ClientOptions{} + clientOptions.Transport = httpClient + serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net", accountName) + clientFn := func(bucketName string) (*container.Client, error) { + return container.NewClientWithSharedKeyCredential(serviceURL+"/"+bucketName, credential, &clientOptions) + } + return &harness{clientFn: clientFn, closer: done, httpClient: httpClient}, nil +} + +// requestInterceptor implements a hack for the lack of portability for +// SignedURLs for PUT. It adds the required "x-ms-blob-type" header where +// Azure requires it. +type requestInterceptor struct { + base http.RoundTripper +} + +func (ri *requestInterceptor) RoundTrip(req *http.Request) (*http.Response, error) { + if req.Method == http.MethodPut && strings.Contains(req.URL.Path, "blob-for-signing") { + reqClone := *req + reqClone.Header.Add("x-ms-blob-type", "BlockBlob") + req = &reqClone + } + return ri.base.RoundTrip(req) +} + +func (h *harness) HTTPClient() *http.Client { + return h.httpClient +} + +func (h *harness) MakeDriver(ctx context.Context) (driver.Bucket, error) { + client, err := h.clientFn(bucketName) + if err != nil { + return nil, err + } + return openBucket(ctx, client, nil) +} + +func (h *harness) MakeDriverForNonexistentBucket(ctx context.Context) (driver.Bucket, error) { + client, err := h.clientFn("bucket-does-not-exist") + if err != nil { + return nil, err + } + return openBucket(ctx, client, nil) +} + +func (h *harness) Close() { + h.closer() +} + +func TestConformance(t *testing.T) { + // See setup instructions above for more details. + // Disable the conformance tests, we don't have an Azure account anymore. + // drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyContentLanguage{}}) +} + +func BenchmarkAzureblob(b *testing.B) { + name := os.Getenv("AZURE_STORAGE_ACCOUNT") + key := os.Getenv("AZURE_STORAGE_KEY") + credential, err := azblob.NewSharedKeyCredential(name, key) + if err != nil { + b.Fatal(err) + } + containerURL := fmt.Sprintf("https://%s.blob.core.windows.net/%s", accountName, bucketName) + client, err := container.NewClientWithSharedKeyCredential(containerURL, credential, nil) + if err != nil { + b.Fatal(err) + } + bkt, err := OpenBucket(context.Background(), client, nil) + if err != nil { + b.Fatal(err) + } + drivertest.RunBenchmarks(b, bkt) +} + +var language = "nl" + +// verifyContentLanguage uses As to access the underlying Azure types and +// read/write the ContentLanguage field. +type verifyContentLanguage struct{} + +func (verifyContentLanguage) Name() string { + return "verify ContentLanguage can be written and read through As" +} + +func (verifyContentLanguage) BucketCheck(b *blob.Bucket) error { + var u *container.Client + if !b.As(&u) { + return errors.New("Bucket.As failed") + } + return nil +} + +func (verifyContentLanguage) ErrorCheck(b *blob.Bucket, err error) error { + return nil +} + +func (verifyContentLanguage) BeforeRead(as func(any) bool) error { + var u *azblob.DownloadStreamOptions + if !as(&u) { + return fmt.Errorf("BeforeRead As failed to get %T", u) + } + return nil +} + +func (verifyContentLanguage) BeforeWrite(as func(any) bool) error { + var azOpts *azblob.UploadStreamOptions + if !as(&azOpts) { + return errors.New("Writer.As failed") + } + azOpts.HTTPHeaders.BlobContentLanguage = &language + return nil +} + +func (verifyContentLanguage) BeforeCopy(as func(any) bool) error { + var co *azblobblob.StartCopyFromURLOptions + if !as(&co) { + return errors.New("BeforeCopy.As failed") + } + return nil +} + +func (verifyContentLanguage) BeforeList(as func(any) bool) error { + var azOpts *container.ListBlobsHierarchyOptions + if !as(&azOpts) { + return errors.New("BeforeList.As failed") + } + return nil +} + +func (verifyContentLanguage) BeforeSign(as func(any) bool) error { + var azOpts *sas.BlobPermissions + if !as(&azOpts) { + return errors.New("BeforeSign.As failed") + } + return nil +} + +func (verifyContentLanguage) AttributesCheck(attrs *blob.Attributes) error { + var resp azblobblob.GetPropertiesResponse + if !attrs.As(&resp) { + return errors.New("Attributes.As returned false") + } + if got := *resp.ContentLanguage; got != language { + return fmt.Errorf("got %q want %q", got, language) + } + return nil +} + +func (verifyContentLanguage) ReaderCheck(r *blob.Reader) error { + var resp azblobblob.DownloadStreamResponse + if !r.As(&resp) { + return errors.New("Reader.As returned false") + } + if got := *resp.ContentLanguage; got != language { + return fmt.Errorf("got %q want %q", got, language) + } + return nil +} + +func (verifyContentLanguage) ListObjectCheck(o *blob.ListObject) error { + if o.IsDir { + var prefix container.BlobPrefix + if !o.As(&prefix) { + return errors.New("ListObject.As for dir returned false") + } + return nil + } + var item container.BlobItem + if !o.As(&item) { + return errors.New("ListObject.As for object returned false") + } + if got := *item.Properties.ContentLanguage; got != language { + return fmt.Errorf("got %q want %q", got, language) + } + return nil +} + +func TestOpenBucket(t *testing.T) { + tests := []struct { + description string + nilClient bool + accountName string + want string + wantErr bool + }{ + { + description: "nil client results in error", + nilClient: true, + accountName: "myaccount", + wantErr: true, + }, + { + description: "success", + accountName: "myaccount", + want: "foo", + }, + } + + ctx := context.Background() + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + var client *container.Client + var err error + if !test.nilClient { + client, err = container.NewClientWithNoCredential("", nil) + if err != nil { + t.Fatal(err) + } + } + // Create portable type. + b, err := OpenBucket(ctx, client, nil) + if b != nil { + defer b.Close() + } + if (err != nil) != test.wantErr { + t.Errorf("got err %v want error %v", err, test.wantErr) + } + }) + } +} + +func TestOpenerFromEnv(t *testing.T) { + tests := []struct { + accountName string + accountKey string + sasToken string + connectionString string + connectionString2 string + domain string + protocol string + isCDN bool + isLocalEmulator bool + + want *credInfoT + wantOpts *ServiceURLOptions + }{ + { + // Shared key. + accountName: "myaccount", + accountKey: "fakecreds", + want: &credInfoT{ + CredType: credTypeSharedKey, + AccountName: "myaccount", + AccountKey: "fakecreds", + }, + wantOpts: &ServiceURLOptions{ + AccountName: "myaccount", + }, + }, + { + // SAS Token. + accountName: "myaccount", + sasToken: "a-sas-token", + want: &credInfoT{ + CredType: credTypeSASViaNone, + AccountName: "myaccount", + }, + wantOpts: &ServiceURLOptions{ + AccountName: "myaccount", + SASToken: "a-sas-token", + }, + }, + { + // Connection string. + accountName: "myaccount", + connectionString: "a-connection-string", + want: &credInfoT{ + CredType: credTypeConnectionString, + AccountName: "myaccount", + ConnectionString: "a-connection-string", + }, + wantOpts: &ServiceURLOptions{ + AccountName: "myaccount", + }, + }, + { + // Connection string provides default protocol and account name. + connectionString: "DefaultEndpointsProtocol=https;AccountName=another-account", + want: &credInfoT{ + CredType: credTypeConnectionString, + ConnectionString: "DefaultEndpointsProtocol=https;AccountName=another-account", + }, + wantOpts: &ServiceURLOptions{ + AccountName: "another-account", + Protocol: "https", + }, + }, + { + // Alternate connection string. + accountName: "myaccount", + connectionString2: "a-connection-string", + want: &credInfoT{ + CredType: credTypeConnectionString, + AccountName: "myaccount", + ConnectionString: "a-connection-string", + }, + wantOpts: &ServiceURLOptions{ + AccountName: "myaccount", + }, + }, + { + // Default. + accountName: "anotheraccount", + want: &credInfoT{ + CredType: credTypeDefault, + AccountName: "anotheraccount", + }, + wantOpts: &ServiceURLOptions{ + AccountName: "anotheraccount", + }, + }, + { + // Setting protocol and domain. + accountName: "myaccount", + protocol: "http", + domain: "foo.bar.com", + want: &credInfoT{ + CredType: credTypeDefault, + AccountName: "myaccount", + }, + wantOpts: &ServiceURLOptions{ + AccountName: "myaccount", + Protocol: "http", + StorageDomain: "foo.bar.com", + }, + }, + { + // Local emulator. + accountName: "myaccount", + isLocalEmulator: true, + want: &credInfoT{ + CredType: credTypeDefault, + AccountName: "myaccount", + }, + wantOpts: &ServiceURLOptions{ + AccountName: "myaccount", + IsLocalEmulator: true, + }, + }, + } + for _, test := range tests { + t.Setenv("AZURE_STORAGE_ACCOUNT", test.accountName) + t.Setenv("AZURE_STORAGE_KEY", test.accountKey) + t.Setenv("AZURE_STORAGE_SAS_TOKEN", test.sasToken) + t.Setenv("AZURE_STORAGE_CONNECTION_STRING", test.connectionString) + t.Setenv("AZURE_STORAGEBLOB_CONNECTIONSTRING", test.connectionString2) + t.Setenv("AZURE_STORAGE_DOMAIN", test.domain) + t.Setenv("AZURE_STORAGE_PROTOCOL", test.protocol) + if test.isCDN { + t.Setenv("AZURE_STORAGE_IS_CDN", "true") + } else { + t.Setenv("AZURE_STORAGE_IS_CDN", "") + } + if test.isLocalEmulator { + t.Setenv("AZURE_STORAGE_IS_LOCAL_EMULATOR", "true") + } else { + t.Setenv("AZURE_STORAGE_IS_LOCAL_EMULATOR", "") + } + + got := newCredInfoFromEnv() + if diff := cmp.Diff(got, test.want); diff != "" { + t.Errorf("unexpected diff in credInfo: %s", diff) + } + gotOpts := NewDefaultServiceURLOptions() + if diff := cmp.Diff(gotOpts, test.wantOpts); diff != "" { + t.Errorf("unexpected diff in Options: %s", diff) + } + + } +} + +func TestNewServiceURL(t *testing.T) { + tests := []struct { + opts ServiceURLOptions + query url.Values + want ServiceURL + wantErrOverrides bool + wantErrURL bool + }{ + { + // Unknown query parameter. + opts: ServiceURLOptions{ + AccountName: "myaccount", + }, + query: url.Values{ + "foo": {"bar"}, + }, + wantErrOverrides: true, + }, + { + // Duplicate query parameter. + opts: ServiceURLOptions{ + AccountName: "myaccount", + }, + query: url.Values{ + "domain": {"blob.core.usgovcloudapi.net", "blob.core.windows.net"}, + }, + wantErrOverrides: true, + }, + { + // Missing account name. + opts: ServiceURLOptions{}, + wantErrURL: true, + }, + { + // Account name set in the query + opts: ServiceURLOptions{}, + query: url.Values{ + "storage_account": {"testaccount"}, + }, + want: "https://testaccount.blob.core.windows.net", + }, + { + // Basic working case. + opts: ServiceURLOptions{ + AccountName: "myaccount", + }, + want: "https://myaccount.blob.core.windows.net", + }, + { + // SASToken. + opts: ServiceURLOptions{ + AccountName: "myaccount", + SASToken: "my-sas-token", + }, + want: "https://myaccount.blob.core.windows.net?my-sas-token", + }, + { + // Setting domain from ServiceURLOptions. + opts: ServiceURLOptions{ + AccountName: "myaccount", + StorageDomain: "blob.core.usgovcloudapi.net", + }, + want: "https://myaccount.blob.core.usgovcloudapi.net", + }, + { + // Setting domain from the URL. + opts: ServiceURLOptions{ + AccountName: "myaccount", + StorageDomain: "overridden", + }, + query: url.Values{ + "domain": {"blob.core.usgovcloudapi.net"}, + }, + want: "https://myaccount.blob.core.usgovcloudapi.net", + }, + { + // Setting protocol from ServiceURLOptions. + opts: ServiceURLOptions{ + AccountName: "myaccount", + Protocol: "http", + }, + want: "http://myaccount.blob.core.windows.net", + }, + { + // Setting protocol from the URL. + opts: ServiceURLOptions{ + AccountName: "myaccount", + Protocol: "https", + }, + query: url.Values{ + "protocol": {"http"}, + }, + want: "http://myaccount.blob.core.windows.net", + }, + { + // Setting IsCDN from ServiceURLOptions. + opts: ServiceURLOptions{ + AccountName: "myaccount", + IsCDN: true, + }, + want: "https://blob.core.windows.net", + }, + { + // Setting IsCDN from the URL. + opts: ServiceURLOptions{ + AccountName: "myaccount", + }, + query: url.Values{ + "cdn": {"true"}, + }, + want: "https://blob.core.windows.net", + }, + { + // Local emulator, implicit from domain. + opts: ServiceURLOptions{ + AccountName: "myaccount", + Protocol: "http", + StorageDomain: "localhost:10001", + }, + want: "http://localhost:10001/myaccount", + }, + { + // Local emulator, implicit from domain through URL parameter. + opts: ServiceURLOptions{ + AccountName: "myaccount", + }, + query: url.Values{ + "protocol": {"http"}, + "domain": {"127.0.0.1:10001"}, + }, + want: "http://127.0.0.1:10001/myaccount", + }, + { + // Local emulator, explicit through ServiceURLOptions. + opts: ServiceURLOptions{ + AccountName: "myaccount", + StorageDomain: "mylocalemulator", + IsLocalEmulator: true, + }, + want: "https://mylocalemulator/myaccount", + }, + { + // Local emulator, explicit through URL parameter. + opts: ServiceURLOptions{ + AccountName: "myaccount", + StorageDomain: "mylocalemulator", + }, + query: url.Values{ + "localemu": {"true"}, + }, + want: "https://mylocalemulator/myaccount", + }, + } + + for _, test := range tests { + opts, err := test.opts.withOverrides(test.query) + if (err != nil) != test.wantErrOverrides { + t.Fatalf("withOverrides got err %v want error %v", err, test.wantErrOverrides) + } + if err != nil { + continue + } + got, err := NewServiceURL(opts) + if (err != nil) != test.wantErrURL { + t.Errorf("NewServiceURL got err %v want error %v", err, test.wantErrURL) + } + if got != test.want { + t.Errorf("got %q want %q", got, test.want) + } + } +} + +func TestOpenBucketFromURL(t *testing.T) { + t.Setenv("AZURE_STORAGE_ACCOUNT", "my-account") + t.Setenv("AZURE_STORAGE_KEY", "bXlrZXk=") // mykey base64 encoded + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"azblob://mybucket", false}, + // With storage domain. + {"azblob://mybucket?domain=blob.core.usgovcloudapi.net", false}, + // With duplicate storage domain. + {"azblob://mybucket?domain=blob.core.usgovcloudapi.net&domain=blob.core.windows.net", true}, + // With protocol. + {"azblob://mybucket?protocol=http", false}, + // With invalid protocol. + {"azblob://mybucket?protocol=ftp", true}, + // With Account. + {"azblob://mybucket?storage_account=test", false}, + // With CDN. + {"azblob://mybucket?cdn=true", false}, + // With invalid CDN. + {"azblob://mybucket?cdn=42", true}, + // With local emulator. + {"azblob://mybucket?localemu=true", false}, + // With invalid local emulator. + {"azblob://mybucket?localemu=42", true}, + // Invalid parameter. + {"azblob://mybucket?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + b, err := blob.OpenBucket(ctx, test.URL) + if b != nil { + defer b.Close() + } + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + } +} diff --git a/go-cloud/blob/azureblob/example_test.go b/go-cloud/blob/azureblob/example_test.go new file mode 100644 index 000000000..ab688c336 --- /dev/null +++ b/go-cloud/blob/azureblob/example_test.go @@ -0,0 +1,99 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 azureblob_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/azureblob" +) + +func ExampleOpenBucket() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + const ( + // The storage container to access. + containerName = "my-container" + ) + + // Construct the service URL. + // There are many forms of service URLs, see ServiceURLOptions. + opts := azureblob.NewDefaultServiceURLOptions() + serviceURL, err := azureblob.NewServiceURL(opts) + if err != nil { + log.Fatal(err) + } + + // There are many ways to authenticate to Azure. + // This approach uses environment variables as described in azureblob package + // documentation. + // For example, to use shared key authentication, you would set + // AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_KEY. + // To use a SAS token, you would set AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_SAS_TOKEN. + // You can also construct a client using the azblob constructors directly, like + // azblob.NewServiceClientWithSharedKey. + client, err := azureblob.NewDefaultClient(serviceURL, containerName) + if err != nil { + log.Fatal(err) + } + + // Create a *blob.Bucket. + b, err := azureblob.OpenBucket(ctx, client, nil) + if err != nil { + log.Fatal(err) + } + defer b.Close() + + // Now we can use b to read or write files to the container. + data, err := b.ReadAll(ctx, "my-key") + if err != nil { + log.Fatal(err) + } + _ = data +} + +func Example_openBucketFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/blob/azureblob" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // blob.OpenBucket creates a *blob.Bucket from a URL. + // This URL will open the container "my-container" using default + // credentials found in environment variables as documented in + // the package. + // Assuming AZURE_STORAGE_ACCOUNT is set to "myaccount", + // and other options aren't set, the service URL will look like: + // "https://myaccount.blob.core.windows.net/my-container". + bucket, err := blob.OpenBucket(ctx, "azblob://my-container") + if err != nil { + log.Fatal(err) + } + defer bucket.Close() + + // Another example, against a local emulator. + // Assuming AZURE_STORAGE_ACCOUNT is set to "myaccount", + // the service URL will look like: + // "http://localhost:10001/myaccount/my-container". + localbucket, err := blob.OpenBucket(ctx, "azblob://my-container?protocol=http&domain=localhost:10001") + if err != nil { + log.Fatal(err) + } + defer localbucket.Close() +} diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..31cabfa5d --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,651 @@ +{ + "Initial": "AQAAAA7dVMCoCXoOugAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "263b7cb086987c42", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Etag": [ + "\"0x8DC2770B72624DD\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "vo7q9sPVKY0=" + ], + "X-Ms-Request-Id": [ + "9326ea65-501e-0022-2659-59dd3d000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "b0c2271384f1ba35", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Etag": [ + "\"0x8DC2770B72624DD\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9326ea81-501e-0022-3f59-59dd3d000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "4958b3f90ff42b91", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Etag": [ + "\"0x8DC2770B72624DD\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9326ea96-501e-0022-5359-59dd3d000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "3ade4c5a78464254", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=1000\u0026prefix=mydir\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "9326eab1-501e-0022-6e59-59dd3d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5teWRpcjwvUHJlZml4PjxNYXhSZXN1bHRzPjEwMDA8L01heFJlc3VsdHM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iUHJlZml4PjxOYW1lPm15ZGlyLzwvTmFtZT48L0Jsb2JQcmVmaXg+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "92bb4ce2fe59cf71", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=mydir%2Fas-test\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "9326eac5-501e-0022-0159-59dd3d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5teWRpci9hcy10ZXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+bXlkaXIvYXMtdGVzdDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5XZWQsIDA3IEZlYiAyMDI0IDAwOjA3OjA0IEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5XZWQsIDA3IEZlYiAyMDI0IDAwOjA3OjA0IEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEQzI3NzBCNzI2MjRERDwvRXRhZz48Q29udGVudC1MZW5ndGg+MTE8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5Yclk3dStBZTd0Q1R5eUs3ajFyTnd3PT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "14ae09b3f7f54dda", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key-does-not-exist", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "9326eadb-501e-0022-1759-59dd3d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOjkzMjZlYWRiLTUwMWUtMDAyMi0xNzU5LTU5ZGQzZDAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDc6MDQuMzMzNjA0Nlo8L01lc3NhZ2U+PC9FcnJvcj4=" + } + }, + { + "ID": "99d0ff29b9a3532b", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Etag": [ + "\"0x8DC2770B73D7A0F\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "1a08d5cd-b2c2-425d-9d53-4ebf7e80652c" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "9326eaef-501e-0022-2a59-59dd3d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "d158d20bf63fb935", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "9326eb1e-501e-0022-5859-59dd3d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "a7c2e1ede335ea4f", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "9326eb3a-501e-0022-7259-59dd3d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay new file mode 100644 index 000000000..3220c927a --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay @@ -0,0 +1,657 @@ +{ + "Initial": "AQAAAA7dVMCnNM6o9QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "01721fa428e61498", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "nl" + ], + "X-Ms-Blob-Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Etag": [ + "\"0x8DC2770B6FCF804\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "vo7q9sPVKY0=" + ], + "X-Ms-Request-Id": [ + "6ef84252-001e-005d-0b59-5912a6000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "a7694ffd8490b83d", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Etag": [ + "\"0x8DC2770B6FCF804\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6ef84282-001e-005d-3959-5912a6000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "8bf2231dfb60c2bd", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Etag": [ + "\"0x8DC2770B6FCF804\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6ef842a6-001e-005d-5c59-5912a6000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "f180d69676c1b7c9", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=1000\u0026prefix=mydir\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:03 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6ef842cf-001e-005d-0559-5912a6000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5teWRpcjwvUHJlZml4PjxNYXhSZXN1bHRzPjEwMDA8L01heFJlc3VsdHM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iUHJlZml4PjxOYW1lPm15ZGlyLzwvTmFtZT48L0Jsb2JQcmVmaXg+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "40688ac858bc60be", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=mydir%2Fas-test\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6ef842f4-001e-005d-2a59-5912a6000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5teWRpci9hcy10ZXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+bXlkaXIvYXMtdGVzdDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5XZWQsIDA3IEZlYiAyMDI0IDAwOjA3OjAzIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5XZWQsIDA3IEZlYiAyMDI0IDAwOjA3OjAzIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEQzI3NzBCNkZDRjgwNDwvRXRhZz48Q29udGVudC1MZW5ndGg+MTE8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2U+bmw8L0NvbnRlbnQtTGFuZ3VhZ2U+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WHJZN3UrQWU3dENUeXlLN2oxck53dz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "e83287343cdc46ce", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key-does-not-exist", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "6ef8431c-001e-005d-5259-5912a6000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOjZlZjg0MzFjLTAwMWUtMDA1ZC01MjU5LTU5MTJhNjAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDc6MDQuMDY0MTQwMlo8L01lc3NhZ2U+PC9FcnJvcj4=" + } + }, + { + "ID": "8d127e157ee5ebb5", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "Etag": [ + "\"0x8DC2770B711405A\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "37af6199-5347-4d3f-af0f-4f9f6c4756a1" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "6ef8433e-001e-005d-7459-5912a6000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "983526e9b3abd7ac", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "6ef84385-001e-005d-3b59-5912a6000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "d61ab5e3f854200d", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/mydir%2Fas-test", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:04 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "6ef843ab-001e-005d-6159-5912a6000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestAttributes.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestAttributes.replay new file mode 100644 index 000000000..a20f8552e --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestAttributes.replay @@ -0,0 +1,708 @@ +{ + "Initial": "AQAAAA7dVMB3AyjflwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "07d79e112173f31e", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/someDir%2Fblob-for-attributes", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "12" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "no-cache" + ], + "X-Ms-Blob-Content-Disposition": [ + "inline" + ], + "X-Ms-Blob-Content-Encoding": [ + "identity" + ], + "X-Ms-Blob-Content-Language": [ + "en" + ], + "X-Ms-Blob-Content-Md5": [ + "7Qdih1MuhjZehB6Sv8UNjA==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "SGVsbG8gV29ybGQh" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "7Qdih1MuhjZehB6Sv8UNjA==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Etag": [ + "\"0x8DC277099E0B43E\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "peH8Xsgc5QI=" + ], + "X-Ms-Request-Id": [ + "4eb2518f-c01e-006d-0359-59ac69000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "9099cbc51fadb608", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/not-found", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "4eb25196-c01e-006d-0859-59ac69000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "9d849cfb58368608", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/someDir", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "4eb2519e-c01e-006d-0e59-59ac69000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "5d6522afd6f2795c", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/someDir__0x2f__", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "4eb251a7-c01e-006d-1559-59ac69000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "874738484cf4a9d1", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/someDir%2Fblob-for-attributes", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "12" + ], + "Content-Md5": [ + "7Qdih1MuhjZehB6Sv8UNjA==" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Etag": [ + "\"0x8DC277099E0B43E\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4eb251ac-c01e-006d-1a59-59ac69000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "fd98b60aafcc104c", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/someDir%2Fblob-for-attributes", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "12" + ], + "Content-Md5": [ + "7Qdih1MuhjZehB6Sv8UNjA==" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Etag": [ + "\"0x8DC277099E0B43E\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4eb251af-c01e-006d-1d59-59ac69000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "SGVsbG8gV29ybGQh" + } + }, + { + "ID": "67a95fc9e9c49265", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/someDir%2Fblob-for-attributes", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "12" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "7Qdih1MuhjZehB6Sv8UNjA==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "SGVsbG8gV29ybGQh" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "7Qdih1MuhjZehB6Sv8UNjA==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Etag": [ + "\"0x8DC277099F3EB4C\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "peH8Xsgc5QI=" + ], + "X-Ms-Request-Id": [ + "4eb251b6-c01e-006d-2259-59ac69000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "291af2e2795f3fde", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/someDir%2Fblob-for-attributes", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "12" + ], + "Content-Md5": [ + "7Qdih1MuhjZehB6Sv8UNjA==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Etag": [ + "\"0x8DC277099F3EB4C\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4eb251b8-c01e-006d-2459-59ac69000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "2680d47826e7406a", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/someDir%2Fblob-for-attributes", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "4eb251bb-c01e-006d-2759-59ac69000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay new file mode 100644 index 000000000..63d7b5bf5 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay @@ -0,0 +1,361 @@ +{ + "Initial": "AQAAAA7dVMCiBLAKEwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "3d7ad495cc57c2ad", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-canceled-write", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3865400\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "vo7q9sPVKY0=" + ], + "X-Ms-Request-Id": [ + "4be00b01-d01e-003c-1759-5931e5000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "2731ae1b79161b62", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-canceled-write", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3865400\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4be00b08-d01e-003c-1c59-5931e5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "a4aaa3ea871ace92", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-canceled-write", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3865400\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4be00b10-d01e-003c-2259-5931e5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "2223836ab248b04b", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-canceled-write", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "4be00b1b-d01e-003c-2a59-5931e5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay new file mode 100644 index 000000000..d5bd6bec6 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay @@ -0,0 +1,161 @@ +{ + "Initial": "AQAAAA7dVMChNFKfDgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "6e9395cdc202785a", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-canceled-write", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "92be14ee-101e-006e-7559-594d0d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOjkyYmUxNGVlLTEwMWUtMDA2ZS03NTU5LTU5NGQwZDAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDY6NTcuOTUzNDE3Nlo8L01lc3NhZ2U+PC9FcnJvcj4=" + } + }, + { + "ID": "17768546db354bf1", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-canceled-write", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "92be14f8-101e-006e-7d59-594d0d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOjkyYmUxNGY4LTEwMWUtMDA2ZS03ZDU5LTU5NGQwZDAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDY6NTcuOTcyNDA2MVo8L01lc3NhZ2U+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay new file mode 100644 index 000000000..5b10217ae --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay @@ -0,0 +1,161 @@ +{ + "Initial": "AQAAAA7dVMChOjAhtgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "e07ece6d59da230b", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-canceled-write", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "5dc61a7a-c01e-0030-2459-59a6ed000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOjVkYzYxYTdhLWMwMWUtMDAzMC0yNDU5LTU5YTZlZDAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDY6NTguMDQ4Nzc3OFo8L01lc3NhZ2U+PC9FcnJvcj4=" + } + }, + { + "ID": "09faf066d14d05fe", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-canceled-write", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "5dc61a85-c01e-0030-2b59-59a6ed000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOjVkYzYxYTg1LWMwMWUtMDAzMC0yYjU5LTU5YTZlZDAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDY6NTguMDY4NzY1MVo8L01lc3NhZ2U+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestConcurrentWriteAndRead.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestConcurrentWriteAndRead.replay new file mode 100644 index 000000000..8fba08230 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestConcurrentWriteAndRead.replay @@ -0,0 +1,4665 @@ +{ + "Initial": "AQAAAA7dVMCiDd39qwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "35faf9bb0b90a459", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key5", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "YfRaKQkG0Wv1UeeMsD1f+Q==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "YfRaKQkG0Wv1UeeMsD1f+Q==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A45EEC\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "nDUBXIJsdys=" + ], + "X-Ms-Request-Id": [ + "80b9adee-b01e-0015-3759-590f91000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "90273f42e536a416", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key12", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "VkGQ+3LJseHAFopbb+BYvg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "VkGQ+3LJseHAFopbb+BYvg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A374AC\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "rz0qlyRkeGI=" + ], + "X-Ms-Request-Id": [ + "b7910625-301e-0034-7b59-592bea000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "ff9e31c2d535e7bb", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key9", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "kfsiuKRZ73D7CzauKodAhg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQ==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "kfsiuKRZ73D7CzauKodAhg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A45EEC\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "fb4JIMHbjS0=" + ], + "X-Ms-Request-Id": [ + "c80655ca-601e-0074-1859-592cd2000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "e8c86a57285e0806", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key0", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "Yg8LZ6kff3QVG8W+dFtxEA==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "Yg8LZ6kff3QVG8W+dFtxEA==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A17938\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "TrYi62fTgmQ=" + ], + "X-Ms-Request-Id": [ + "c6b7d4fb-601e-0064-1359-59e9ba000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "47a7a68a5318a47a", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key17", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "32eeXsj7ZyhCl0o20wPQ/w==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "EREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQ==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "32eeXsj7ZyhCl0o20wPQ/w==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A26369\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "v6kY2Ee1eCA=" + ], + "X-Ms-Request-Id": [ + "fc0d49d0-401e-005c-6d59-594d7a000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "80d670b0daa1350d", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key14", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "NlFDUFM0TpF1S+MXE1PxDg==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "Dg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "NlFDUFM0TpF1S+MXE1PxDg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A437E4\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "bEbvZqMjdxU=" + ], + "X-Ms-Request-Id": [ + "8232c10a-301e-0046-0259-592ca5000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "35d86e59500abe24", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key4", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "H06jyF3ZsJDOcwyB5gg+zw==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "H06jyF3ZsJDOcwyB5gg+zw==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A1EE44\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "yEGoCGhcnIo=" + ], + "X-Ms-Request-Id": [ + "fb4f5b57-401e-002e-4859-594a35000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "ae2c68ddada02447", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key15", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "qHqy3TOCPLWABZ/YTEeiAg==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "qHqy3TOCPLWABZ/YTEeiAg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A1EE44\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "ODJGMkkTnLQ=" + ], + "X-Ms-Request-Id": [ + "7183feb5-601e-004b-3959-59e471000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "9d050226ccfc3ade", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key1", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "qo85ln3rRBpudISWOUWpYA==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "qo85ln3rRBpudISWOUWpYA==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A54925\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "GsKLv43jacU=" + ], + "X-Ms-Request-Id": [ + "7f19919b-501e-0050-1d59-59da72000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "07f3cf75031f4576", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key10", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "AXKK1JVcZ791KxchIXYNNg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "AXKK1JVcZ791KxchIXYNNg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A54925\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "6rFlhaysafs=" + ], + "X-Ms-Request-Id": [ + "87762cce-f01e-002b-7f59-5998ee000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "9b36985b9de1ac64", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key11", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "AbDmWR96f1VIFnW4JQ5/SA==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "CwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCw==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "AbDmWR96f1VIFnW4JQ5/SA==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A54925\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "vsXM0Uacglo=" + ], + "X-Ms-Request-Id": [ + "395524dc-501e-000d-0659-59d0f6000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "cc9a0d78b1ea1b8b", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key19", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "2w9S4aRqKABHoeAhyiAJMA==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEw==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "2w9S4aRqKABHoeAhyiAJMA==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A3E9D0\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "fNLdKcDyd1c=" + ], + "X-Ms-Request-Id": [ + "f149b5a4-801e-007c-0f59-5936dd000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "a39417c1066e986a", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key6", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "lko2uDqoJrgEyYNnvcJ6vw==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "lko2uDqoJrgEyYNnvcJ6vw==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A4FB11\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "Czpt+e8bk/0=" + ], + "X-Ms-Request-Id": [ + "f4beaff0-f01e-0049-4259-595ac9000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "20eb4c7fe547675a", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key13", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "SsTzFZ3m7R1NrIc42UKW+Q==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "SsTzFZ3m7R1NrIc42UKW+Q==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A485F7\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "+0mDw85Uk8M=" + ], + "X-Ms-Request-Id": [ + "a431884f-601e-0080-3959-59e724000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "c12d8dddbd959410", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key2", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "ZUHn/UhoC5tg7AVev6McAg==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "ZUHn/UhoC5tg7AVev6McAg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A54925\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "jc3nGuCUjRM=" + ], + "X-Ms-Request-Id": [ + "56e8fa50-001e-002f-5f59-5915e9000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "4b5f7a6bbc22547a", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key3", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "7tBPOyKIo0omYOmbN3Ht7w==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "7tBPOyKIo0omYOmbN3Ht7w==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A4FB11\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "2blOTgqkZrI=" + ], + "X-Ms-Request-Id": [ + "2b3e4806-b01e-003a-3c59-59025a000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "a44153651eaec20d", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key8", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "qPZPE0uAGBNKE6LhEQTA8Q==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "qPZPE0uAGBNKE6LhEQTA8Q==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A4D408\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "KcqgdCvrZow=" + ], + "X-Ms-Request-Id": [ + "6a2d0c30-801e-0021-2359-593c59000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "c0aad7b8e8f4e0f6", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key16", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "65n9CjdrJkNQEaG4fFWMgQ==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEA==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "65n9CjdrJkNQEaG4fFWMgQ==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A4ACFF\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "692xjK2Fk4E=" + ], + "X-Ms-Request-Id": [ + "41c4e666-a01e-0036-5159-599552000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "753addf13ba893a4", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key18", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "wZvI1MtOgANGQD0gzZ4NUg==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "EhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEg==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "wZvI1MtOgANGQD0gzZ4NUg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A4FB11\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "KKZ0fSrCnPY=" + ], + "X-Ms-Request-Id": [ + "2597e5c4-f01e-0082-4d59-59599c000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "e4525c468c961e68", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key7", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "4096" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "kbuiTp5JEugjwAkgztPoXA==" + ], + "X-Ms-Blob-Content-Type": [ + "application/octet-stream" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "kbuiTp5JEugjwAkgztPoXA==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A59738\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "X07ErQUreFw=" + ], + "X-Ms-Request-Id": [ + "df382daf-c01e-001f-2859-59ab26000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "26fe097b8dfc0dd9", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key4", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "H06jyF3ZsJDOcwyB5gg+zw==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A1EE44\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "fb4f5b71-401e-002e-6159-594a35000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA==" + } + }, + { + "ID": "07deadfa1fa50a87", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key1", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "qo85ln3rRBpudISWOUWpYA==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A54925\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "c6b7d51f-601e-0064-3559-59e9ba000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ==" + } + }, + { + "ID": "5f04ee03f54cc943", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key13", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "SsTzFZ3m7R1NrIc42UKW+Q==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A485F7\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "c6b7d52f-601e-0064-4359-59e9ba000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ==" + } + }, + { + "ID": "dedf915bb1654380", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key2", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "ZUHn/UhoC5tg7AVev6McAg==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A54925\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "fb4f5b80-401e-002e-6f59-594a35000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg==" + } + }, + { + "ID": "d17cf656d5d64521", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key14", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "NlFDUFM0TpF1S+MXE1PxDg==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A437E4\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "c6b7d539-601e-0064-4d59-59e9ba000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "Dg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg==" + } + }, + { + "ID": "8d7807162b60f184", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key10", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "AXKK1JVcZ791KxchIXYNNg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A54925\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "fb4f5b88-401e-002e-7759-594a35000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg==" + } + }, + { + "ID": "c6bfcbf1e1a2b857", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key5", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "YfRaKQkG0Wv1UeeMsD1f+Q==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A45EEC\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "c6b7d548-601e-0064-5959-59e9ba000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ==" + } + }, + { + "ID": "0afd2bf72ee252b2", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key16", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "65n9CjdrJkNQEaG4fFWMgQ==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A4ACFF\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "fb4f5b8f-401e-002e-7e59-594a35000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEA==" + } + }, + { + "ID": "1ec32073ef487318", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key17", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "32eeXsj7ZyhCl0o20wPQ/w==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A26369\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "de1d6d10-501e-006f-1259-5912d1000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "EREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQ==" + } + }, + { + "ID": "6dca688273167df4", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key9", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "kfsiuKRZ73D7CzauKodAhg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A45EEC\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "e9dfb127-901e-0012-4459-5963f2000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQ==" + } + }, + { + "ID": "75c7c90a95321532", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key19", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "2w9S4aRqKABHoeAhyiAJMA==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A3E9D0\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "fbd8baf5-b01e-002a-4059-59c732000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEw==" + } + }, + { + "ID": "27714b93c7c1d3a0", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key6", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "lko2uDqoJrgEyYNnvcJ6vw==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A4FB11\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "241ca3e9-201e-0038-3859-59bce2000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg==" + } + }, + { + "ID": "2185cabf029d51a7", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key7", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "kbuiTp5JEugjwAkgztPoXA==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A59738\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "a0c1845f-801e-0053-1a59-593b16000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw==" + } + }, + { + "ID": "df34ad02c8238aaf", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key0", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "Yg8LZ6kff3QVG8W+dFtxEA==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A17938\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "52966d83-801e-006c-1059-59f3b5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" + } + }, + { + "ID": "ff47e414d7444d0e", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key18", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "wZvI1MtOgANGQD0gzZ4NUg==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A4FB11\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "20ff1db7-a01e-0009-6559-595df1000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "EhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEg==" + } + }, + { + "ID": "c8381a049bf86db2", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key12", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "VkGQ+3LJseHAFopbb+BYvg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A374AC\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "ca36575d-e01e-0008-4859-59022d000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA==" + } + }, + { + "ID": "4fa11485a6df10c4", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key8", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "qPZPE0uAGBNKE6LhEQTA8Q==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A4D408\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6b619a89-901e-004f-3659-596976000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA==" + } + }, + { + "ID": "613e20421f735bda", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key3", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "7tBPOyKIo0omYOmbN3Ht7w==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A4FB11\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "d5a00ca0-701e-0068-2059-597eb2000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw==" + } + }, + { + "ID": "469ce3073f304ba7", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key11", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "AbDmWR96f1VIFnW4JQ5/SA==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A54925\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "e389d7eb-801e-000e-0d59-593192000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "CwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCw==" + } + }, + { + "ID": "3aba728c3505516c", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key15", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "4096" + ], + "Content-Md5": [ + "qHqy3TOCPLWABZ/YTEeiAg==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3A1EE44\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "7f537300-901e-0060-4559-5964bd000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw==" + } + }, + { + "ID": "ab3481045a6727db", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key19", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e60-001e-0062-5359-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "95605225d1d308a6", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key18", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e67-001e-0062-5859-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "23562f8d5b876fdf", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key17", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e6a-001e-0062-5b59-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "ee72eb93c46a680a", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key16", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e6f-001e-0062-6059-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "e212bc4636ab58ad", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key15", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e75-001e-0062-6659-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "aaa999d25bce69c4", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key14", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e78-001e-0062-6959-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "b404c4503de3d99d", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key13", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e7c-001e-0062-6d59-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "704a8e6bcfc73833", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key12", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e7f-001e-0062-6f59-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "6fa0a007dbd6a2b2", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key11", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e83-001e-0062-7259-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "70f2bdd3f69545ed", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key10", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e8b-001e-0062-7a59-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "3f66aaae92580d04", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key9", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e97-001e-0062-0659-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "b56e9b960633df9f", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key8", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322e9b-001e-0062-0a59-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "ea9c9b34ce96414d", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key7", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322ea7-001e-0062-1159-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "ff4054568c1eec2e", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key6", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322ea8-001e-0062-1259-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "243f09f5ac2a8b42", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key5", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322eb0-001e-0062-1859-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "9233cdde09f73837", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key4", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322eb6-001e-0062-1e59-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "b9e2e7fada0f2558", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key3", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322ebe-001e-0062-2659-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "4c05cbd8a7672aeb", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key2", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322ec5-001e-0062-2d59-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "3cb9ad0e1886bd94", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key1", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322ecb-001e-0062-3359-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "768387140a4f7510", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key0", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a9322ed3-001e-0062-3b59-59da05000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestCopy/NonExistentSourceFails.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestCopy/NonExistentSourceFails.replay new file mode 100644 index 000000000..366d3b8e9 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestCopy/NonExistentSourceFails.replay @@ -0,0 +1,109 @@ +{ + "Initial": "AQAAAA7dVMCjNq/IsgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "e1c4cf9539dee835", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-dest", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/does-not-exist" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "ba760d19-d01e-0061-4c59-593b61000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOmJhNzYwZDE5LWQwMWUtMDA2MS00YzU5LTU5M2I2MTAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDY6NTkuOTkwNTcwNFo8L01lc3NhZ2U+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestCopy/Works.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestCopy/Works.replay new file mode 100644 index 000000000..7e0fb665e --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestCopy/Works.replay @@ -0,0 +1,924 @@ +{ + "Initial": "AQAAAA7dVMCjO5aflwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "f87109358f7e8773", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-src", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "no-cache" + ], + "X-Ms-Blob-Content-Disposition": [ + "inline" + ], + "X-Ms-Blob-Content-Encoding": [ + "identity" + ], + "X-Ms-Blob-Content-Language": [ + "en" + ], + "X-Ms-Blob-Content-Md5": [ + "sQqNsWTgdUEFt6mb5y4/5Q==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Meta-Foo": [ + "bar" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "SGVsbG8gV29ybGQ=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "sQqNsWTgdUEFt6mb5y4/5Q==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4AB4855\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "YeJLfssylmU=" + ], + "X-Ms-Request-Id": [ + "47d5f536-d01e-004e-6659-5936aa000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "d4ffcb5836b6da9c", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-src", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "sQqNsWTgdUEFt6mb5y4/5Q==" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4AB4855\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Mon, 15 Jul 2019 16:10:26 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Meta-Foo": [ + "bar" + ], + "X-Ms-Request-Id": [ + "47d5f542-d01e-004e-7159-5936aa000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "92681aca7bed74d4", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-dest-exists", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "10" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "oPqafXJA1cXuvXCJlDDFlw==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "Y2xvYmJlciBtZQ==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "oPqafXJA1cXuvXCJlDDFlw==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4B1FE0F\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "Y9mFmC2gxu4=" + ], + "X-Ms-Request-Id": [ + "47d5f548-d01e-004e-7659-5936aa000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "7476d61943289e82", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-dest", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-src" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4B77B87\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "e437369d-5f58-4180-abbe-0ca024fb430b" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "47d5f556-d01e-004e-0359-5936aa000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "c9ce25461774a3b8", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-dest", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "sQqNsWTgdUEFt6mb5y4/5Q==" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4B77B87\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "X-Ms-Copy-Id": [ + "e437369d-5f58-4180-abbe-0ca024fb430b" + ], + "X-Ms-Copy-Progress": [ + "11/11" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-src" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Mon, 15 Jul 2019 16:10:27 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Meta-Foo": [ + "bar" + ], + "X-Ms-Request-Id": [ + "47d5f563-d01e-004e-0f59-5936aa000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "SGVsbG8gV29ybGQ=" + } + }, + { + "ID": "0da5cf2b94221cd2", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-dest", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "sQqNsWTgdUEFt6mb5y4/5Q==" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4B77B87\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "X-Ms-Copy-Id": [ + "e437369d-5f58-4180-abbe-0ca024fb430b" + ], + "X-Ms-Copy-Progress": [ + "11/11" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-src" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Mon, 15 Jul 2019 16:10:27 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Meta-Foo": [ + "bar" + ], + "X-Ms-Request-Id": [ + "47d5f56a-d01e-004e-1659-5936aa000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "3c60641b36f7af56", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-dest-exists", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-src" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4C29D78\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "9293ce53-a728-4ab7-9f32-ad32faf2d398" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "47d5f575-d01e-004e-2159-5936aa000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "5d8bc5c645d4c114", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-dest-exists", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "sQqNsWTgdUEFt6mb5y4/5Q==" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4C29D78\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "X-Ms-Copy-Id": [ + "9293ce53-a728-4ab7-9f32-ad32faf2d398" + ], + "X-Ms-Copy-Progress": [ + "11/11" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-src" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Mon, 15 Jul 2019 16:10:27 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Meta-Foo": [ + "bar" + ], + "X-Ms-Request-Id": [ + "47d5f58a-d01e-004e-3559-5936aa000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "SGVsbG8gV29ybGQ=" + } + }, + { + "ID": "702a5e60fd35c8c5", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-dest-exists", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "sQqNsWTgdUEFt6mb5y4/5Q==" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4C29D78\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "X-Ms-Copy-Id": [ + "9293ce53-a728-4ab7-9f32-ad32faf2d398" + ], + "X-Ms-Copy-Progress": [ + "11/11" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-copying-src" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Mon, 15 Jul 2019 16:10:27 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Meta-Foo": [ + "bar" + ], + "X-Ms-Request-Id": [ + "47d5f591-d01e-004e-3c59-5936aa000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestDelete/NonExistentFails.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestDelete/NonExistentFails.replay new file mode 100644 index 000000000..52563b941 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestDelete/NonExistentFails.replay @@ -0,0 +1,103 @@ +{ + "Initial": "AQAAAA7dVMCkEG+1GAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "d588121abef3d1b8", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/does-not-exist", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "fcf22d3f-901e-0002-5259-59a69a000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOmZjZjIyZDNmLTkwMWUtMDAwMi01MjU5LTU5YTY5YTAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDc6MDAuMzUxMTg4N1o8L01lc3NhZ2U+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestDelete/Works.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestDelete/Works.replay new file mode 100644 index 000000000..02671be06 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestDelete/Works.replay @@ -0,0 +1,307 @@ +{ + "Initial": "AQAAAA7dVMCkFXB3sQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "85f0eeebf2720b02", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-deleting", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "PiWWCnnbxptnTNTsZ6csYg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "SGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "PiWWCnnbxptnTNTsZ6csYg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4E1929E\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:07:00 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "2yoxP9BZ4jg=" + ], + "X-Ms-Request-Id": [ + "d0fa6d4d-301e-001b-6959-592621000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "a4e23bb89bbdc031", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-deleting", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "d0fa6d54-301e-001b-7059-592621000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "84cf6fe201e4935a", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-deleting", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "d0fa6d60-301e-001b-7b59-592621000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOmQwZmE2ZDYwLTMwMWUtMDAxYi03YjU5LTU5MjYyMTAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDc6MDAuNDcyMTI3N1o8L01lc3NhZ2U+PC9FcnJvcj4=" + } + }, + { + "ID": "754a67873654dd01", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-deleting", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "d0fa6d64-301e-001b-7f59-592621000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOmQwZmE2ZDY0LTMwMWUtMDAxYi03ZjU5LTU5MjYyMTAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDc6MDAuNDkxMTE2OFo8L01lc3NhZ2U+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestDirsWithCharactersBeforeDelimiter.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestDirsWithCharactersBeforeDelimiter.replay new file mode 100644 index 000000000..6baf06352 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestDirsWithCharactersBeforeDelimiter.replay @@ -0,0 +1,1228 @@ +{ + "Initial": "AQAAAA7dVMB1FLqo7gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "abd22e504b0fd97c", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db1c7-801e-0043-1059-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyQTlDQ0JGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxL3Rlc3RGaWxlMWRpcjE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VHVlLCAwOCBGZWIgMjAyMiAyMzo1MToxMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VHVlLCAwOCBGZWIgMjAyMiAyMzo1MToxMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDlFQjVERTI5Rjk1MDc8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvdGVzdEZpbGUxZGlyMjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEOUVCNURFMkE1MTI3ODwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC0vdDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UaHUsIDEyIE9jdCAyMDIzIDE3OjQyOjA1IEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEQkNCNEE4RDMxMzE3RDwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC90L3Q8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VHVlLCAwOCBGZWIgMjAyMiAyMzo1MToxMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VHVlLCAwOCBGZWIgMjAyMiAyMzo1MToxMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDlFQjVERTI5NDczMEM8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMTwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEOUVCNURFMjkwMDZERjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "583c2eaa4d2a0cb8", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-dirs-with-chars-before-delimiter%2Ft-%2Ft.", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Etag": [ + "\"0x8DC277098E2551A\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "573db1d1-801e-0043-1759-59fe7e000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "43851d7608e91a18", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=10\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db1d5-801e-0043-1b59-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWF4UmVzdWx0cz4xMDwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEOUVCNURFMkE5Q0NCRjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvPC9OYW1lPjwvQmxvYlByZWZpeD48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvPC9OYW1lPjwvQmxvYlByZWZpeD48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VHVlLCAwOCBGZWIgMjAyMiAyMzo1MToxMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VHVlLCAwOCBGZWIgMjAyMiAyMzo1MToxMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDlFQjVERTI5MDA2REY8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "6b2b142871f46d54", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=9\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db1df-801e-0043-2459-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWF4UmVzdWx0cz45PC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyQTlDQ0JGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMTwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEOUVCNURFMjkwMDZERjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "b89dfc8addcf9b05", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=8\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db1ea-801e-0043-2d59-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWF4UmVzdWx0cz44PC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyQTlDQ0JGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMTwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEOUVCNURFMjkwMDZERjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "38eb44572e16b462", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=7\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db1f8-801e-0043-3a59-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWF4UmVzdWx0cz43PC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyQTlDQ0JGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMTwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEOUVCNURFMjkwMDZERjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "d092bb8a00744621", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=6\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db1ff-801e-0043-4159-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWF4UmVzdWx0cz42PC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyQTlDQ0JGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMTwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEOUVCNURFMjkwMDZERjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "a699936fe4fdfbf5", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=5\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db209-801e-0043-4b59-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWF4UmVzdWx0cz41PC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyQTlDQ0JGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L05hbWU+PC9CbG9iUHJlZml4PjwvQmxvYnM+PE5leHRNYXJrZXI+MiExMjghTURBd01EVXhJV0pzYjJJdFptOXlMV1JwY25NdGQybDBhQzFqYUdGeWN5MWlaV1p2Y21VdFpHVnNhVzFwZEdWeUwzUmxjM1JHYVd4bE1TRXdNREF3TWpnaE9UazVPUzB4TWkwek1WUXlNem8xT1RvMU9TNDVPVGs1T1RrNVdpRS08L05leHRNYXJrZXI+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "a47586c7663543df", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%21128%21MDAwMDUxIWJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMSEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=5\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db20f-801e-0043-5159-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWFya2VyPjIhMTI4IU1EQXdNRFV4SVdKc2IySXRabTl5TFdScGNuTXRkMmwwYUMxamFHRnljeTFpWldadmNtVXRaR1ZzYVcxcGRHVnlMM1JsYzNSR2FXeGxNU0V3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9NYXJrZXI+PE1heFJlc3VsdHM+NTwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyOTAwNkRGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "49fefdaf7b109090", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=4\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db216-801e-0043-5859-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWF4UmVzdWx0cz40PC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyQTlDQ0JGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvTmFtZT48L0Jsb2JQcmVmaXg+PC9CbG9icz48TmV4dE1hcmtlcj4yITEyNCFNREF3TURRM0lXSnNiMkl0Wm05eUxXUnBjbk10ZDJsMGFDMWphR0Z5Y3kxaVpXWnZjbVV0WkdWc2FXMXBkR1Z5TDNRdmRDOTBJVEF3TURBeU9DRTVPVGs1TFRFeUxUTXhWREl6T2pVNU9qVTVMams1T1RrNU9UbGFJUS0tPC9OZXh0TWFya2VyPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "8f6c50104f418ba0", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%21124%21MDAwMDQ3IWJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvdC90ITAwMDAyOCE5OTk5LTEyLTMxVDIzOjU5OjU5Ljk5OTk5OTlaIQ--\u0026maxresults=4\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db21f-801e-0043-6159-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWFya2VyPjIhMTI0IU1EQXdNRFEzSVdKc2IySXRabTl5TFdScGNuTXRkMmwwYUMxamFHRnljeTFpWldadmNtVXRaR1ZzYVcxcGRHVnlMM1F2ZEM5MElUQXdNREF5T0NFNU9UazVMVEV5TFRNeFZESXpPalU1T2pVNUxqazVPVGs1T1RsYUlRLS08L01hcmtlcj48TWF4UmVzdWx0cz40PC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyOTAwNkRGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "76b659999ddc706c", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=3\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db224-801e-0043-6659-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWF4UmVzdWx0cz4zPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyQTlDQ0JGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L05hbWU+PC9CbG9iUHJlZml4PjwvQmxvYnM+PE5leHRNYXJrZXI+MiExMjAhTURBd01EUTJJV0pzYjJJdFptOXlMV1JwY25NdGQybDBhQzFqYUdGeWN5MWlaV1p2Y21VdFpHVnNhVzFwZEdWeUwzUXRMM1FoTURBd01ESTRJVGs1T1RrdE1USXRNekZVTWpNNk5UazZOVGt1T1RrNU9UazVPVm9oPC9OZXh0TWFya2VyPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "92dc6fbe0d63fc53", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%21120%21MDAwMDQ2IWJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtL3QhMDAwMDI4ITk5OTktMTItMzFUMjM6NTk6NTkuOTk5OTk5OVoh\u0026maxresults=3\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db22b-801e-0043-6d59-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWFya2VyPjIhMTIwIU1EQXdNRFEySVdKc2IySXRabTl5TFdScGNuTXRkMmwwYUMxamFHRnljeTFpWldadmNtVXRaR1ZzYVcxcGRHVnlMM1F0TDNRaE1EQXdNREk0SVRrNU9Ua3RNVEl0TXpGVU1qTTZOVGs2TlRrdU9UazVPVGs1T1ZvaDwvTWFya2VyPjxNYXhSZXN1bHRzPjM8L01heFJlc3VsdHM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMTwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UdWUsIDA4IEZlYiAyMDIyIDIzOjUxOjExIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEOUVCNURFMjkwMDZERjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "fa455440bfe94e25", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=2\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db233-801e-0043-7559-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWF4UmVzdWx0cz4yPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyQTlDQ0JGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvTmFtZT48L0Jsb2JQcmVmaXg+PC9CbG9icz48TmV4dE1hcmtlcj4yITE0MCFNREF3TURZd0lXSnNiMkl0Wm05eUxXUnBjbk10ZDJsMGFDMWphR0Z5Y3kxaVpXWnZjbVV0WkdWc2FXMXBkR1Z5TDJScGNqSXZkR1Z6ZEVacGJHVXhaR2x5TWlFd01EQXdNamdoT1RrNU9TMHhNaTB6TVZReU16bzFPVG8xT1M0NU9UazVPVGs1V2lFLTwvTmV4dE1hcmtlcj48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "1e232989bf24e00e", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%21140%21MDAwMDYwIWJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvdGVzdEZpbGUxZGlyMiEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=2\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db239-801e-0043-7b59-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWFya2VyPjIhMTQwIU1EQXdNRFl3SVdKc2IySXRabTl5TFdScGNuTXRkMmwwYUMxamFHRnljeTFpWldadmNtVXRaR1ZzYVcxcGRHVnlMMlJwY2pJdmRHVnpkRVpwYkdVeFpHbHlNaUV3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9NYXJrZXI+PE1heFJlc3VsdHM+MjwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48QmxvYnM+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvTmFtZT48L0Jsb2JQcmVmaXg+PC9CbG9icz48TmV4dE1hcmtlcj4yITEyNCFNREF3TURRM0lXSnNiMkl0Wm05eUxXUnBjbk10ZDJsMGFDMWphR0Z5Y3kxaVpXWnZjbVV0WkdWc2FXMXBkR1Z5TDNRdmRDOTBJVEF3TURBeU9DRTVPVGs1TFRFeUxUTXhWREl6T2pVNU9qVTVMams1T1RrNU9UbGFJUS0tPC9OZXh0TWFya2VyPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "85b66a06606cf32a", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%21124%21MDAwMDQ3IWJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvdC90ITAwMDAyOCE5OTk5LTEyLTMxVDIzOjU5OjU5Ljk5OTk5OTlaIQ--\u0026maxresults=2\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db240-801e-0043-0159-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWFya2VyPjIhMTI0IU1EQXdNRFEzSVdKc2IySXRabTl5TFdScGNuTXRkMmwwYUMxamFHRnljeTFpWldadmNtVXRaR1ZzYVcxcGRHVnlMM1F2ZEM5MElUQXdNREF5T0NFNU9UazVMVEV5TFRNeFZESXpPalU1T2pVNUxqazVPVGs1T1RsYUlRLS08L01hcmtlcj48TWF4UmVzdWx0cz4yPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyOTAwNkRGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "adf77f8fbb309f0b", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db243-801e-0043-0459-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWF4UmVzdWx0cz4xPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyQTlDQ0JGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyPjIhMTQwIU1EQXdNRFl3SVdKc2IySXRabTl5TFdScGNuTXRkMmwwYUMxamFHRnljeTFpWldadmNtVXRaR1ZzYVcxcGRHVnlMMlJwY2pFdmRHVnpkRVpwYkdVeFpHbHlNU0V3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9OZXh0TWFya2VyPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "babae1bbd2786a83", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%21140%21MDAwMDYwIWJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjEvdGVzdEZpbGUxZGlyMSEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db245-801e-0043-0659-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWFya2VyPjIhMTQwIU1EQXdNRFl3SVdKc2IySXRabTl5TFdScGNuTXRkMmwwYUMxamFHRnljeTFpWldadmNtVXRaR1ZzYVcxcGRHVnlMMlJwY2pFdmRHVnpkRVpwYkdVeFpHbHlNU0V3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9NYXJrZXI+PE1heFJlc3VsdHM+MTwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48QmxvYnM+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS88L05hbWU+PC9CbG9iUHJlZml4PjwvQmxvYnM+PE5leHRNYXJrZXI+MiExNDAhTURBd01EWXdJV0pzYjJJdFptOXlMV1JwY25NdGQybDBhQzFqYUdGeWN5MWlaV1p2Y21VdFpHVnNhVzFwZEdWeUwyUnBjakl2ZEdWemRFWnBiR1V4WkdseU1pRXdNREF3TWpnaE9UazVPUzB4TWkwek1WUXlNem8xT1RvMU9TNDVPVGs1T1RrNVdpRS08L05leHRNYXJrZXI+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "8ce1599d1635af39", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%21140%21MDAwMDYwIWJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvdGVzdEZpbGUxZGlyMiEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db24c-801e-0043-0c59-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWFya2VyPjIhMTQwIU1EQXdNRFl3SVdKc2IySXRabTl5TFdScGNuTXRkMmwwYUMxamFHRnljeTFpWldadmNtVXRaR1ZzYVcxcGRHVnlMMlJwY2pJdmRHVnpkRVpwYkdVeFpHbHlNaUV3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9NYXJrZXI+PE1heFJlc3VsdHM+MTwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48QmxvYnM+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L05hbWU+PC9CbG9iUHJlZml4PjwvQmxvYnM+PE5leHRNYXJrZXI+MiExMjAhTURBd01EUTJJV0pzYjJJdFptOXlMV1JwY25NdGQybDBhQzFqYUdGeWN5MWlaV1p2Y21VdFpHVnNhVzFwZEdWeUwzUXRMM1FoTURBd01ESTRJVGs1T1RrdE1USXRNekZVTWpNNk5UazZOVGt1T1RrNU9UazVPVm9oPC9OZXh0TWFya2VyPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "6c94f3791976cd05", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%21120%21MDAwMDQ2IWJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtL3QhMDAwMDI4ITk5OTktMTItMzFUMjM6NTk6NTkuOTk5OTk5OVoh\u0026maxresults=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db250-801e-0043-1059-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWFya2VyPjIhMTIwIU1EQXdNRFEySVdKc2IySXRabTl5TFdScGNuTXRkMmwwYUMxamFHRnljeTFpWldadmNtVXRaR1ZzYVcxcGRHVnlMM1F0TDNRaE1EQXdNREk0SVRrNU9Ua3RNVEl0TXpGVU1qTTZOVGs2TlRrdU9UazVPVGs1T1ZvaDwvTWFya2VyPjxNYXhSZXN1bHRzPjE8L01heFJlc3VsdHM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvTmFtZT48L0Jsb2JQcmVmaXg+PC9CbG9icz48TmV4dE1hcmtlcj4yITEyNCFNREF3TURRM0lXSnNiMkl0Wm05eUxXUnBjbk10ZDJsMGFDMWphR0Z5Y3kxaVpXWnZjbVV0WkdWc2FXMXBkR1Z5TDNRdmRDOTBJVEF3TURBeU9DRTVPVGs1TFRFeUxUTXhWREl6T2pVNU9qVTVMams1T1RrNU9UbGFJUS0tPC9OZXh0TWFya2VyPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "c7727fbf1ee76c46", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%21124%21MDAwMDQ3IWJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvdC90ITAwMDAyOCE5OTk5LTEyLTMxVDIzOjU5OjU5Ljk5OTk5OTlaIQ--\u0026maxresults=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db255-801e-0043-1559-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWFya2VyPjIhMTI0IU1EQXdNRFEzSVdKc2IySXRabTl5TFdScGNuTXRkMmwwYUMxamFHRnljeTFpWldadmNtVXRaR1ZzYVcxcGRHVnlMM1F2ZEM5MElUQXdNREF5T0NFNU9UazVMVEV5TFRNeFZESXpPalU1T2pVNUxqazVPVGs1T1RsYUlRLS08L01hcmtlcj48TWF4UmVzdWx0cz4xPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LzwvTmFtZT48L0Jsb2JQcmVmaXg+PC9CbG9icz48TmV4dE1hcmtlcj4yITEyOCFNREF3TURVeElXSnNiMkl0Wm05eUxXUnBjbk10ZDJsMGFDMWphR0Z5Y3kxaVpXWnZjbVV0WkdWc2FXMXBkR1Z5TDNSbGMzUkdhV3hsTVNFd01EQXdNamdoT1RrNU9TMHhNaTB6TVZReU16bzFPVG8xT1M0NU9UazVPVGs1V2lFLTwvTmV4dE1hcmtlcj48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "5279852eaab7c436", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%21128%21MDAwMDUxIWJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMSEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "573db25d-801e-0043-1d59-59fe7e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci88L1ByZWZpeD48TWFya2VyPjIhMTI4IU1EQXdNRFV4SVdKc2IySXRabTl5TFdScGNuTXRkMmwwYUMxamFHRnljeTFpWldadmNtVXRaR1ZzYVcxcGRHVnlMM1JsYzNSR2FXeGxNU0V3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9NYXJrZXI+PE1heFJlc3VsdHM+MTwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlR1ZSwgMDggRmViIDIwMjIgMjM6NTE6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ5RUI1REUyOTAwNkRGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-1.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-1.replay new file mode 100644 index 000000000..f9b757dd5 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-1.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK+Le0BggAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "61ba13c2677736b3", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8BD2746\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "6c61dd95-601e-0074-6829-982cd2000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "ef672aa6a71993e9", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8BD2746\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6c61dd9d-601e-0074-6f29-982cd2000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "acc854af83c13bae", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8BD2746\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6c61dda6-601e-0074-7629-982cd2000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "2a941d2d12a1efb8", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8BD2746\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6c61ddad-601e-0074-7d29-982cd2000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "db6885931c2c7be7", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8C9F6A8\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "7f4ec50b-d0da-4e2a-b9b8-a397a40d051a" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "6c61ddb4-601e-0074-0429-982cd2000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "7743af85aa1de79b", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8C9F6A8\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Copy-Id": [ + "7f4ec50b-d0da-4e2a-b9b8-a397a40d051a" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6c61ddbb-601e-0074-0b29-982cd2000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "7f0583082beeb762", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "6c61ddc2-601e-0074-1229-982cd2000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "8d4de367bfdb19ed", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "6c61ddce-601e-0074-1e29-982cd2000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-2.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-2.replay new file mode 100644 index 000000000..5bd1fdbb7 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-2.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK/AFHY1wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "2b4f37be6f1940b6", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8E124D3\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "740677e3-401e-0063-6d29-9885d9000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "d10207c381b3880a", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8E124D3\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "740677e8-401e-0063-7029-9885d9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "d0faf17042ed7c69", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8E124D3\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "740677f0-401e-0063-7629-9885d9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "02e95e17066eb832", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8E124D3\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "740677f2-401e-0063-7829-9885d9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "940466b3f8c6f7c4", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8EDA622\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "67074147-f6b1-4cad-9577-e1439e7e9fec" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "740677f5-401e-0063-7b29-9885d9000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "2fb7eca5ca842c5e", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8EDA622\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Copy-Id": [ + "67074147-f6b1-4cad-9577-e1439e7e9fec" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "740677f6-401e-0063-7c29-9885d9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "4bcbab2e82433776", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "740677f9-401e-0063-7f29-9885d9000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "fea9587df001c642", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "740677ff-401e-0063-0429-9885d9000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-3.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-3.replay new file mode 100644 index 000000000..c4a395e8b --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-3.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK/Deb0YQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "52de825322dae101", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%20%21__0x22____0x23__$__0x25__\u0026%27%28%29%2A+%2C-.__0x2f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E902FFCB\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "d6807b13-f01e-0082-1729-98599c000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "8fbbd75ff8db2119", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%20%21__0x22____0x23__$__0x25__\u0026%27%28%29%2A+%2C-.__0x2f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E902FFCB\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "d6807b17-f01e-0082-1a29-98599c000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6001cb81b48014cc", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%20%21__0x22____0x23__$__0x25__\u0026%27%28%29%2A+%2C-.__0x2f__", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E902FFCB\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "d6807b1e-f01e-0082-2029-98599c000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "f3411d7c1610a71e", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%20%21__0x22____0x23__$__0x25__\u0026%27%28%29%2A+%2C-.__0x2f__?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E902FFCB\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "d6807b21-f01e-0082-2329-98599c000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "bcc7355a4bd9a27d", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%20%21__0x22____0x23__$__0x25__\u0026%27%28%29%2A+%2C-.%2F-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%20%21__0x22____0x23__$__0x25__\u0026%27%28%29%2A+%2C-.__0x2f__" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E90E96E0\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "5e829744-6791-4503-ba41-5aa125db0c8e" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "d6807b24-f01e-0082-2529-98599c000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "7b51c167feb3e280", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%20%21__0x22____0x23__$__0x25__\u0026%27%28%29%2A+%2C-.%2F-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E90E96E0\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Copy-Id": [ + "5e829744-6791-4503-ba41-5aa125db0c8e" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%20%21__0x22____0x23__$__0x25__\u0026%27%28%29%2A+%2C-.__0x2f__" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "d6807b2c-f01e-0082-2d29-98599c000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "85939eda7410fc68", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%20%21__0x22____0x23__$__0x25__\u0026%27%28%29%2A+%2C-.%2F-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "d6807b2f-f01e-0082-3029-98599c000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "de565421c9efe4fb", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%20%21__0x22____0x23__$__0x25__\u0026%27%28%29%2A+%2C-.__0x2f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "d6807b31-f01e-0082-3229-98599c000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-4.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-4.replay new file mode 100644 index 000000000..8ae93d122 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-4.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK9AyqergAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "1a5c3464d714cc70", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys:%3B%3C=%3E__0x3f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E7B700B2\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "ba5ef0cd-b01e-0005-5b29-98caf9000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "5d39cdd9574a9e80", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys:%3B%3C=%3E__0x3f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E7B700B2\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "ba5ef0d1-b01e-0005-5e29-98caf9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "78ca74066af6dd20", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys:%3B%3C=%3E__0x3f__", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E7B700B2\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "ba5ef0d6-b01e-0005-6229-98caf9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "3b9c3b4dc140b394", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys:%3B%3C=%3E__0x3f__?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E7B700B2\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "ba5ef0d8-b01e-0005-6429-98caf9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "dafb250106d39988", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys:%3B%3C=%3E__0x3f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys:%3B%3C=%3E__0x3f__" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E7C2E5E4\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "3f832248-e13f-416c-8109-f6c0c8c582ab" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "ba5ef0df-b01e-0005-6b29-98caf9000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "bd86008479a452a0", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys:%3B%3C=%3E__0x3f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E7C2E5E4\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Copy-Id": [ + "3f832248-e13f-416c-8109-f6c0c8c582ab" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys:%3B%3C=%3E__0x3f__" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "ba5ef0e5-b01e-0005-7129-98caf9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "e085ce9795d54f72", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys:%3B%3C=%3E__0x3f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "ba5ef0e9-b01e-0005-7529-98caf9000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "a3b32274b10d90f2", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys:%3B%3C=%3E__0x3f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "ba5ef0ee-b01e-0005-7a29-98caf9000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-5.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-5.replay new file mode 100644 index 000000000..54dc568c2 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-5.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK7N03TdwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "01a9919ee9741fc4", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys@", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E70B9730\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "0f79a716-f01e-0004-3e29-989525000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "f6df458c8d4fbd04", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys@", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E70B9730\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "0f79a720-f01e-0004-4529-989525000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "4a96b8215b43f286", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys@", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E70B9730\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "0f79a72a-f01e-0004-4d29-989525000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "c30d2ad65f428153", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys@?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E70B9730\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "0f79a734-f01e-0004-5729-989525000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "8156d280ab351949", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys@-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys@" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E71977EA\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "56237f37-e9f3-4184-b86f-ec6b498d0268" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "0f79a73e-f01e-0004-6029-989525000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "036084c3f67a5604", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys@-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E71977EA\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Copy-Id": [ + "56237f37-e9f3-4184-b86f-ec6b498d0268" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys@" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "0f79a742-f01e-0004-6429-989525000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "4ea336b86084db14", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys@-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "0f79a744-f01e-0004-6629-989525000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "8337c1841ba8e984", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys@", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "0f79a74f-f01e-0004-6f29-989525000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-6.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-6.replay new file mode 100644 index 000000000..6ed18c366 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-6.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK8ChDYvAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "685c13bd8e74b4e9", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%5B__0x5c__%5D%5E_", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E72FBBCA\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "6c432ce8-d01e-0071-6a29-98fe09000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "33a28e8eb03d4d1c", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%5B__0x5c__%5D%5E_", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E72FBBCA\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6c432cf3-d01e-0071-7129-98fe09000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "2fbc2e0b7ca6dbbc", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%5B__0x5c__%5D%5E_", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E72FBBCA\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6c432cf7-d01e-0071-7429-98fe09000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "c0e3bfabd2b3a9bf", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%5B__0x5c__%5D%5E_?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E72FBBCA\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6c432cfa-d01e-0071-7729-98fe09000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "c1b2e5fb4aaf8feb", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%5B__0x5c__%5D%5E_-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%5B__0x5c__%5D%5E_" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E73C6423\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "28b8d42c-ff7e-49ce-9dd8-eb0bc99d21e0" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "6c432cfd-d01e-0071-7a29-98fe09000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "4aaad6e1d721d0ad", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%5B__0x5c__%5D%5E_-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E73C6423\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Copy-Id": [ + "28b8d42c-ff7e-49ce-9dd8-eb0bc99d21e0" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%5B__0x5c__%5D%5E_" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6c432d02-d01e-0071-7f29-98fe09000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "4e08f77f3bf5a763", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%5B__0x5c__%5D%5E_-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "6c432d05-d01e-0071-0229-98fe09000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "34a29b8dec7c1cb1", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%5B__0x5c__%5D%5E_", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "6c432d06-d01e-0071-0329-98fe09000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-7.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-7.replay new file mode 100644 index 000000000..00c9b9bcb --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-7.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK/GnzE5wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "afdaa3570249e3d9", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%60", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E923A282\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "9c760ce9-601e-0016-2429-98eef5000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "ae4fcaedab32d480", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%60", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E923A282\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9c760cf8-601e-0016-3129-98eef5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "9aee9a0a8c7d964e", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%60", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E923A282\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9c760d02-601e-0016-3929-98eef5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "2e8a45dd4b660350", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%60?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E923A282\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9c760d09-601e-0016-4029-98eef5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "12714614d8bd260a", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%60-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%60" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E92FFCBE\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "8ed18886-1a28-459b-bc42-2e87622f5a71" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "9c760d0f-601e-0016-4629-98eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "18bbb7e9557dbeca", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%60-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E92FFCBE\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Copy-Id": [ + "8ed18886-1a28-459b-bc42-2e87622f5a71" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%60" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:35 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9c760d15-601e-0016-4c29-98eef5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "af37c679f2becda8", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%60-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "9c760d1c-601e-0016-5329-98eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "1f01b986b86128b0", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%60", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "9c760d24-601e-0016-5929-98eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-8.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-8.replay new file mode 100644 index 000000000..d7aca094f --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/ascii-8.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK+E9kiZAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "404163511f6d897e", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%7B%7C%7D~__0x7f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8792337\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "2ca324c6-b01e-0015-0f29-980f91000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "afa37dd93a4164ae", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%7B%7C%7D~__0x7f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8792337\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "2ca324c9-b01e-0015-1129-980f91000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "e6d6f03f05bc503a", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%7B%7C%7D~__0x7f__", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8792337\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "2ca324cd-b01e-0015-1429-980f91000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "c98b25f7cad42d4e", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%7B%7C%7D~__0x7f__?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8792337\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "2ca324ce-b01e-0015-1529-980f91000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "936dfbda8f35faee", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%7B%7C%7D~__0x7f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%7B%7C%7D~__0x7f__" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E884E156\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "f0b039da-3ed1-4fea-b590-a6e87b9513ee" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "2ca324d0-b01e-0015-1729-980f91000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "08ef887fe3c92045", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%7B%7C%7D~__0x7f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E884E156\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Copy-Id": [ + "f0b039da-3ed1-4fea-b590-a6e87b9513ee" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%7B%7C%7D~__0x7f__" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "2ca324d9-b01e-0015-1f29-980f91000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "1e665070e1f6d9f4", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%7B%7C%7D~__0x7f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "2ca324e4-b01e-0015-2929-980f91000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "57f75b4966a18237", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%7B%7C%7D~__0x7f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "2ca324ea-b01e-0015-2d29-980f91000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/backslashes.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/backslashes.replay new file mode 100644 index 000000000..987d9a1ac --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/backslashes.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK9M7fq/gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "41a16099906d40bc", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x5c__bar__0x5c__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E83371B4\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "bbb6b2c6-201e-005a-2729-987ec5000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "3523502640c915e5", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x5c__bar__0x5c__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E83371B4\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "bbb6b2d1-201e-005a-3129-987ec5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "667ccf2d21dcced5", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x5c__bar__0x5c__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E83371B4\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "bbb6b2df-201e-005a-3d29-987ec5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "5c1d693f3a2b1a08", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x5c__bar__0x5c__baz?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E83371B4\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "bbb6b2ef-201e-005a-4b29-987ec5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "fe074b6727e3a613", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x5c__bar__0x5c__baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x5c__bar__0x5c__baz" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E8408F33\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "daff5004-b053-46a9-aabe-f081b354c083" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "bbb6b2f2-201e-005a-4e29-987ec5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "32d04d999ccd9891", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x5c__bar__0x5c__baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E8408F33\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Copy-Id": [ + "daff5004-b053-46a9-aabe-f081b354c083" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x5c__bar__0x5c__baz" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "bbb6b2fc-201e-005a-5829-987ec5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "96622a19a902ea21", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x5c__bar__0x5c__baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "bbb6b309-201e-005a-6329-987ec5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "0b6870d0e241479e", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x5c__bar__0x5c__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "bbb6b318-201e-005a-7129-987ec5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/dotdotbackslash.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/dotdotbackslash.replay new file mode 100644 index 000000000..877618cb9 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/dotdotbackslash.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK7KFi4+gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "391b6b8c79543337", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c__..__0x5c__bar__0x5c__..__0x5c__..__0x5c__baz..__0x5c__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E6E835E0\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "9e227b9f-b01e-0077-5a29-98cdb6000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "e64f167b4d8eb047", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c__..__0x5c__bar__0x5c__..__0x5c__..__0x5c__baz..__0x5c__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E6E835E0\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9e227baa-b01e-0077-6429-98cdb6000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "46f25e32cdaf7b22", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c__..__0x5c__bar__0x5c__..__0x5c__..__0x5c__baz..__0x5c__", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E6E835E0\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9e227bb9-b01e-0077-7229-98cdb6000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "61f7038b9de1e396", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c__..__0x5c__bar__0x5c__..__0x5c__..__0x5c__baz..__0x5c__?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E6E835E0\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9e227bc0-b01e-0077-7829-98cdb6000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "88dc3bc81192a083", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c__..__0x5c__bar__0x5c__..__0x5c__..__0x5c__baz..__0x5c__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c__..__0x5c__bar__0x5c__..__0x5c__..__0x5c__baz..__0x5c__" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E6F50537\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "881a063d-e8ca-442c-a49d-5dd37ee9b1c3" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "9e227bca-b01e-0077-0229-98cdb6000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "8abd2362e663bbed", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c__..__0x5c__bar__0x5c__..__0x5c__..__0x5c__baz..__0x5c__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E6F50537\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "X-Ms-Copy-Id": [ + "881a063d-e8ca-442c-a49d-5dd37ee9b1c3" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c__..__0x5c__bar__0x5c__..__0x5c__..__0x5c__baz..__0x5c__" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9e227bd7-b01e-0077-0f29-98cdb6000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "ffdbf0cfdf18c62e", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c__..__0x5c__bar__0x5c__..__0x5c__..__0x5c__baz..__0x5c__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "9e227be2-b01e-0077-1a29-98cdb6000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "8b1fcd16445757b0", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c__..__0x5c__bar__0x5c__..__0x5c__..__0x5c__baz..__0x5c__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "9e227beb-b01e-0077-2329-98cdb6000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/dotdotslash.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/dotdotslash.replay new file mode 100644 index 000000000..72485a7f4 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/dotdotslash.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK9Jqg6XQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "262934c579e79f9b", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E81148B0\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "4a04ddc1-901e-0070-5429-98a1d5000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "9d96f1d4452d9f36", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E81148B0\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4a04ddc4-901e-0070-5629-98a1d5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "16809e2554eb4b6b", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E81148B0\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4a04ddc7-901e-0070-5829-98a1d5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "eff28e735e4aa3be", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E81148B0\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4a04ddc8-901e-0070-5929-98a1d5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "5fd0f7f52706bb36", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E81DF10C\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "4362fcc1-2cf0-47c6-98bd-a978ccdcf1e2" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "4a04ddca-901e-0070-5b29-98a1d5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "2e87c8babfd62fa8", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E81DF10C\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Copy-Id": [ + "4362fcc1-2cf0-47c6-98bd-a978ccdcf1e2" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4a04ddce-901e-0070-5f29-98a1d5000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "5497dae89a50c659", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "4a04ddd1-901e-0070-6129-98a1d5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "6d8241de6ce037fa", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "4a04ddd3-901e-0070-6329-98a1d5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/fwdslashes.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/fwdslashes.replay new file mode 100644 index 000000000..d65b99019 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/fwdslashes.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK9EGi/5AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "6935a675545a0f4e", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2Fbar%2Fbaz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7D8B49E\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "ec0fca3e-301e-0024-4d29-98ee82000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "7bc62ad882825ccf", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2Fbar%2Fbaz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7D8B49E\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "ec0fca4a-301e-0024-5729-98ee82000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "43bdbe9c2fb5be82", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2Fbar%2Fbaz", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7D8B49E\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "ec0fca53-301e-0024-5d29-98ee82000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "cf94e1549813710c", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2Fbar%2Fbaz?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7D8B49E\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "ec0fca59-301e-0024-6329-98ee82000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "a8c0cda285785fbc", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2Fbar%2Fbaz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2Fbar%2Fbaz" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7E50EEF\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "877e9715-266a-423e-95f1-0bc9f36ac26e" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "ec0fca60-301e-0024-6a29-98ee82000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "f555e67682957b60", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2Fbar%2Fbaz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7E50EEF\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Copy-Id": [ + "877e9715-266a-423e-95f1-0bc9f36ac26e" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2Fbar%2Fbaz" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "ec0fca68-301e-0024-7129-98ee82000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "628c36562a489e0e", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2Fbar%2Fbaz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "ec0fca6d-301e-0024-7629-98ee82000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "ece2b87ee3184c74", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2Fbar%2Fbaz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "ec0fca75-301e-0024-7e29-98ee82000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/non-UTF8_fails.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/non-UTF8_fails.replay new file mode 100644 index 000000000..1c8e00214 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/non-UTF8_fails.replay @@ -0,0 +1,44 @@ +{ + "Initial": "AQAAAA7dviK7HVicvwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/quote.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/quote.replay new file mode 100644 index 000000000..2caf66171 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/quote.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK8JH3r7QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "ec53a75d9cc0b744", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x22__bar__0x22__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7734AC4\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "9760ce18-701e-001a-6129-9879fd000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "4c0458e9d4a85d71", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x22__bar__0x22__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7734AC4\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9760ce25-701e-001a-6d29-9879fd000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "b762090197b20d99", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x22__bar__0x22__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7734AC4\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9760ce2c-701e-001a-7329-9879fd000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "a415a52f06d8e8a2", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x22__bar__0x22__baz?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7734AC4\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9760ce34-701e-001a-7a29-9879fd000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "55e3b42c23059d46", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x22__bar__0x22__baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x22__bar__0x22__baz" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E77F7DF3\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "7f12b301-b32d-4b4c-a3a6-b79501b24192" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "9760ce36-701e-001a-7c29-9879fd000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "42568ade31bdfc63", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x22__bar__0x22__baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E77F7DF3\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Copy-Id": [ + "7f12b301-b32d-4b4c-a3a6-b79501b24192" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x22__bar__0x22__baz" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "9760ce39-701e-001a-7f29-9879fd000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "53ee6f2d57f5e93c", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x22__bar__0x22__baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "9760ce3e-701e-001a-0329-9879fd000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "6077716e9b40a730", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo__0x22__bar__0x22__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "9760ce3f-701e-001a-0429-9879fd000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/repeatedbackslashes.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/repeatedbackslashes.replay new file mode 100644 index 000000000..7c9bc0f74 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/repeatedbackslashes.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK8F1g/5QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "0a55a460b7dbc0e7", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:31 GMT" + ], + "Etag": [ + "\"0x8DC6640E75196D1\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "6ddbd9ea-101e-0033-7d29-984789000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "4240b64f338790fc", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E75196D1\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6ddbd9f7-101e-0033-0929-984789000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "5900bdd0b16d716c", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E75196D1\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6ddbda09-101e-0033-1929-984789000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "7eb50a161cc45db0", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E75196D1\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6ddbda16-101e-0033-2529-984789000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "724b079ed9bf6bf0", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E75DCA01\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "3a9ddc1f-4663-4b87-ac6b-ef82d13461d2" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "6ddbda21-101e-0033-2f29-984789000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "f0d38aa4f6f99940", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E75DCA01\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Copy-Id": [ + "3a9ddc1f-4663-4b87-ac6b-ef82d13461d2" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "6ddbda2b-101e-0033-3929-984789000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "ccd71be54801833f", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "6ddbda35-101e-0033-4229-984789000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "361e1173752ec439", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys..__0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "6ddbda3f-101e-0033-4c29-984789000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/repeatedfwdslashes.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/repeatedfwdslashes.replay new file mode 100644 index 000000000..bc834d1f4 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/repeatedfwdslashes.replay @@ -0,0 +1,440 @@ +{ + "Initial": "AQAAAA7dviK9HbCbqAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "3dd8c4bb33030b3d", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2F%2Fbar%2F%2F%2Fbaz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E7F9F375\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "020288c9-701e-0078-4b29-98bbda000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "a5dc9264f49f690d", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2F%2Fbar%2F%2F%2Fbaz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E7F9F375\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "020288d6-701e-0078-5729-98bbda000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "b2338004d08aa3cc", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2F%2Fbar%2F%2F%2Fbaz", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E7F9F375\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "020288de-701e-0078-5e29-98bbda000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "ede57b4da6ba5137", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2F%2Fbar%2F%2F%2Fbaz?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Etag": [ + "\"0x8DC6640E7F9F375\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "020288e2-701e-0078-6229-98bbda000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "8a225195a4d93a34", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%2F%2Fbar%2F%2F%2Fbaz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:33 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "020288ea-701e-0078-6a29-98bbda000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/spaces.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/spaces.replay new file mode 100644 index 000000000..059f580e0 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/spaces.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK8Mav5UAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "59ad295a695ac478", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%20bar%20baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E79525BA\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "d5741280-401e-0011-4a29-988296000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "51bd12cba3c60ce2", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%20bar%20baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E79525BA\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "d574128a-401e-0011-5329-988296000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "d15939ceeb77808f", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%20bar%20baz", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E79525BA\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "d5741297-401e-0011-5e29-988296000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "9bddc491fecfd4b2", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%20bar%20baz?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E79525BA\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "d574129b-401e-0011-6229-988296000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "19c0631bc209a393", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%20bar%20baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%20bar%20baz" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7A15901\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "1bfc31e8-7ed0-4a0e-9e0d-aa491db16344" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "d57412a1-401e-0011-6829-988296000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "22e452e33b269f4b", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%20bar%20baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Etag": [ + "\"0x8DC6640E7A15901\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Copy-Id": [ + "1bfc31e8-7ed0-4a0e-9e0d-aa491db16344" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%20bar%20baz" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "d57412a8-401e-0011-6f29-988296000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "866637e5709dd7f4", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%20bar%20baz-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "d57412ab-401e-0011-7229-988296000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "daf3767c1048a8e4", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keysfoo%20bar%20baz", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:32 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "d57412b0-401e-0011-7729-988296000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/startwithdigit.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/startwithdigit.replay new file mode 100644 index 000000000..46a606d1e --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/startwithdigit.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK+ICt8wwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "b3af6de1a690ddfb", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys12345", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E899ECF1\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "a1537ce9-e01e-007a-0929-980562000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "83e6eea7aaa50a9b", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys12345", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E899ECF1\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "a1537cf4-e01e-007a-1129-980562000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "df1ba6a7c3b1f640", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys12345", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E899ECF1\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "a1537cff-e01e-007a-1929-980562000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "b85fde7b612f62ce", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys12345?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E899ECF1\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "a1537d09-e01e-007a-2129-980562000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "821eecd33a492ad0", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys12345-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys12345" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8A6E359\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "2aa08637-8b41-43b8-82ac-57119eb7deb9" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "a1537d10-e01e-007a-2829-980562000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "104663afddfcdd27", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys12345-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8A6E359\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Copy-Id": [ + "2aa08637-8b41-43b8-82ac-57119eb7deb9" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys12345" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "a1537d13-e01e-007a-2b29-980562000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "cb03b0aa3d2a025c", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys12345-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a1537d17-e01e-007a-2f29-980562000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "422e9afdc85cb27e", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys12345", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a1537d27-e01e-007a-3e29-980562000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/unicode.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/unicode.replay new file mode 100644 index 000000000..2e88e5108 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestKeys/unicode.replay @@ -0,0 +1,665 @@ +{ + "Initial": "AQAAAA7dviK+BlkmUgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "c138eeb26813a8a9", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E857964E\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "8ec6e0ae-501e-007f-6329-98d7b9000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "f720de97bb3573a5", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E857964E\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "8ec6e0b7-501e-007f-6a29-98d7b9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "92ae17927600edf9", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E857964E\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "8ec6e0c2-501e-007f-7229-98d7b9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "2e953a3440040352", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E857964E\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "8ec6e0cf-501e-007f-7f29-98d7b9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "5beceeaf2156ef54", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8643EBB\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Copy-Id": [ + "365cbb8b-b231-44ad-84d1-0673f7ecb0cc" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Request-Id": [ + "8ec6e0d7-501e-007f-0629-98d7b9000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "76f219e332d5e9c3", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Etag": [ + "\"0x8DC6640E8643EBB\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Copy-Completion-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Copy-Id": [ + "365cbb8b-b231-44ad-84d1-0673f7ecb0cc" + ], + "X-Ms-Copy-Progress": [ + "5/5" + ], + "X-Ms-Copy-Source": [ + "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Ms-Copy-Status": [ + "success" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "8ec6e0dd-501e-007f-0c29-98d7b9000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "07885b880e6d333d", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "8ec6e0df-501e-007f-0e29-98d7b9000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "5b2db57a5ae2901a", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:34 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "8ec6e0e0-501e-007f-0f29-98d7b9000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestList/PaginationConsistencyAfterDelete.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/PaginationConsistencyAfterDelete.replay new file mode 100644 index 000000000..76ef7a28b --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/PaginationConsistencyAfterDelete.replay @@ -0,0 +1,347 @@ +{ + "Initial": "AQAAAA7dVMB0ADiWHgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "b73a887ff6655376", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "1cae9ea2-f01e-0076-2f59-59926a000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWxpc3QtMjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VFRkUyMjMzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "b218c74286299203", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=2\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "1cae9ed0-f01e-0076-5a59-59926a000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MjwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXI+MiE4MCFNREF3TURFMUlXSnNiMkl0Wm05eUxXeHBjM1F0TWlFd01EQXdNamdoT1RrNU9TMHhNaTB6TVZReU16bzFPVG8xT1M0NU9UazVPVGs1V2lFLTwvTmV4dE1hcmtlcj48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "6f8bc6523bd34284", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-list-1", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "1cae9eea-f01e-0076-7459-59926a000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "bed47585da303715", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026marker=2%2180%21MDAwMDE1IWJsb2ItZm9yLWxpc3QtMiEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=1000\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "1cae9f04-f01e-0076-0e59-59926a000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1hcmtlcj4yITgwIU1EQXdNREUxSVdKc2IySXRabTl5TFd4cGMzUXRNaUV3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9NYXJrZXI+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0yPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGRTIyMzM5PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "bbb1177c7e1bc29d", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-list-1", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Etag": [ + "\"0x8DC2770981EFA84\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "1cae9f1a-f01e-0076-2259-59926a000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestList/PaginationConsistencyAfterInsert.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/PaginationConsistencyAfterInsert.replay new file mode 100644 index 000000000..deb90f08d --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/PaginationConsistencyAfterInsert.replay @@ -0,0 +1,347 @@ +{ + "Initial": "AQAAAA7dVMBzMJ5dNgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "310279ddbcc4ae5b", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "60e7fbb8-e01e-0018-1459-59c745000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWxpc3QtMjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VFRkUyMjMzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "39a332e5f87ac77f", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=2\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "60e7fbd0-e01e-0018-2a59-59c745000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MjwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXI+MiE4MCFNREF3TURFMUlXSnNiMkl0Wm05eUxXeHBjM1F0TWlFd01EQXdNamdoT1RrNU9TMHhNaTB6TVZReU16bzFPVG8xT1M0NU9UazVPVGs1V2lFLTwvTmV4dE1hcmtlcj48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "4f8ee09244edc66a", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-list-0a", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Etag": [ + "\"0x8DC277097FBE748\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "60e7fbe1-e01e-0018-3b59-59c745000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "e73a620e1027c172", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026marker=2%2180%21MDAwMDE1IWJsb2ItZm9yLWxpc3QtMiEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=1000\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "60e7fbf6-e01e-0018-5059-59c745000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1hcmtlcj4yITgwIU1EQXdNREUxSVdKc2IySXRabTl5TFd4cGMzUXRNaUV3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9NYXJrZXI+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0yPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGRTIyMzM5PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "8e652c811deb6965", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-list-0a", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "60e7fc03-e01e-0018-5d59-59c745000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestList/by_1.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/by_1.replay new file mode 100644 index 000000000..8d2b3b2e3 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/by_1.replay @@ -0,0 +1,253 @@ +{ + "Initial": "AQAAAA7dVMBzF4U6aQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "b429d851fd2f38dd", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "67f93feb-d01e-005e-7f59-59f3c2000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWxpc3QtMjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VFRkUyMjMzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "284538f23e55c9b2", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "67f93ff8-d01e-005e-0a59-59f3c2000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyPjIhODAhTURBd01ERTFJV0pzYjJJdFptOXlMV3hwYzNRdE1TRXdNREF3TWpnaE9UazVPUzB4TWkwek1WUXlNem8xT1RvMU9TNDVPVGs1T1RrNVdpRS08L05leHRNYXJrZXI+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "51ae847f57f0fcec", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026marker=2%2180%21MDAwMDE1IWJsb2ItZm9yLWxpc3QtMSEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=1\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "67f93ffe-d01e-005e-1059-59f3c2000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1hcmtlcj4yITgwIU1EQXdNREUxSVdKc2IySXRabTl5TFd4cGMzUXRNU0V3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9NYXJrZXI+PE1heFJlc3VsdHM+MTwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0xPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlRodSwgMTIgT2N0IDIwMjMgMTc6NDI6MDQgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlRodSwgMTIgT2N0IDIwMjMgMTc6NDI6MDQgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OERCQ0I0QThDNjk5MUMwPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyPjIhODAhTURBd01ERTFJV0pzYjJJdFptOXlMV3hwYzNRdE1pRXdNREF3TWpnaE9UazVPUzB4TWkwek1WUXlNem8xT1RvMU9TNDVPVGs1T1RrNVdpRS08L05leHRNYXJrZXI+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "1d878a3f394358a0", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026marker=2%2180%21MDAwMDE1IWJsb2ItZm9yLWxpc3QtMiEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=1\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "67f94003-d01e-005e-1559-59f3c2000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1hcmtlcj4yITgwIU1EQXdNREUxSVdKc2IySXRabTl5TFd4cGMzUXRNaUV3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9NYXJrZXI+PE1heFJlc3VsdHM+MTwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0yPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGRTIyMzM5PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestList/by_2.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/by_2.replay new file mode 100644 index 000000000..9f41d50b2 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/by_2.replay @@ -0,0 +1,201 @@ +{ + "Initial": "AQAAAA7dVMBzIMxpsAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "9744ebab281dd4d0", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:10 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "cded91f2-c01e-007d-0459-596901000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWxpc3QtMjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VFRkUyMjMzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "9f3d05764df001d3", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=2\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:10 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "cded9200-c01e-007d-1059-596901000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MjwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXI+MiE4MCFNREF3TURFMUlXSnNiMkl0Wm05eUxXeHBjM1F0TWlFd01EQXdNamdoT1RrNU9TMHhNaTB6TVZReU16bzFPVG8xT1M0NU9UazVPVGs1V2lFLTwvTmV4dE1hcmtlcj48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "de2a5068d8d21a47", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026marker=2%2180%21MDAwMDE1IWJsb2ItZm9yLWxpc3QtMiEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=2\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:10 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "cded9205-c01e-007d-1459-596901000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1hcmtlcj4yITgwIU1EQXdNREUxSVdKc2IySXRabTl5TFd4cGMzUXRNaUV3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9NYXJrZXI+PE1heFJlc3VsdHM+MjwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0yPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGRTIyMzM5PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestList/by_3.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/by_3.replay new file mode 100644 index 000000000..35f8094c1 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/by_3.replay @@ -0,0 +1,149 @@ +{ + "Initial": "AQAAAA7dVMBzKMlpcgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "06193ace60f00f34", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "e30724f2-401e-004c-5659-598812000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWxpc3QtMjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VFRkUyMjMzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "8b7f22df8b07dbaa", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=3\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "e3072506-401e-004c-6859-598812000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MzwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWxpc3QtMjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VFRkUyMjMzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestList/exactly_1_object_due_to_prefix.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/exactly_1_object_due_to_prefix.replay new file mode 100644 index 000000000..ee992fbaf --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/exactly_1_object_due_to_prefix.replay @@ -0,0 +1,149 @@ +{ + "Initial": "AQAAAA7dVMBzCJGs0gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "f806b29ef6245863", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:10 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "df359e9c-e01e-0037-5b59-59ca8e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWxpc3QtMjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VFRkUyMjMzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "f94523fe99dec916", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-list-1\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:10 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "df359ec9-e01e-0037-0359-59ca8e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0LTE8L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestList/no_objects.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/no_objects.replay new file mode 100644 index 000000000..0caf97b10 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/no_objects.replay @@ -0,0 +1,149 @@ +{ + "Initial": "AQAAAA7dVMBzASrIPwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "708ad659faf1b6b3", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:10 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "58b08e69-401e-0001-4959-5947fe000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWxpc3QtMjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VFRkUyMjMzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "780a8b440fe256c9", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=no-objects-with-this-prefix\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:10 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "58b08e81-401e-0001-5c59-5947fe000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5uby1vYmplY3RzLXdpdGgtdGhpcy1wcmVmaXg8L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxCbG9icyAvPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestList/no_pagination.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/no_pagination.replay new file mode 100644 index 000000000..067b8a017 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestList/no_pagination.replay @@ -0,0 +1,149 @@ +{ + "Initial": "AQAAAA7dVMBzD7tYAAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "d6b190ef8e2565e0", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:10 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "9cc5ef16-401e-003e-6d59-598f5d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWxpc3QtMjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VFRkUyMjMzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "489fe054a0121c8f", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-list\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:10 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "9cc5ef38-401e-003e-0c59-598f5d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1saXN0PC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbGlzdC0wPC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUVGREQ0MDU2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1saXN0LTE8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNCBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOEM2OTkxQzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWxpc3QtMjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VFRkUyMjMzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestListDelimiters/abc.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestListDelimiters/abc.replay new file mode 100644 index 000000000..427ef1966 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestListDelimiters/abc.replay @@ -0,0 +1,711 @@ +{ + "Initial": "AQAAAA7dVMB0OxI7mwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "fc7d85fbc7c28a8f", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-delimiters-abc\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6c5d4d6b-d01e-0013-3f59-593c2e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiYzwvUHJlZml4PjxNYXhSZXN1bHRzPjEwMDA8L01heFJlc3VsdHM+PEJsb2JzPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2EudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwRDAwOUZDPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNiLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMEQyQzk5RDwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjYy50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjBENTg5M0U8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2QudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwRDdEMzlBPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmNlLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UaHUsIDEyIE9jdCAyMDIzIDE3OjQyOjA1IEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UaHUsIDEyIE9jdCAyMDIzIDE3OjQyOjA1IEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEQkNCNEE4RDFERkE2MzwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMERDNDEzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "3e02c56c661e378a", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-delimiters-abc\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6c5d4d81-d01e-0013-5159-593c2e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiYzwvUHJlZml4PjxNYXhSZXN1bHRzPjEwMDA8L01heFJlc3VsdHM+PEJsb2JzPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2EudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwRDAwOUZDPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNiLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMEQyQzk5RDwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjYy50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjBENTg5M0U8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2QudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwRDdEMzlBPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmNlLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UaHUsIDEyIE9jdCAyMDIzIDE3OjQyOjA1IEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UaHUsIDEyIE9jdCAyMDIzIDE3OjQyOjA1IEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEQkNCNEE4RDFERkE2MzwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMERDNDEzOTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "82ff33753c78e9b9", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=abc\u0026maxresults=1000\u0026prefix=blob-for-delimiters-abc\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6c5d4d8c-d01e-0013-5859-593c2e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiYzwvUHJlZml4PjxNYXhSZXN1bHRzPjEwMDA8L01heFJlc3VsdHM+PERlbGltaXRlcj5hYmM8L0RlbGltaXRlcj48QmxvYnM+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjPC9OYW1lPjwvQmxvYlByZWZpeD48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmM8L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjBEQzQxMzk8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "48fb0d635b111669", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=abc\u0026maxresults=1000\u0026prefix=blob-for-delimiters-abcdir1abc\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6c5d4d8e-d01e-0013-5a59-593c2e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmM8L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+YWJjPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2EudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwRDAwOUZDPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNiLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMEQyQzk5RDwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjPC9OYW1lPjwvQmxvYlByZWZpeD48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "31191fcae59cb48e", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=abc\u0026maxresults=1000\u0026prefix=blob-for-delimiters-abcdir1abcsubdirabc\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6c5d4d98-d01e-0013-6259-593c2e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmM8L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+YWJjPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2MudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwRDU4OTNFPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNkLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMEQ3RDM5QTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "188a20602ca7250e", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=abc\u0026maxresults=1000\u0026prefix=blob-for-delimiters-abcdir2abc\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6c5d4d9c-d01e-0013-6659-593c2e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmM8L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+YWJjPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiY2UudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlRodSwgMTIgT2N0IDIwMjMgMTc6NDI6MDUgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlRodSwgMTIgT2N0IDIwMjMgMTc6NDI6MDUgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OERCQ0I0QThEMURGQTYzPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "825536a9a7773da2", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=abc\u0026maxresults=1\u0026prefix=blob-for-delimiters-abc\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6c5d4da0-d01e-0013-6a59-593c2e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiYzwvUHJlZml4PjxNYXhSZXN1bHRzPjE8L01heFJlc3VsdHM+PERlbGltaXRlcj5hYmM8L0RlbGltaXRlcj48QmxvYnM+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjPC9OYW1lPjwvQmxvYlByZWZpeD48L0Jsb2JzPjxOZXh0TWFya2VyPjIhMTA4IU1EQXdNRE0xSVdKc2IySXRabTl5TFdSbGJHbHRhWFJsY25NdFlXSmpaR2x5TW1GaVkyVXVkSGgwSVRBd01EQXlPQ0U1T1RrNUxURXlMVE14VkRJek9qVTVPalU1TGprNU9UazVPVGxhSVEtLTwvTmV4dE1hcmtlcj48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "263ddacf08470a85", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=abc\u0026marker=2%21108%21MDAwMDM1IWJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiY2UudHh0ITAwMDAyOCE5OTk5LTEyLTMxVDIzOjU5OjU5Ljk5OTk5OTlaIQ--\u0026maxresults=1\u0026prefix=blob-for-delimiters-abc\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6c5d4da5-d01e-0013-6f59-593c2e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiYzwvUHJlZml4PjxNYXJrZXI+MiExMDghTURBd01ETTFJV0pzYjJJdFptOXlMV1JsYkdsdGFYUmxjbk10WVdKalpHbHlNbUZpWTJVdWRIaDBJVEF3TURBeU9DRTVPVGs1TFRFeUxUTXhWREl6T2pVNU9qVTVMams1T1RrNU9UbGFJUS0tPC9NYXJrZXI+PE1heFJlc3VsdHM+MTwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPmFiYzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmM8L05hbWU+PC9CbG9iUHJlZml4PjwvQmxvYnM+PE5leHRNYXJrZXI+MiE5NiFNREF3TURJNElXSnNiMkl0Wm05eUxXUmxiR2x0YVhSbGNuTXRZV0pqWmk1MGVIUWhNREF3TURJNElUazVPVGt0TVRJdE16RlVNak02TlRrNk5Ua3VPVGs1T1RrNU9Wb2g8L05leHRNYXJrZXI+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "7e98b3b4aef96945", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=abc\u0026marker=2%2196%21MDAwMDI4IWJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQhMDAwMDI4ITk5OTktMTItMzFUMjM6NTk6NTkuOTk5OTk5OVoh\u0026maxresults=1\u0026prefix=blob-for-delimiters-abc\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6c5d4da9-d01e-0013-7359-593c2e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiYzwvUHJlZml4PjxNYXJrZXI+MiE5NiFNREF3TURJNElXSnNiMkl0Wm05eUxXUmxiR2x0YVhSbGNuTXRZV0pqWmk1MGVIUWhNREF3TURJNElUazVPVGt0TVRJdE16RlVNak02TlRrNk5Ua3VPVGs1T1RrNU9Wb2g8L01hcmtlcj48TWF4UmVzdWx0cz4xPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+YWJjPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjBEQzQxMzk8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "ad7ba6734d17ac5f", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-delimiters-abcdir2abce.txt", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "6c5d4daf-d01e-0013-7859-593c2e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "6c23da92ca81a60c", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=abc\u0026maxresults=1000\u0026prefix=blob-for-delimiters-abc\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "6c5d4db6-d01e-0013-7d59-593c2e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiYzwvUHJlZml4PjxNYXhSZXN1bHRzPjEwMDA8L01heFJlc3VsdHM+PERlbGltaXRlcj5hYmM8L0RlbGltaXRlcj48QmxvYnM+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjPC9OYW1lPjwvQmxvYlByZWZpeD48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2YudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwREM0MTM5PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "6852e861526db5cf", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-delimiters-abcdir2abce.txt", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Etag": [ + "\"0x8DC277098CFE144\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "6c5d4dbb-d01e-0013-0259-593c2e000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestListDelimiters/backslash.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestListDelimiters/backslash.replay new file mode 100644 index 000000000..a8bad27b5 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestListDelimiters/backslash.replay @@ -0,0 +1,711 @@ +{ + "Initial": "AQAAAA7dVMB0JvQpPAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "efbc7baaf055d19c", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-delimiters-__0x5c__\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "778ee711-501e-0032-3959-591855000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fPC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1fXzB4NWNfX2RpcjFfXzB4NWNfX2EudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwOUMxRjMxPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fZGlyMV9fMHg1Y19fYi50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA5RTY5OTE8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19kaXIxX18weDVjX19zdWJkaXJfXzB4NWNfX2MudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwQTBEQUZGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fZGlyMV9fMHg1Y19fc3ViZGlyX18weDVjX19kLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMEEzMjU1RjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1fXzB4NWNfX2RpcjJfXzB4NWNfX2UudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlRodSwgMTIgT2N0IDIwMjMgMTc6NDI6MDUgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlRodSwgMTIgT2N0IDIwMjMgMTc6NDI6MDUgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OERCQ0I0QThDRTkwRjZFPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fZi50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjBBQTJCODk8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "fe68d79e519ec3c4", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-delimiters-__0x5c__\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "778ee71e-501e-0032-4459-591855000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fPC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1fXzB4NWNfX2RpcjFfXzB4NWNfX2EudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwOUMxRjMxPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fZGlyMV9fMHg1Y19fYi50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA5RTY5OTE8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19kaXIxX18weDVjX19zdWJkaXJfXzB4NWNfX2MudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwQTBEQUZGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fZGlyMV9fMHg1Y19fc3ViZGlyX18weDVjX19kLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMEEzMjU1RjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1fXzB4NWNfX2RpcjJfXzB4NWNfX2UudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPlRodSwgMTIgT2N0IDIwMjMgMTc6NDI6MDUgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlRodSwgMTIgT2N0IDIwMjMgMTc6NDI6MDUgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OERCQ0I0QThDRTkwRjZFPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fZi50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjBBQTJCODk8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "7be223b510d3015a", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=__0x5c__\u0026maxresults=1000\u0026prefix=blob-for-delimiters-__0x5c__\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "778ee733-501e-0032-5559-591855000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fPC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPl9fMHg1Y19fPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19kaXIxX18weDVjX188L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19kaXIyX18weDVjX188L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19mLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMEFBMkI4OTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "c0176f2070886ec4", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=__0x5c__\u0026maxresults=1000\u0026prefix=blob-for-delimiters-__0x5c__dir1__0x5c__\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "778ee738-501e-0032-5a59-591855000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fZGlyMV9fMHg1Y19fPC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPl9fMHg1Y19fPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19kaXIxX18weDVjX19hLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDlDMUYzMTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1fXzB4NWNfX2RpcjFfXzB4NWNfX2IudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwOUU2OTkxPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fZGlyMV9fMHg1Y19fc3ViZGlyX18weDVjX188L05hbWU+PC9CbG9iUHJlZml4PjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "ee6eb5f69a33b421", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=__0x5c__\u0026maxresults=1000\u0026prefix=blob-for-delimiters-__0x5c__dir1__0x5c__subdir__0x5c__\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "778ee742-501e-0032-6459-591855000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fZGlyMV9fMHg1Y19fc3ViZGlyX18weDVjX188L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+X18weDVjX188L0RlbGltaXRlcj48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1fXzB4NWNfX2RpcjFfXzB4NWNfX3N1YmRpcl9fMHg1Y19fYy50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjBBMERBRkY8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19kaXIxX18weDVjX19zdWJkaXJfXzB4NWNfX2QudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwQTMyNTVGPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "8fe36afe9ef4d708", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=__0x5c__\u0026maxresults=1000\u0026prefix=blob-for-delimiters-__0x5c__dir2__0x5c__\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "778ee74b-501e-0032-6c59-591855000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fZGlyMl9fMHg1Y19fPC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPl9fMHg1Y19fPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19kaXIyX18weDVjX19lLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5UaHUsIDEyIE9jdCAyMDIzIDE3OjQyOjA1IEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5UaHUsIDEyIE9jdCAyMDIzIDE3OjQyOjA1IEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEQkNCNEE4Q0U5MEY2RTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "0c06736090c31351", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=__0x5c__\u0026maxresults=1\u0026prefix=blob-for-delimiters-__0x5c__\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "778ee74f-501e-0032-7059-591855000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fPC9QcmVmaXg+PE1heFJlc3VsdHM+MTwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPl9fMHg1Y19fPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19kaXIxX18weDVjX188L05hbWU+PC9CbG9iUHJlZml4PjwvQmxvYnM+PE5leHRNYXJrZXI+MiExMjAhTURBd01EUTFJV0pzYjJJdFptOXlMV1JsYkdsdGFYUmxjbk10WDE4d2VEVmpYMTlrYVhJeVgxOHdlRFZqWDE5bExuUjRkQ0V3TURBd01qZ2hPVGs1T1MweE1pMHpNVlF5TXpvMU9UbzFPUzQ1T1RrNU9UazVXaUUtPC9OZXh0TWFya2VyPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "37e5491bc07d80b3", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=__0x5c__\u0026marker=2%21120%21MDAwMDQ1IWJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19kaXIyX18weDVjX19lLnR4dCEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=1\u0026prefix=blob-for-delimiters-__0x5c__\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "778ee75a-501e-0032-7b59-591855000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fPC9QcmVmaXg+PE1hcmtlcj4yITEyMCFNREF3TURRMUlXSnNiMkl0Wm05eUxXUmxiR2x0YVhSbGNuTXRYMTh3ZURWalgxOWthWEl5WDE4d2VEVmpYMTlsTG5SNGRDRXdNREF3TWpnaE9UazVPUzB4TWkwek1WUXlNem8xT1RvMU9TNDVPVGs1T1RrNVdpRS08L01hcmtlcj48TWF4UmVzdWx0cz4xPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+X18weDVjX188L0RlbGltaXRlcj48QmxvYnM+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy1fXzB4NWNfX2RpcjJfXzB4NWNfXzwvTmFtZT48L0Jsb2JQcmVmaXg+PC9CbG9icz48TmV4dE1hcmtlcj4yITEwNCFNREF3TURNeklXSnNiMkl0Wm05eUxXUmxiR2x0YVhSbGNuTXRYMTh3ZURWalgxOW1MblI0ZENFd01EQXdNamdoT1RrNU9TMHhNaTB6TVZReU16bzFPVG8xT1M0NU9UazVPVGs1V2lFLTwvTmV4dE1hcmtlcj48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "a7beeb6297155487", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=__0x5c__\u0026marker=2%21104%21MDAwMDMzIWJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19mLnR4dCEwMDAwMjghOTk5OS0xMi0zMVQyMzo1OTo1OS45OTk5OTk5WiE-\u0026maxresults=1\u0026prefix=blob-for-delimiters-__0x5c__\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "778ee761-501e-0032-0259-591855000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fPC9QcmVmaXg+PE1hcmtlcj4yITEwNCFNREF3TURNeklXSnNiMkl0Wm05eUxXUmxiR2x0YVhSbGNuTXRYMTh3ZURWalgxOW1MblI0ZENFd01EQXdNamdoT1RrNU9TMHhNaTB6TVZReU16bzFPVG8xT1M0NU9UazVPVGs1V2lFLTwvTWFya2VyPjxNYXhSZXN1bHRzPjE8L01heFJlc3VsdHM+PERlbGltaXRlcj5fXzB4NWNfXzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fZi50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjBBQTJCODk8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "28eab1db95075fc2", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-delimiters-__0x5c__dir2__0x5c__e.txt", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "778ee769-501e-0032-0859-591855000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "d11560abebf32e1f", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=__0x5c__\u0026maxresults=1000\u0026prefix=blob-for-delimiters-__0x5c__\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "778ee772-501e-0032-1059-591855000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLV9fMHg1Y19fPC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPl9fMHg1Y19fPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19kaXIxX18weDVjX188L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtX18weDVjX19mLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMEFBMkI4OTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "729b2990aec6d783", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-delimiters-__0x5c__dir2__0x5c__e.txt", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Etag": [ + "\"0x8DC2770989948D4\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "778ee785-501e-0032-2159-591855000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestListDelimiters/fwdslash.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestListDelimiters/fwdslash.replay new file mode 100644 index 000000000..e19338cb5 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestListDelimiters/fwdslash.replay @@ -0,0 +1,711 @@ +{ + "Initial": "AQAAAA7dVMB0EzovHQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "99d95abc09b675ec", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-delimiters-%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "c17b7a64-601e-0016-6859-59eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS88L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2EudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwNzdBMDk3PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2IudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwN0E2MDM3PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci9jLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDdDODM3QjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvZC50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA3RTU4OTQ8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjIvZS50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOENCNDRCODQ8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtL2YudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwODJFRDQ2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "25c21765a7ed1d6a", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-delimiters-%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "c17b7a87-601e-0016-0859-59eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS88L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2EudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwNzdBMDk3PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2IudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwN0E2MDM3PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci9jLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDdDODM3QjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvZC50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA3RTU4OTQ8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjIvZS50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOENCNDRCODQ8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtL2YudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwODJFRDQ2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "f5f7cb24630db9b6", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=1000\u0026prefix=blob-for-delimiters-%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "c17b7aa5-601e-0016-2359-59eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS88L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2JQcmVmaXg+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMi88L05hbWU+PC9CbG9iUHJlZml4PjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtL2YudHh0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwODJFRDQ2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyIC8+PC9FbnVtZXJhdGlvblJlc3VsdHM+" + } + }, + { + "ID": "4c1eae948318d193", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=1000\u0026prefix=blob-for-delimiters-%2Fdir1%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "c17b7abd-601e-0016-3959-59eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLzwvUHJlZml4PjxNYXhSZXN1bHRzPjEwMDA8L01heFJlc3VsdHM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvYS50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA3N0EwOTc8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvYi50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA3QTYwMzc8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iUHJlZml4PjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvc3ViZGlyLzwvTmFtZT48L0Jsb2JQcmVmaXg+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "8e69937a20a198c9", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=1000\u0026prefix=blob-for-delimiters-%2Fdir1%2Fsubdir%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "c17b7acf-601e-0016-4959-59eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci88L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYj48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci9jLnR4dDwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDdDODM3QjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvZC50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA3RTU4OTQ8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "e3de61ad957e5fae", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=1000\u0026prefix=blob-for-delimiters-%2Fdir2%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "c17b7adc-601e-0016-5559-59eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyLzwvUHJlZml4PjxNYXhSZXN1bHRzPjEwMDA8L01heFJlc3VsdHM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PEJsb2JzPjxCbG9iPjxOYW1lPmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjIvZS50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+VGh1LCAxMiBPY3QgMjAyMyAxNzo0MjowNSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4REJDQjRBOENCNDRCODQ8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "baa8109db5a7850b", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=1\u0026prefix=blob-for-delimiters-%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "c17b7af5-601e-0016-6c59-59eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS88L1ByZWZpeD48TWF4UmVzdWx0cz4xPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLzwvTmFtZT48L0Jsb2JQcmVmaXg+PC9CbG9icz48TmV4dE1hcmtlcj4yITEwMCFNREF3TURNeElXSnNiMkl0Wm05eUxXUmxiR2x0YVhSbGNuTXRMMlJwY2pJdlpTNTBlSFFoTURBd01ESTRJVGs1T1RrdE1USXRNekZVTWpNNk5UazZOVGt1T1RrNU9UazVPVm9oPC9OZXh0TWFya2VyPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "fb4c12839d43d00b", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%21100%21MDAwMDMxIWJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjIvZS50eHQhMDAwMDI4ITk5OTktMTItMzFUMjM6NTk6NTkuOTk5OTk5OVoh\u0026maxresults=1\u0026prefix=blob-for-delimiters-%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "c17b7b0c-601e-0016-0259-59eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS88L1ByZWZpeD48TWFya2VyPjIhMTAwIU1EQXdNRE14SVdKc2IySXRabTl5TFdSbGJHbHRhWFJsY25NdEwyUnBjakl2WlM1MGVIUWhNREF3TURJNElUazVPVGt0TVRJdE16RlVNak02TlRrNk5Ua3VPVGs1T1RrNU9Wb2g8L01hcmtlcj48TWF4UmVzdWx0cz4xPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyLzwvTmFtZT48L0Jsb2JQcmVmaXg+PC9CbG9icz48TmV4dE1hcmtlcj4yITk2IU1EQXdNREkySVdKc2IySXRabTl5TFdSbGJHbHRhWFJsY25NdEwyWXVkSGgwSVRBd01EQXlPQ0U1T1RrNUxURXlMVE14VkRJek9qVTVPalU1TGprNU9UazVPVGxhSVEtLTwvTmV4dE1hcmtlcj48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "845e564e7b29aa76", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026marker=2%2196%21MDAwMDI2IWJsb2ItZm9yLWRlbGltaXRlcnMtL2YudHh0ITAwMDAyOCE5OTk5LTEyLTMxVDIzOjU5OjU5Ljk5OTk5OTlaIQ--\u0026maxresults=1\u0026prefix=blob-for-delimiters-%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "c17b7b1b-601e-0016-1059-59eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS88L1ByZWZpeD48TWFya2VyPjIhOTYhTURBd01ESTJJV0pzYjJJdFptOXlMV1JsYkdsdGFYUmxjbk10TDJZdWRIaDBJVEF3TURBeU9DRTVPVGs1TFRFeUxUTXhWREl6T2pVNU9qVTVMams1T1RrNU9UbGFJUS0tPC9NYXJrZXI+PE1heFJlc3VsdHM+MTwvTWF4UmVzdWx0cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy0vZi50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA4MkVENDY8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "00c29831bbd08e7b", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-delimiters-%2Fdir2%2Fe.txt", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "c17b7b2d-601e-0016-2259-59eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "e528d9d805315d1b", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=%2F\u0026maxresults=1000\u0026prefix=blob-for-delimiters-%2F\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "c17b7b47-601e-0016-3a59-59eef5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS88L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxCbG9icz48QmxvYlByZWZpeD48TmFtZT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLzwvTmFtZT48L0Jsb2JQcmVmaXg+PEJsb2I+PE5hbWU+YmxvYi1mb3ItZGVsaW1pdGVycy0vZi50eHQ8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA4MkVENDY8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjwvQmxvYnM+PE5leHRNYXJrZXIgLz48L0VudW1lcmF0aW9uUmVzdWx0cz4=" + } + }, + { + "ID": "ac75c45026b0c6b3", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-delimiters-%2Fdir2%2Fe.txt", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Etag": [ + "\"0x8DC27709865E443\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:12 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "c17b7b57-601e-0016-4a59-59eef5000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestListWeirdKeys.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestListWeirdKeys.replay new file mode 100644 index 000000000..58b1e156f --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestListWeirdKeys.replay @@ -0,0 +1,149 @@ +{ + "Initial": "AQAAAA7dVMB0C0xodwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "cc397d3369d5480f", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=list-weirdkeys-\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "e84baa26-201e-005a-5b59-597ec5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5saXN0LXdlaXJka2V5cy08L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxCbG9icz48QmxvYj48TmFtZT5saXN0LXdlaXJka2V5cy0gISIjJCUmYW1wOycoKSorLC0uX18weDJmX188L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA1QzRCNkI8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLS4uX18weDJmX19mb28vLi5fXzB4MmZfX2Jhci8uLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX188L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA1OUQ5Rjk8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLS4uX18weDVjX19mb29fXzB4NWNfXy4uX18weDVjX19iYXJfXzB4NWNfXy4uX18weDVjX18uLl9fMHg1Y19fYmF6Li5fXzB4NWNfXzwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDM1ODI4NjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+bGlzdC13ZWlyZGtleXMtLi5fXzB4NWNfX2Zvb19fMHg1Y19fX18weDVjX19iYXJfXzB4NWNfX19fMHg1Y19fX18weDVjX19iYXo8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA0NjRFNzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLTEyMzQ1PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwMzlDOTA5PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5saXN0LXdlaXJka2V5cy06OyZsdDs9Jmd0Oz88L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA1NTQ1NEM8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLUA8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjAzQkVDNEM8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLVtfXzB4NWNfX11eXzwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDYzMDM2QzwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+bGlzdC13ZWlyZGtleXMtX18weDBfX19fMHgxX19fXzB4Ml9fX18weDNfX19fMHg0X19fXzB4NV9fX18weDZfX19fMHg3X19fXzB4OF9fX18weDlfX19fMHhhX19fXzB4Yl9fX18weGNfX19fMHhkX19fXzB4ZV9fX18weGZfXzwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDY1NzREQTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+bGlzdC13ZWlyZGtleXMtX18weDEwX19fXzB4MTFfX19fMHgxMl9fX18weDEzX19fXzB4MTRfX19fMHgxNV9fX18weDE2X19fXzB4MTdfX19fMHgxOF9fX18weDE5X19fXzB4MWFfX19fMHgxYl9fX18weDFjX19fXzB4MWRfX19fMHgxZV9fX18weDFmX188L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA2N0JGMzQ8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLWA8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjAzRTVEQkU8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLWZvbyBiYXIgYmF6PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwNkM1M0U5PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5saXN0LXdlaXJka2V5cy1mb28iYmFyImJhejwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDM3N0VBRTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+bGlzdC13ZWlyZGtleXMtZm9vLy9iYXIvLy9iYXo8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA0MkYyNzg8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLWZvby9iYXIvYmF6PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwNTdCNkJBPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5saXN0LXdlaXJka2V5cy1mb29fXzB4NWNfX2Jhcl9fMHg1Y19fYmF6PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwNkEzMEE2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5saXN0LXdlaXJka2V5cy17fH1+X18weDdmX188L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA0MDgxMDI8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLeKYuuKYuuKYujwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDRENTQ5NzwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "61fe7d459ebe5b08", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=list-weirdkeys-\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:11 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "e84baa42-201e-005a-7259-597ec5000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5saXN0LXdlaXJka2V5cy08L1ByZWZpeD48TWF4UmVzdWx0cz4xMDAwPC9NYXhSZXN1bHRzPjxCbG9icz48QmxvYj48TmFtZT5saXN0LXdlaXJka2V5cy0gISIjJCUmYW1wOycoKSorLC0uX18weDJmX188L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA1QzRCNkI8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLS4uX18weDJmX19mb28vLi5fXzB4MmZfX2Jhci8uLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX188L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA1OUQ5Rjk8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLS4uX18weDVjX19mb29fXzB4NWNfXy4uX18weDVjX19iYXJfXzB4NWNfXy4uX18weDVjX18uLl9fMHg1Y19fYmF6Li5fXzB4NWNfXzwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDM1ODI4NjwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+bGlzdC13ZWlyZGtleXMtLi5fXzB4NWNfX2Zvb19fMHg1Y19fX18weDVjX19iYXJfXzB4NWNfX19fMHg1Y19fX18weDVjX19iYXo8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA0NjRFNzA8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLTEyMzQ1PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwMzlDOTA5PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5saXN0LXdlaXJka2V5cy06OyZsdDs9Jmd0Oz88L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA1NTQ1NEM8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLUA8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjAzQkVDNEM8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLVtfXzB4NWNfX11eXzwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDYzMDM2QzwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+bGlzdC13ZWlyZGtleXMtX18weDBfX19fMHgxX19fXzB4Ml9fX18weDNfX19fMHg0X19fXzB4NV9fX18weDZfX19fMHg3X19fXzB4OF9fX18weDlfX19fMHhhX19fXzB4Yl9fX18weGNfX19fMHhkX19fXzB4ZV9fX18weGZfXzwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDY1NzREQTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+bGlzdC13ZWlyZGtleXMtX18weDEwX19fXzB4MTFfX19fMHgxMl9fX18weDEzX19fXzB4MTRfX19fMHgxNV9fX18weDE2X19fXzB4MTdfX19fMHgxOF9fX18weDE5X19fXzB4MWFfX19fMHgxYl9fX18weDFjX19fXzB4MWRfX19fMHgxZV9fX18weDFmX188L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMiBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA2N0JGMzQ8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLWA8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjAzRTVEQkU8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLWZvbyBiYXIgYmF6PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwNkM1M0U5PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5saXN0LXdlaXJka2V5cy1mb28iYmFyImJhejwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIxIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDM3N0VBRTwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+bGlzdC13ZWlyZGtleXMtZm9vLy9iYXIvLy9iYXo8L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA0MkYyNzg8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLWZvby9iYXIvYmF6PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwNTdCNkJBPC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5saXN0LXdlaXJka2V5cy1mb29fXzB4NWNfX2Jhcl9fMHg1Y19fYmF6PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjIgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OEQ3MDkzRUYwNkEzMEE2PC9FdGFnPjxDb250ZW50LUxlbmd0aD41PC9Db250ZW50LUxlbmd0aD48Q29udGVudC1UeXBlPnRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTg8L0NvbnRlbnQtVHlwZT48Q29udGVudC1FbmNvZGluZyAvPjxDb250ZW50LUxhbmd1YWdlIC8+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+WFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbCAvPjxDb250ZW50LURpc3Bvc2l0aW9uIC8+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48QmxvYj48TmFtZT5saXN0LXdlaXJka2V5cy17fH1+X18weDdmX188L05hbWU+PFByb3BlcnRpZXM+PENyZWF0aW9uLVRpbWU+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0NyZWF0aW9uLVRpbWU+PExhc3QtTW9kaWZpZWQ+TW9uLCAxNSBKdWwgMjAxOSAxNjoxMDoyMSBHTVQ8L0xhc3QtTW9kaWZpZWQ+PEV0YWc+MHg4RDcwOTNFRjA0MDgxMDI8L0V0YWc+PENvbnRlbnQtTGVuZ3RoPjU8L0NvbnRlbnQtTGVuZ3RoPjxDb250ZW50LVR5cGU+dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtODwvQ29udGVudC1UeXBlPjxDb250ZW50LUVuY29kaW5nIC8+PENvbnRlbnQtTGFuZ3VhZ2UgLz48Q29udGVudC1DUkM2NCAvPjxDb250ZW50LU1ENT5YVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT08L0NvbnRlbnQtTUQ1PjxDYWNoZS1Db250cm9sIC8+PENvbnRlbnQtRGlzcG9zaXRpb24gLz48QmxvYlR5cGU+QmxvY2tCbG9iPC9CbG9iVHlwZT48QWNjZXNzVGllcj5Ib3Q8L0FjY2Vzc1RpZXI+PEFjY2Vzc1RpZXJJbmZlcnJlZD50cnVlPC9BY2Nlc3NUaWVySW5mZXJyZWQ+PExlYXNlU3RhdHVzPnVubG9ja2VkPC9MZWFzZVN0YXR1cz48TGVhc2VTdGF0ZT5hdmFpbGFibGU8L0xlYXNlU3RhdGU+PFNlcnZlckVuY3J5cHRlZD50cnVlPC9TZXJ2ZXJFbmNyeXB0ZWQ+PC9Qcm9wZXJ0aWVzPjxPck1ldGFkYXRhIC8+PC9CbG9iPjxCbG9iPjxOYW1lPmxpc3Qtd2VpcmRrZXlzLeKYuuKYuuKYujwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5Nb24sIDE1IEp1bCAyMDE5IDE2OjEwOjIyIEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhENzA5M0VGMDRENTQ5NzwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestMD5.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestMD5.replay new file mode 100644 index 000000000..f98574956 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestMD5.replay @@ -0,0 +1,565 @@ +{ + "Initial": "AQAAAA7dVMCjKbU2hQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "d68b9089fa7b7326", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-md5-aaa", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B47DAF4D\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "cb8ddf44-301e-0024-6059-59ee82000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "d5cf6a585ab5315c", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-md5-bbb", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "7" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "afqrYmg1ApVVDefVh7wyPQ==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "Z29vZGJ5ZQ==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "afqrYmg1ApVVDefVh7wyPQ==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B4815838\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "QEUKcRXwUQA=" + ], + "X-Ms-Request-Id": [ + "cb8ddf50-301e-0024-6b59-59ee82000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "49526966c47aca19", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-md5-aaa", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B47DAF4D\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "cb8ddf5c-301e-0024-7559-59ee82000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "72322ef6b167c73a", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-md5-bbb", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "7" + ], + "Content-Md5": [ + "afqrYmg1ApVVDefVh7wyPQ==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B4815838\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "cb8ddf64-301e-0024-7c59-59ee82000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "6120aa89f6ddc39d", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1000\u0026prefix=blob-for-md5-\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "cb8ddf6e-301e-0024-0659-59ee82000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PFByZWZpeD5ibG9iLWZvci1tZDUtPC9QcmVmaXg+PE1heFJlc3VsdHM+MTAwMDwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbWQ1LWFhYTwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5XZWQsIDA3IEZlYiAyMDI0IDAwOjA2OjU5IEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5XZWQsIDA3IEZlYiAyMDI0IDAwOjA2OjU5IEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEQzI3NzBCNDdEQUY0RDwvRXRhZz48Q29udGVudC1MZW5ndGg+NTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PEJsb2I+PE5hbWU+YmxvYi1mb3ItbWQ1LWJiYjwvTmFtZT48UHJvcGVydGllcz48Q3JlYXRpb24tVGltZT5XZWQsIDA3IEZlYiAyMDI0IDAwOjA2OjU5IEdNVDwvQ3JlYXRpb24tVGltZT48TGFzdC1Nb2RpZmllZD5XZWQsIDA3IEZlYiAyMDI0IDAwOjA2OjU5IEdNVDwvTGFzdC1Nb2RpZmllZD48RXRhZz4weDhEQzI3NzBCNDgxNTgzODwvRXRhZz48Q29udGVudC1MZW5ndGg+NzwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04PC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2RpbmcgLz48Q29udGVudC1MYW5ndWFnZSAvPjxDb250ZW50LUNSQzY0IC8+PENvbnRlbnQtTUQ1PmFmcXJZbWcxQXBWVkRlZlZoN3d5UFE9PTwvQ29udGVudC1NRDU+PENhY2hlLUNvbnRyb2wgLz48Q29udGVudC1EaXNwb3NpdGlvbiAvPjxCbG9iVHlwZT5CbG9ja0Jsb2I8L0Jsb2JUeXBlPjxBY2Nlc3NUaWVyPkhvdDwvQWNjZXNzVGllcj48QWNjZXNzVGllckluZmVycmVkPnRydWU8L0FjY2Vzc1RpZXJJbmZlcnJlZD48TGVhc2VTdGF0dXM+dW5sb2NrZWQ8L0xlYXNlU3RhdHVzPjxMZWFzZVN0YXRlPmF2YWlsYWJsZTwvTGVhc2VTdGF0ZT48U2VydmVyRW5jcnlwdGVkPnRydWU8L1NlcnZlckVuY3J5cHRlZD48L1Byb3BlcnRpZXM+PE9yTWV0YWRhdGEgLz48L0Jsb2I+PC9CbG9icz48TmV4dE1hcmtlciAvPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + }, + { + "ID": "3662c96729012fac", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-md5-bbb", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "cb8ddf7c-301e-0024-1459-59ee82000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "96c9cc77263dc4b0", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-md5-aaa", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "cb8ddf90-301e-0024-2759-59ee82000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/duplicate_case-insensitive_key_fails.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/duplicate_case-insensitive_key_fails.replay new file mode 100644 index 000000000..775b64fb6 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/duplicate_case-insensitive_key_fails.replay @@ -0,0 +1,44 @@ +{ + "Initial": "AQAAAA7dVMCjCuQd1QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/empty.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/empty.replay new file mode 100644 index 000000000..cc0baab42 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/empty.replay @@ -0,0 +1,279 @@ +{ + "Initial": "AQAAAA7dVMCjA0D66gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "538969556364df4e", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B41B7952\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "163de19b-201e-0007-7759-597441000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "82bbea8250fde130", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B41B7952\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "163de1a6-201e-0007-0159-597441000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "5545d636d50a293d", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "163de1ab-201e-0007-0559-597441000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/empty_key_fails.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/empty_key_fails.replay new file mode 100644 index 000000000..756bce445 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/empty_key_fails.replay @@ -0,0 +1,44 @@ +{ + "Initial": "AQAAAA7dVMCjCtuhkQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_key.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_key.replay new file mode 100644 index 000000000..c2b968581 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_key.replay @@ -0,0 +1,44 @@ +{ + "Initial": "AQAAAA7dVMCjKaZQTQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_value.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_value.replay new file mode 100644 index 000000000..215a18609 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_value.replay @@ -0,0 +1,44 @@ +{ + "Initial": "AQAAAA7dVMCjKa5f2wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata.replay new file mode 100644 index 000000000..5b0e45e8b --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata.replay @@ -0,0 +1,297 @@ +{ + "Initial": "AQAAAA7dVMCjCusDiQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "14a632549ed0996c", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Meta-Key_a": [ + "value-a" + ], + "X-Ms-Meta-Key_b": [ + "value-b" + ], + "X-Ms-Meta-Key_c": [ + "vAlUe-c" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B42E3B52\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "5b142a43-b01e-0077-4a59-59cdb6000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "83745ed21f469704", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B42E3B52\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Meta-Key_a": [ + "value-a" + ], + "X-Ms-Meta-Key_b": [ + "value-b" + ], + "X-Ms-Meta-Key_c": [ + "vAlUe-c" + ], + "X-Ms-Request-Id": [ + "5b142a4b-b01e-0077-4f59-59cdb6000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "9dc63b97316be1e7", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "5b142a4e-b01e-0077-5159-59cdb6000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata_with_content_type.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata_with_content_type.replay new file mode 100644 index 000000000..c76cbcc6c --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata_with_content_type.replay @@ -0,0 +1,285 @@ +{ + "Initial": "AQAAAA7dVMCjGv36sAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "808ec749314c1abb", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Meta-Foo": [ + "bar" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4578F45\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "325adfed-201e-0081-0659-59b8f8000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "62a3132af30e93c1", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B4578F45\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Meta-Foo": [ + "bar" + ], + "X-Ms-Request-Id": [ + "325ae000-201e-0081-1759-59b8f8000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "8bca071c9242e900", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "325ae00f-201e-0081-2559-59b8f8000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata_with_empty_body.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata_with_empty_body.replay new file mode 100644 index 000000000..5ebab690f --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/valid_metadata_with_empty_body.replay @@ -0,0 +1,285 @@ +{ + "Initial": "AQAAAA7dVMCjEj8FlAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "cfd3d7c0b0604059", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Meta-Foo": [ + "bar" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B4414B52\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "c1fcce93-901e-002d-1e59-59ab51000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "d5ef5dbb8a6903e9", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B4414B52\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Meta-Foo": [ + "bar" + ], + "X-Ms-Request-Id": [ + "c1fcceab-901e-002d-3259-59ab51000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "c83b3f4f6971546f", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "c1fcceb6-901e-002d-3b59-59ab51000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/weird_metadata_keys.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/weird_metadata_keys.replay new file mode 100644 index 000000000..deeef69ce --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestMetadata/weird_metadata_keys.replay @@ -0,0 +1,387 @@ +{ + "Initial": "AQAAAA7dVMCjIkG4AgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "e9e2685baec724b4", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "5" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Meta-Foo__0x20__bar__0x20__baz": [ + "foo%20bar%20baz" + ], + "X-Ms-Meta-Foo__0x22__bar__0x22__baz": [ + "foo%22bar%22baz" + ], + "X-Ms-Meta-Foo__0x2f____0x2f__bar__0x2f____0x2f____0x2f__baz": [ + "foo%2F%2Fbar%2F%2F%2Fbaz" + ], + "X-Ms-Meta-Foo__0x2f__bar__0x2f__baz": [ + "foo%2Fbar%2Fbaz" + ], + "X-Ms-Meta-Foo__0x5c__bar__0x5c__baz": [ + "foo%5Cbar%5Cbaz" + ], + "X-Ms-Meta-__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__": [ + "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F" + ], + "X-Ms-Meta-__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__": [ + "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F" + ], + "X-Ms-Meta-__0x20____0x21____0x22____0x23____0x24____0x25____0x26____0x27____0x28____0x29____0x2a____0x2b____0x2c____0x2d____0x2e____0x2f__": [ + "%20%21%22%23$%25\u0026%27%28%29%2A+%2C-.%2F" + ], + "X-Ms-Meta-__0x263a____0x263a____0x263a__": [ + "%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Ms-Meta-__0x2e____0x2e____0x2f__foo__0x2f____0x2e____0x2e____0x2f__bar__0x2f____0x2e____0x2e____0x2f____0x2e____0x2e____0x2f__baz__0x2e____0x2e____0x2f__": [ + "..%2Ffoo%2F..%2Fbar%2F..%2F..%2Fbaz..%2F" + ], + "X-Ms-Meta-__0x2e____0x2e____0x5c__foo__0x5c____0x2e____0x2e____0x5c__bar__0x5c____0x2e____0x2e____0x5c____0x2e____0x2e____0x5c__baz__0x2e____0x2e____0x5c__": [ + "..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C" + ], + "X-Ms-Meta-__0x2e____0x2e____0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz": [ + "..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz" + ], + "X-Ms-Meta-__0x31__2345": [ + "12345" + ], + "X-Ms-Meta-__0x3a____0x3b____0x3c____0x3d____0x3e____0x3f__": [ + ":%3B%3C=%3E%3F" + ], + "X-Ms-Meta-__0x40__": [ + "@" + ], + "X-Ms-Meta-__0x5b____0x5c____0x5d____0x5e___": [ + "%5B%5C%5D%5E_" + ], + "X-Ms-Meta-__0x60__": [ + "%60" + ], + "X-Ms-Meta-__0x7b____0x7c____0x7d____0x7e____0x7f__": [ + "%7B%7C%7D~%7F" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B46A2A2A\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "V0JSBnCFdzM=" + ], + "X-Ms-Request-Id": [ + "5daca777-c01e-0052-7a59-5964ca000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "3548e93a704cf317", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Etag": [ + "\"0x8DC2770B46A2A2A\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Meta-Foo__0x20__bar__0x20__baz": [ + "foo%20bar%20baz" + ], + "X-Ms-Meta-Foo__0x22__bar__0x22__baz": [ + "foo%22bar%22baz" + ], + "X-Ms-Meta-Foo__0x2f____0x2f__bar__0x2f____0x2f____0x2f__baz": [ + "foo%2F%2Fbar%2F%2F%2Fbaz" + ], + "X-Ms-Meta-Foo__0x2f__bar__0x2f__baz": [ + "foo%2Fbar%2Fbaz" + ], + "X-Ms-Meta-Foo__0x5c__bar__0x5c__baz": [ + "foo%5Cbar%5Cbaz" + ], + "X-Ms-Meta-__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__": [ + "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F" + ], + "X-Ms-Meta-__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__": [ + "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F" + ], + "X-Ms-Meta-__0x20____0x21____0x22____0x23____0x24____0x25____0x26____0x27____0x28____0x29____0x2a____0x2b____0x2c____0x2d____0x2e____0x2f__": [ + "%20%21%22%23$%25\u0026%27%28%29%2A+%2C-.%2F" + ], + "X-Ms-Meta-__0x263a____0x263a____0x263a__": [ + "%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Ms-Meta-__0x2e____0x2e____0x2f__foo__0x2f____0x2e____0x2e____0x2f__bar__0x2f____0x2e____0x2e____0x2f____0x2e____0x2e____0x2f__baz__0x2e____0x2e____0x2f__": [ + "..%2Ffoo%2F..%2Fbar%2F..%2F..%2Fbaz..%2F" + ], + "X-Ms-Meta-__0x2e____0x2e____0x5c__foo__0x5c____0x2e____0x2e____0x5c__bar__0x5c____0x2e____0x2e____0x5c____0x2e____0x2e____0x5c__baz__0x2e____0x2e____0x5c__": [ + "..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C" + ], + "X-Ms-Meta-__0x2e____0x2e____0x5c__foo__0x5c____0x5c__bar__0x5c____0x5c____0x5c__baz": [ + "..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz" + ], + "X-Ms-Meta-__0x31__2345": [ + "12345" + ], + "X-Ms-Meta-__0x3a____0x3b____0x3c____0x3d____0x3e____0x3f__": [ + ":%3B%3C=%3E%3F" + ], + "X-Ms-Meta-__0x40__": [ + "@" + ], + "X-Ms-Meta-__0x5b____0x5c____0x5d____0x5e___": [ + "%5B%5C%5D%5E_" + ], + "X-Ms-Meta-__0x60__": [ + "%60" + ], + "X-Ms-Meta-__0x7b____0x7c____0x7d____0x7e____0x7f__": [ + "%7B%7C%7D~%7F" + ], + "X-Ms-Request-Id": [ + "5daca780-c01e-0052-0159-5964ca000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "97be359fd9584124", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-metadata", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "5daca78b-c01e-0052-0a59-5964ca000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestNonexistentBucket.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestNonexistentBucket.replay new file mode 100644 index 000000000..3062faf65 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestNonexistentBucket.replay @@ -0,0 +1,155 @@ +{ + "Initial": "AQAAAA7dVMByLQxiIwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "a5186170b1dcffac", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/bucket-does-not-exist?comp=list\u0026delimiter=\u0026maxresults=1\u0026prefix=\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "225" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:10 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "ContainerNotFound" + ], + "X-Ms-Request-Id": [ + "0bdde196-d01e-002c-7a59-59f48d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+Q29udGFpbmVyTm90Rm91bmQ8L0NvZGU+PE1lc3NhZ2U+VGhlIHNwZWNpZmllZCBjb250YWluZXIgZG9lcyBub3QgZXhpc3QuClJlcXVlc3RJZDowYmRkZTE5Ni1kMDFlLTAwMmMtN2E1OS01OWY0OGQwMDAwMDAKVGltZToyMDI0LTAyLTA3VDAwOjA2OjEwLjk5MDMwOTdaPC9NZXNzYWdlPjwvRXJyb3I+" + } + }, + { + "ID": "f4f7f71e382d586f", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket?comp=list\u0026delimiter=\u0026maxresults=1\u0026prefix=\u0026restype=container", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:10 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "0bdde1b0-d01e-002c-1159-59f48d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW51bWVyYXRpb25SZXN1bHRzIFNlcnZpY2VFbmRwb2ludD0iaHR0cHM6Ly9nb2Nsb3VkYmxvYnRlc3RzLmJsb2IuY29yZS53aW5kb3dzLm5ldC8iIENvbnRhaW5lck5hbWU9ImdvLWNsb3VkLWJ1Y2tldCI+PE1heFJlc3VsdHM+MTwvTWF4UmVzdWx0cz48QmxvYnM+PEJsb2I+PE5hbWU+YmxvYi1mb3ItY29weWluZy1kZXN0PC9OYW1lPjxQcm9wZXJ0aWVzPjxDcmVhdGlvbi1UaW1lPk1vbiwgMTUgSnVsIDIwMTkgMTY6MTA6MjcgR01UPC9DcmVhdGlvbi1UaW1lPjxMYXN0LU1vZGlmaWVkPlRodSwgMTIgT2N0IDIwMjMgMTc6NDI6MTEgR01UPC9MYXN0LU1vZGlmaWVkPjxFdGFnPjB4OERCQ0I0QTkwQTRBMUUwPC9FdGFnPjxDb250ZW50LUxlbmd0aD4xMTwvQ29udGVudC1MZW5ndGg+PENvbnRlbnQtVHlwZT50ZXh0L3BsYWluPC9Db250ZW50LVR5cGU+PENvbnRlbnQtRW5jb2Rpbmc+aWRlbnRpdHk8L0NvbnRlbnQtRW5jb2Rpbmc+PENvbnRlbnQtTGFuZ3VhZ2U+ZW48L0NvbnRlbnQtTGFuZ3VhZ2U+PENvbnRlbnQtQ1JDNjQgLz48Q29udGVudC1NRDU+c1FxTnNXVGdkVUVGdDZtYjV5NC81UT09PC9Db250ZW50LU1ENT48Q2FjaGUtQ29udHJvbD5uby1jYWNoZTwvQ2FjaGUtQ29udHJvbD48Q29udGVudC1EaXNwb3NpdGlvbj5pbmxpbmU8L0NvbnRlbnQtRGlzcG9zaXRpb24+PEJsb2JUeXBlPkJsb2NrQmxvYjwvQmxvYlR5cGU+PEFjY2Vzc1RpZXI+SG90PC9BY2Nlc3NUaWVyPjxBY2Nlc3NUaWVySW5mZXJyZWQ+dHJ1ZTwvQWNjZXNzVGllckluZmVycmVkPjxMZWFzZVN0YXR1cz51bmxvY2tlZDwvTGVhc2VTdGF0dXM+PExlYXNlU3RhdGU+YXZhaWxhYmxlPC9MZWFzZVN0YXRlPjxTZXJ2ZXJFbmNyeXB0ZWQ+dHJ1ZTwvU2VydmVyRW5jcnlwdGVkPjwvUHJvcGVydGllcz48T3JNZXRhZGF0YSAvPjwvQmxvYj48L0Jsb2JzPjxOZXh0TWFya2VyPjIhOTYhTURBd01ESTRJV0pzYjJJdFptOXlMV052Y0hscGJtY3RaR1Z6ZEMxbGVHbHpkSE1oTURBd01ESTRJVGs1T1RrdE1USXRNekZVTWpNNk5UazZOVGt1T1RrNU9UazVPVm9oPC9OZXh0TWFya2VyPjwvRW51bWVyYXRpb25SZXN1bHRzPg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/length_0_read.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/length_0_read.replay new file mode 100644 index 000000000..4b5f48030 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/length_0_read.replay @@ -0,0 +1,361 @@ +{ + "Initial": "AQAAAA7dVMB2BGw6ZQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "2a1c696bbeb3f22c", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "27" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Etag": [ + "\"0x8DC2770994BB5ED\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "CQSsryslIqA=" + ], + "X-Ms-Request-Id": [ + "f08b50d0-701e-0047-7959-597379000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "1291b49a2fed1cec", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "27" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Etag": [ + "\"0x8DC2770994BB5ED\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "f08b50d8-701e-0047-8059-597379000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "d38c131c84b64379", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "27" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Etag": [ + "\"0x8DC2770994BB5ED\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "f08b50e1-701e-0047-0859-597379000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "0344a908def7e83e", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "f08b50e5-701e-0047-0c59-597379000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/negative_offset_fails.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/negative_offset_fails.replay new file mode 100644 index 000000000..91836e4c0 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/negative_offset_fails.replay @@ -0,0 +1,44 @@ +{ + "Initial": "AQAAAA7dVMB2BGHBpwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_a_part_in_middle.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_a_part_in_middle.replay new file mode 100644 index 000000000..883633395 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_a_part_in_middle.replay @@ -0,0 +1,646 @@ +{ + "Initial": "AQAAAA7dVMB2GgYGrAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "faf3f1b58246ebac", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "27" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099822742\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "CQSsryslIqA=" + ], + "X-Ms-Request-Id": [ + "bafe632c-701e-0057-7459-59b611000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "83ca26d9b305bcc7", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=10-14" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 10-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099822742\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "bafe6331-701e-0057-7859-59b611000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "a2xtbm8=" + } + }, + { + "ID": "29abdccfde812ac8", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=10-14" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 10-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099822742\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "bafe6336-701e-0057-7c59-59b611000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "a2xtbm8=" + } + }, + { + "ID": "d8fb09a689a26ae4", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=14-14" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 14-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099822742\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "bafe633c-701e-0057-0259-59b611000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "bw==" + } + }, + { + "ID": "9223cf8f46921c95", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=14-14" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 14-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099822742\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "bafe633d-701e-0057-0359-59b611000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "bw==" + } + }, + { + "ID": "943ca0f123fef95f", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=12-14" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "3" + ], + "Content-Range": [ + "bytes 12-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099822742\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "bafe6340-701e-0057-0659-59b611000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "bW5v" + } + }, + { + "ID": "5bd0daf167cbf34c", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "bafe6343-701e-0057-0959-59b611000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_from_positive_offset_to_end.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_from_positive_offset_to_end.replay new file mode 100644 index 000000000..392d16f2c --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_from_positive_offset_to_end.replay @@ -0,0 +1,646 @@ +{ + "Initial": "AQAAAA7dVMB2Da12yQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "e9e9d838787ab93f", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "27" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Etag": [ + "\"0x8DC27709963321F\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "CQSsryslIqA=" + ], + "X-Ms-Request-Id": [ + "059081d3-501e-001d-2359-59159e000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "4be3b133d5e46337", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=10-" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "17" + ], + "Content-Range": [ + "bytes 10-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Etag": [ + "\"0x8DC27709963321F\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "059081e8-501e-001d-3559-59159e000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "a2xtbm9wcXVyc3R1dnd4eXo=" + } + }, + { + "ID": "168276e417593df2", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=10-" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "17" + ], + "Content-Range": [ + "bytes 10-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Etag": [ + "\"0x8DC27709963321F\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "059081f7-501e-001d-4259-59159e000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "a2xtbm9wcXVyc3R1dnd4eXo=" + } + }, + { + "ID": "c68d951e6cf56101", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=22-" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 22-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Etag": [ + "\"0x8DC27709963321F\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "059081ff-501e-001d-4959-59159e000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "dnd4eXo=" + } + }, + { + "ID": "e24feb1d737d23ea", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=22-" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 22-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Etag": [ + "\"0x8DC27709963321F\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "05908205-501e-001d-4f59-59159e000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "dnd4eXo=" + } + }, + { + "ID": "1145b9238a4b22de", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=16-" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "11" + ], + "Content-Range": [ + "bytes 16-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Etag": [ + "\"0x8DC27709963321F\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "0590820d-501e-001d-5659-59159e000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "cXVyc3R1dnd4eXo=" + } + }, + { + "ID": "e0e21c29bf88a43f", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "05908219-501e-001d-6059-59159e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_in_full.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_in_full.replay new file mode 100644 index 000000000..eea72442f --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_in_full.replay @@ -0,0 +1,634 @@ +{ + "Initial": "AQAAAA7dVMB2JaSYeAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "49e383875779ecd2", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "27" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099A0CE54\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "CQSsryslIqA=" + ], + "X-Ms-Request-Id": [ + "4fa5c117-601e-005b-6e59-592119000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "faf4151972d76f68", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "27" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099A0CE54\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4fa5c125-601e-005b-7b59-592119000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "31b96b0df9c5845f", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "27" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099A0CE54\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4fa5c132-601e-005b-0559-592119000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "e0a1a7fa0f80e5b8", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=18-" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099A0CE54\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4fa5c13b-601e-005b-0e59-592119000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "296f9643ee676df1", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=18-" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099A0CE54\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4fa5c142-601e-005b-1559-592119000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "e2b5ce9a0e803515", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=9-" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "18" + ], + "Content-Range": [ + "bytes 9-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099A0CE54\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "4fa5c14b-601e-005b-1e59-592119000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "amtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "1224e53d1e3b3854", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "4fa5c152-601e-005b-2559-592119000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_in_full_with_negative_length_not_-1.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_in_full_with_negative_length_not_-1.replay new file mode 100644 index 000000000..2fe25c376 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_in_full_with_negative_length_not_-1.replay @@ -0,0 +1,634 @@ +{ + "Initial": "AQAAAA7dVMB2MhiqOgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "d0807eec7cb46206", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "27" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099C0FBDA\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "CQSsryslIqA=" + ], + "X-Ms-Request-Id": [ + "df71ef24-f01e-0004-4159-599525000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "2cc626c6440cddf3", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "27" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099C0FBDA\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "df71ef2b-f01e-0004-4759-599525000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "66d6d1211a7fd2e8", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "27" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099C0FBDA\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "df71ef33-f01e-0004-4e59-599525000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "98cc9815bacd7597", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=18-" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099C0FBDA\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "df71ef3a-f01e-0004-5559-599525000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "8395a07ccf0eedf7", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=18-" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099C0FBDA\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "df71ef42-f01e-0004-5b59-599525000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "8d2d1868db803d67", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Range": [ + "bytes=9-" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "18" + ], + "Content-Range": [ + "bytes 9-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC277099C0FBDA\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "df71ef47-f01e-0004-6059-599525000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "amtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "f9719f35870c1fe1", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "df71ef53-f01e-0004-6a59-599525000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_of_nonexistent_key_fails.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_of_nonexistent_key_fails.replay new file mode 100644 index 000000000..6cbda1198 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestRead/read_of_nonexistent_key_fails.replay @@ -0,0 +1,249 @@ +{ + "Initial": "AQAAAA7dVMB1OCLMbQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "7bb0d73519f2bdbe", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "27" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Etag": [ + "\"0x8DC27709937E2A9\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "CQSsryslIqA=" + ], + "X-Ms-Request-Id": [ + "3d382368-001e-0000-4559-591822000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "8da06e4be9503f54", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/key-does-not-exist", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "3d382370-001e-0000-4c59-591822000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOjNkMzgyMzcwLTAwMWUtMDAwMC00YzU5LTU5MTgyMjAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDY6MTQuMDM5MTczOVo8L01lc3NhZ2U+PC9FcnJvcj4=" + } + }, + { + "ID": "ea8bc12ff38fa675", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:13 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "3d382378-001e-0000-5359-591822000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestSignedURL.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestSignedURL.replay new file mode 100644 index 000000000..6f451c14d --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestSignedURL.replay @@ -0,0 +1,626 @@ +{ + "Initial": "AQAAAA7dviK2JCzi3QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "e88a3ea7a04f3ee1", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-signing?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "279" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:25 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "AuthorizationPermissionMismatch" + ], + "X-Ms-Request-Id": [ + "f1cf088c-801e-0021-3329-983c59000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QXV0aG9yaXphdGlvblBlcm1pc3Npb25NaXNtYXRjaDwvQ29kZT48TWVzc2FnZT5UaGlzIHJlcXVlc3QgaXMgbm90IGF1dGhvcml6ZWQgdG8gcGVyZm9ybSB0aGlzIG9wZXJhdGlvbiB1c2luZyB0aGlzIHBlcm1pc3Npb24uClJlcXVlc3RJZDpmMWNmMDg4Yy04MDFlLTAwMjEtMzMyOS05ODNjNTkwMDAwMDAKVGltZToyMDI0LTA0LTI2VDIyOjMzOjI2LjgzNTg3MzFaPC9NZXNzYWdlPjwvRXJyb3I+" + } + }, + { + "ID": "2cf85a49503197fa", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-signing?sp=d\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "279" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:25 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "AuthorizationPermissionMismatch" + ], + "X-Ms-Request-Id": [ + "f1cf0893-801e-0021-3929-983c59000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QXV0aG9yaXphdGlvblBlcm1pc3Npb25NaXNtYXRjaDwvQ29kZT48TWVzc2FnZT5UaGlzIHJlcXVlc3QgaXMgbm90IGF1dGhvcml6ZWQgdG8gcGVyZm9ybSB0aGlzIG9wZXJhdGlvbiB1c2luZyB0aGlzIHBlcm1pc3Npb24uClJlcXVlc3RJZDpmMWNmMDg5My04MDFlLTAwMjEtMzkyOS05ODNjNTkwMDAwMDAKVGltZToyMDI0LTA0LTI2VDIyOjMzOjI2Ljg1NDk4NzdaPC9NZXNzYWdlPjwvRXJyb3I+" + } + }, + { + "ID": "d030a18fe2807069", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-signing?sp=cw\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:25 GMT" + ], + "Etag": [ + "\"0x8DC6640E3FD4193\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:26 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "vo7q9sPVKY0=" + ], + "X-Ms-Request-Id": [ + "f1cf0897-801e-0021-3d29-983c59000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "aaed499f1908b08a", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-signing?sp=d\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "279" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:26 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "AuthorizationPermissionMismatch" + ], + "X-Ms-Request-Id": [ + "f1cf089d-801e-0021-4129-983c59000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QXV0aG9yaXphdGlvblBlcm1pc3Npb25NaXNtYXRjaDwvQ29kZT48TWVzc2FnZT5UaGlzIHJlcXVlc3QgaXMgbm90IGF1dGhvcml6ZWQgdG8gcGVyZm9ybSB0aGlzIG9wZXJhdGlvbiB1c2luZyB0aGlzIHBlcm1pc3Npb24uClJlcXVlc3RJZDpmMWNmMDg5ZC04MDFlLTAwMjEtNDEyOS05ODNjNTkwMDAwMDAKVGltZToyMDI0LTA0LTI2VDIyOjMzOjI2Ljg5Nzc4MTBaPC9NZXNzYWdlPjwvRXJyb3I+" + } + }, + { + "ID": "20e8106baa8c5e09", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-signing?sp=cw\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "279" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:26 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "AuthorizationPermissionMismatch" + ], + "X-Ms-Request-Id": [ + "f1cf08a3-801e-0021-4629-983c59000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QXV0aG9yaXphdGlvblBlcm1pc3Npb25NaXNtYXRjaDwvQ29kZT48TWVzc2FnZT5UaGlzIHJlcXVlc3QgaXMgbm90IGF1dGhvcml6ZWQgdG8gcGVyZm9ybSB0aGlzIG9wZXJhdGlvbiB1c2luZyB0aGlzIHBlcm1pc3Npb24uClJlcXVlc3RJZDpmMWNmMDhhMy04MDFlLTAwMjEtNDYyOS05ODNjNTkwMDAwMDAKVGltZToyMDI0LTA0LTI2VDIyOjMzOjI2LjkxNjEyNDhaPC9NZXNzYWdlPjwvRXJyb3I+" + } + }, + { + "ID": "71a4330d6c1b156a", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-signing", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "223" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:26 GMT" + ], + "Server": [ + "Blob Service Version 1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Request-Id": [ + "f1cf08a6-801e-0021-4929-983c59000000" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+UmVzb3VyY2VOb3RGb3VuZDwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIHJlc291cmNlIGRvZXMgbm90IGV4aXN0LgpSZXF1ZXN0SWQ6ZjFjZjA4YTYtODAxZS0wMDIxLTQ5MjktOTgzYzU5MDAwMDAwClRpbWU6MjAyNC0wNC0yNlQyMjozMzoyNi45MzQyNTczWjwvTWVzc2FnZT48L0Vycm9yPg==" + } + }, + { + "ID": "5537485276eba0d8", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-signing?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:26 GMT" + ], + "Etag": [ + "\"0x8DC6640E3FD4193\"" + ], + "Last-Modified": [ + "Fri, 26 Apr 2024 22:33:26 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Fri, 26 Apr 2024 22:33:26 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "f1cf08a8-801e-0021-4b29-983c59000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "8ac1ef3ac555f51d", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-signing?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "279" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:26 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "AuthorizationPermissionMismatch" + ], + "X-Ms-Request-Id": [ + "f1cf08ab-801e-0021-4e29-983c59000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QXV0aG9yaXphdGlvblBlcm1pc3Npb25NaXNtYXRjaDwvQ29kZT48TWVzc2FnZT5UaGlzIHJlcXVlc3QgaXMgbm90IGF1dGhvcml6ZWQgdG8gcGVyZm9ybSB0aGlzIG9wZXJhdGlvbiB1c2luZyB0aGlzIHBlcm1pc3Npb24uClJlcXVlc3RJZDpmMWNmMDhhYi04MDFlLTAwMjEtNGUyOS05ODNjNTkwMDAwMDAKVGltZToyMDI0LTA0LTI2VDIyOjMzOjI2Ljk3MTM2NjJaPC9NZXNzYWdlPjwvRXJyb3I+" + } + }, + { + "ID": "2d4b51c22891c796", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-signing?sp=cw\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "279" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:26 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "AuthorizationPermissionMismatch" + ], + "X-Ms-Request-Id": [ + "f1cf08ae-801e-0021-5129-983c59000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QXV0aG9yaXphdGlvblBlcm1pc3Npb25NaXNtYXRjaDwvQ29kZT48TWVzc2FnZT5UaGlzIHJlcXVlc3QgaXMgbm90IGF1dGhvcml6ZWQgdG8gcGVyZm9ybSB0aGlzIG9wZXJhdGlvbiB1c2luZyB0aGlzIHBlcm1pc3Npb24uClJlcXVlc3RJZDpmMWNmMDhhZS04MDFlLTAwMjEtNTEyOS05ODNjNTkwMDAwMDAKVGltZToyMDI0LTA0LTI2VDIyOjMzOjI2Ljk4OTgxOTdaPC9NZXNzYWdlPjwvRXJyb3I+" + } + }, + { + "ID": "b94ff09b49f80ede", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-signing?sp=d\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:26 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "f1cf08b1-801e-0021-5429-983c59000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "4e194413626b0905", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-signing?sp=r\u0026sr=b\u0026sv=2023-11-03", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Fri, 26 Apr 2024 22:33:26 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "f1cf08ba-801e-0021-5a29-983c59000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOmYxY2YwOGJhLTgwMWUtMDAyMS01YTI5LTk4M2M1OTAwMDAwMApUaW1lOjIwMjQtMDQtMjZUMjI6MzM6MjcuMDI4OTQ3M1o8L01lc3NhZ2U+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestUploadDownload.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestUploadDownload.replay new file mode 100644 index 000000000..4c25af94d --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestUploadDownload.replay @@ -0,0 +1,419 @@ +{ + "Initial": "AQAAAA7dVMCiN511SAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "a1573b6ce9672d41", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-upload-download", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Type": [ + "text" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "dXAgYW5kIGRvd24=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "G3VTPtWoaf9vOuAzbQwzIA==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B4081B42\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "wOkxZJKwY/U=" + ], + "X-Ms-Request-Id": [ + "3ca15839-a01e-0044-4059-59921d000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "9ed781a5d8e54025", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-upload-download", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "G3VTPtWoaf9vOuAzbQwzIA==" + ], + "Content-Type": [ + "text" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B4081B42\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "3ca1584b-a01e-0044-5059-59921d000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "dXAgYW5kIGRvd24=" + } + }, + { + "ID": "a1573b6ce9672d42", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-upload-download", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "G3VTPtWoaf9vOuAzbQwzIA==" + ], + "X-Ms-Blob-Content-Type": [ + "text" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "dXAgYW5kIGRvd24=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "G3VTPtWoaf9vOuAzbQwzIA==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Etag": [ + "\"0x8DC2770B4081B42\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:59 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "wOkxZJKwY/U=" + ], + "X-Ms-Request-Id": [ + "3ca15839-a01e-0044-4059-59921d000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "31399688c633573d", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-upload-download", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "3ca15857-a01e-0044-5a59-59921d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "31399688c633573e", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-upload-download", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:58 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "3ca15857-a01e-0044-5a59-59921d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/ContentType_is_discovered_if_not_provided.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/ContentType_is_discovered_if_not_provided.replay new file mode 100644 index 000000000..908715956 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/ContentType_is_discovered_if_not_provided.replay @@ -0,0 +1,361 @@ +{ + "Initial": "AQAAAA7dVMCMCZBfVAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "4625d8a3d67044cd", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "6354" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Type": [ + "text/html; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "D2p8n/PT13C49/oZwq4Z0A==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Etag": [ + "\"0x8DC2770A675FB5A\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "h/FDiq2zgEw=" + ], + "X-Ms-Request-Id": [ + "06db5877-101e-0041-6159-5940c6000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "923e7ca9e4b0c4b9", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "6354" + ], + "Content-Md5": [ + "D2p8n/PT13C49/oZwq4Z0A==" + ], + "Content-Type": [ + "text/html; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Etag": [ + "\"0x8DC2770A675FB5A\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "06db58b2-101e-0041-6f59-5940c6000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "91f79674569ba9f7", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "6354" + ], + "Content-Md5": [ + "D2p8n/PT13C49/oZwq4Z0A==" + ], + "Content-Type": [ + "text/html; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Etag": [ + "\"0x8DC2770A675FB5A\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "06db58d4-101e-0041-7959-5940c6000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "cc3411340347defc", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "06db58e3-101e-0041-0159-5940c6000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay new file mode 100644 index 000000000..175b15bc3 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay @@ -0,0 +1,273 @@ +{ + "Initial": "AQAAAA7dVMCMEqb1XQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "1d24ce9ae728ae9a", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "6354" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Type": [ + "" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "D2p8n/PT13C49/oZwq4Z0A==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Etag": [ + "\"0x8DC2770A6920AC5\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "h/FDiq2zgEw=" + ], + "X-Ms-Request-Id": [ + "772045de-b01e-0083-1159-590640000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "452773bba75efcec", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "6354" + ], + "Content-Md5": [ + "D2p8n/PT13C49/oZwq4Z0A==" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Etag": [ + "\"0x8DC2770A6920AC5\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "772045f5-b01e-0083-1a59-590640000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "3c891036536c3bde", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "77204603-b01e-0083-2159-590640000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match,_blob_existed.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match,_blob_existed.replay new file mode 100644 index 000000000..752e71252 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match,_blob_existed.replay @@ -0,0 +1,276 @@ +{ + "Initial": "AQAAAA7dVMCMMXnlVgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "18889ef16c37b9fd", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "16" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "dH9B/ScP7BuCvgMMwc1IAQ==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "ZXhpc3RpbmcgY29udGVudA==" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "dH9B/ScP7BuCvgMMwc1IAQ==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Etag": [ + "\"0x8DC2770A6DC0148\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "vsdKdvBj/oM=" + ], + "X-Ms-Request-Id": [ + "1b824846-d01e-0003-5659-59f946000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "6a1f17607f6fd4a4", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "16" + ], + "Content-Md5": [ + "dH9B/ScP7BuCvgMMwc1IAQ==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Etag": [ + "\"0x8DC2770A6DC0148\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "1b824850-d01e-0003-5c59-59f946000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "ZXhpc3RpbmcgY29udGVudA==" + } + }, + { + "ID": "8c7980f71320c2fc", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "1b824860-d01e-0003-6559-59f946000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match.replay new file mode 100644 index 000000000..04423b9e5 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match.replay @@ -0,0 +1,103 @@ +{ + "Initial": "AQAAAA7dVMCMLJf7xgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "21b17413210a0e73", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "7662cf48-b01e-0067-1459-5908de000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOjc2NjJjZjQ4LWIwMWUtMDA2Ny0xNDU5LTU5MDhkZTAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDY6MzYuODI1NTQwM1o8L01lc3NhZ2U+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_match.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_match.replay new file mode 100644 index 000000000..b18028299 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/Content_md5_match.replay @@ -0,0 +1,276 @@ +{ + "Initial": "AQAAAA7dVMCMJOHbOAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "1efba82184b182f9", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Etag": [ + "\"0x8DC2770A6BBFAE2\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "vo7q9sPVKY0=" + ], + "X-Ms-Request-Id": [ + "b32a493b-601e-0039-2459-59e33e000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "fc03ac90885e7f3f", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "11" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Etag": [ + "\"0x8DC2770A6BBFAE2\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "b32a4958-601e-0039-3459-59e33e000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "60cc779a7410e661", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "b32a496f-601e-0039-3f59-59e33e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/a_large_jpg_file_gets_a_ContentType.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/a_large_jpg_file_gets_a_ContentType.replay new file mode 100644 index 000000000..ad648df2e --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/a_large_jpg_file_gets_a_ContentType.replay @@ -0,0 +1,422 @@ +{ + "Initial": "AQAAAA7dVMCNBoKDvwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "71c7010a770404d4", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "38430" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Type": [ + "image/jpeg" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + ] + }, + "Response": { + "StatusCode": 502, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Warning": [ + "199 \"martian\" \"dial tcp 20.60.80.2:443: connect: connection timed out\" \"Wed, 07 Feb 2024 00:06:56 GMT\"" + ] + }, + "Body": "" + } + }, + { + "ID": "8eed9964f1d22ec3", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "38430" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Type": [ + "image/jpeg" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "YtQ/og5wv6H9siUQ0cBg0g==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3331000\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "3cprLrYfk2E=" + ], + "X-Ms-Request-Id": [ + "cc605ee8-c01e-0042-2b59-59a1a2000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "548d1c705705b6e3", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "38430" + ], + "Content-Md5": [ + "YtQ/og5wv6H9siUQ0cBg0g==" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3331000\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "cc605efc-c01e-0042-3e59-59a1a2000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + } + }, + { + "ID": "de5d33292cd052ac", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "38430" + ], + "Content-Md5": [ + "YtQ/og5wv6H9siUQ0cBg0g==" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B3331000\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "cc605f0b-c01e-0042-4c59-59a1a2000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "9a0d2115f52419b8", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "cc605f12-c01e-0042-5159-59a1a2000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay new file mode 100644 index 000000000..8943f3fcb --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay @@ -0,0 +1,361 @@ +{ + "Initial": "AQAAAA7dVMChKbuqXgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "8a61c33a678818cd", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "38430" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Type": [ + "image/jpeg" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "YtQ/og5wv6H9siUQ0cBg0g==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B34E352C\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "3cprLrYfk2E=" + ], + "X-Ms-Request-Id": [ + "a5efc8ba-201e-0075-5859-59730e000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "8f72eff4b6da0fce", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "38430" + ], + "Content-Md5": [ + "YtQ/og5wv6H9siUQ0cBg0g==" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B34E352C\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "a5efc8ca-201e-0075-6559-59730e000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + } + }, + { + "ID": "0d28174169b433d9", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "38430" + ], + "Content-Md5": [ + "YtQ/og5wv6H9siUQ0cBg0g==" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Etag": [ + "\"0x8DC2770B34E352C\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "a5efc8d7-201e-0075-7059-59730e000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "d02c078f55191abd", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:57 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "a5efc8de-201e-0075-7659-59730e000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/a_small_text_file_gets_a_ContentType.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/a_small_text_file_gets_a_ContentType.replay new file mode 100644 index 000000000..2e62e16f1 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/a_small_text_file_gets_a_ContentType.replay @@ -0,0 +1,361 @@ +{ + "Initial": "AQAAAA7dVMCMOTi7MAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "3e4fedee8ab0f8f4", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "20" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "VGhpcyBpcyBhIHRleHQgZmlsZS4=" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "PzMJMSzDJkoTibLSY97OjQ==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Etag": [ + "\"0x8DC2770A6EFD48F\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:37 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "t1+o9/4ppWU=" + ], + "X-Ms-Request-Id": [ + "d0fa4863-301e-001b-2359-592621000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "7f9524124d54496b", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "20" + ], + "Content-Md5": [ + "PzMJMSzDJkoTibLSY97OjQ==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Etag": [ + "\"0x8DC2770A6EFD48F\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:37 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:37 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "d0fa4868-301e-001b-2759-592621000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "VGhpcyBpcyBhIHRleHQgZmlsZS4=" + } + }, + { + "ID": "c542b853c7c61275", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "20" + ], + "Content-Md5": [ + "PzMJMSzDJkoTibLSY97OjQ==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Etag": [ + "\"0x8DC2770A6EFD48F\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:37 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:37 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "d0fa4873-301e-001b-2e59-592621000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "14ab534fb309eb60", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "d0fa487d-301e-001b-3659-592621000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/invalid_ContentType_fails.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/invalid_ContentType_fails.replay new file mode 100644 index 000000000..49d38c539 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/invalid_ContentType_fails.replay @@ -0,0 +1,143 @@ +{ + "Initial": "AQAAAA7dVMB3KKpGPgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "f80800bad2ec5a9a", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 502, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Warning": [ + "199 \"martian\" \"dial tcp 20.60.80.2:443: connect: connection timed out\" \"Wed, 07 Feb 2024 00:06:35 GMT\"" + ] + }, + "Body": "" + } + }, + { + "ID": "36bf63e6a40cb44d", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "BlobNotFound" + ], + "X-Ms-Request-Id": [ + "446981c6-b01e-0058-2859-59c07d000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+QmxvYk5vdEZvdW5kPC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQgYmxvYiBkb2VzIG5vdCBleGlzdC4KUmVxdWVzdElkOjQ0Njk4MWM2LWIwMWUtMDA1OC0yODU5LTU5YzA3ZDAwMDAwMApUaW1lOjIwMjQtMDItMDdUMDA6MDY6MzYuMTUxNTE5M1o8L01lc3NhZ2U+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay new file mode 100644 index 000000000..023cf7902 --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay @@ -0,0 +1,273 @@ +{ + "Initial": "AQAAAA7dVMB3H4AeBAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "941b3cf92d9bafda", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "1B2M2Y8AsgTpgAmY7PhCfg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Etag": [ + "\"0x8DC27709A2BBC06\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "AAAAAAAAAAA=" + ], + "X-Ms-Request-Id": [ + "3e5803d1-701e-0035-6c59-597436000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "a4f68aa90e7ee68c", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "1B2M2Y8AsgTpgAmY7PhCfg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Etag": [ + "\"0x8DC27709A2BBC06\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "3e5803e7-701e-0035-7f59-597436000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "fb1ff0f8593675c8", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "3e5803ee-701e-0035-0559-597436000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob.replay new file mode 100644 index 000000000..b98daaedd --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob.replay @@ -0,0 +1,273 @@ +{ + "Initial": "AQAAAA7dVMB3F9/72QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "cc8bb0c9b188ed79", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "1B2M2Y8AsgTpgAmY7PhCfg==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC27709A163B59\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "AAAAAAAAAAA=" + ], + "X-Ms-Request-Id": [ + "853285a1-a01e-0026-5959-59503a000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "e5b18ee2e03199f0", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "1B2M2Y8AsgTpgAmY7PhCfg==" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Etag": [ + "\"0x8DC27709A163B59\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:15 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "853285b0-a01e-0026-6759-59503a000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "c0ca7694e64db930", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "853285b8-a01e-0026-6d59-59503a000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/write_to_empty_key_fails.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/write_to_empty_key_fails.replay new file mode 100644 index 000000000..ccbe046cd --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/write_to_empty_key_fails.replay @@ -0,0 +1,176 @@ +{ + "Initial": "AQAAAA7dVMB3Ee6ItAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "4c45c88947e81a8f", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Type": [ + "text/plain; charset=utf-8" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "325" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "InvalidUri" + ], + "X-Ms-Request-Id": [ + "2441b67a-e01e-0055-1c59-5908a9000000" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+SW52YWxpZFVyaTwvQ29kZT48TWVzc2FnZT5UaGUgcmVxdWVzdGVkIFVSSSBkb2VzIG5vdCByZXByZXNlbnQgYW55IHJlc291cmNlIG9uIHRoZSBzZXJ2ZXIuClJlcXVlc3RJZDoyNDQxYjY3YS1lMDFlLTAwNTUtMWM1OS01OTA4YTkwMDAwMDAKVGltZToyMDI0LTAyLTA3VDAwOjA2OjE1LjM3MjY4NTFaPC9NZXNzYWdlPjxVcmlQYXRoPmh0dHBzOi8vZ29jbG91ZGJsb2J0ZXN0cy5ibG9iLmNvcmUud2luZG93cy5uZXQvZ28tY2xvdWQtYnVja2V0LzwvVXJpUGF0aD48L0Vycm9yPg==" + } + }, + { + "ID": "bcb7cbe66eb0e2a1", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "325" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:14 GMT" + ], + "Server": [ + "Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Error-Code": [ + "InvalidUri" + ], + "X-Ms-Request-Id": [ + "2441b67f-e01e-0055-2059-5908a9000000" + ] + }, + "Body": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RXJyb3I+PENvZGU+SW52YWxpZFVyaTwvQ29kZT48TWVzc2FnZT5UaGUgcmVxdWVzdGVkIFVSSSBkb2VzIG5vdCByZXByZXNlbnQgYW55IHJlc291cmNlIG9uIHRoZSBzZXJ2ZXIuClJlcXVlc3RJZDoyNDQxYjY3Zi1lMDFlLTAwNTUtMjA1OS01OTA4YTkwMDAwMDAKVGltZToyMDI0LTAyLTA3VDAwOjA2OjE1LjM5MDY3NjVaPC9NZXNzYWdlPjxVcmlQYXRoPmh0dHBzOi8vZ29jbG91ZGJsb2J0ZXN0cy5ibG9iLmNvcmUud2luZG93cy5uZXQvZ28tY2xvdWQtYnVja2V0LzwvVXJpUGF0aD48L0Vycm9yPg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay new file mode 100644 index 000000000..a231b31ab --- /dev/null +++ b/go-cloud/blob/azureblob/testdata/TestConformance/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay @@ -0,0 +1,361 @@ +{ + "Initial": "AQAAAA7dVMCMHDzHRAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "\u003cBlock(l|L)ist\u003e\u003cLatest\u003e.*\u003c/Latest\u003e\u003c/Block(l|L)ist\u003e" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^X-Ms-Version$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^blockid$" + ], + "RemoveParams": [ + "^se$", + "^sig$", + "^st$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "fdeec03d70573910", + "Request": { + "Method": "PUT", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "6354" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Blob-Cache-Control": [ + "" + ], + "X-Ms-Blob-Content-Disposition": [ + "" + ], + "X-Ms-Blob-Content-Encoding": [ + "" + ], + "X-Ms-Blob-Content-Language": [ + "" + ], + "X-Ms-Blob-Content-Type": [ + "application/json" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + ] + }, + "Response": { + "StatusCode": 201, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Md5": [ + "D2p8n/PT13C49/oZwq4Z0A==" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Etag": [ + "\"0x8DC2770A6A58FE9\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Content-Crc64": [ + "h/FDiq2zgEw=" + ], + "X-Ms-Request-Id": [ + "fbc0ab6d-301e-0056-4459-59e9cd000000" + ], + "X-Ms-Request-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "13fc0e5ed8fa5204", + "Request": { + "Method": "GET", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "6354" + ], + "Content-Md5": [ + "D2p8n/PT13C49/oZwq4Z0A==" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Etag": [ + "\"0x8DC2770A6A58FE9\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "fbc0ab90-301e-0056-5259-59e9cd000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "1cb1bfa003ff24c9", + "Request": { + "Method": "HEAD", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Disposition": [ + "" + ], + "Content-Length": [ + "6354" + ], + "Content-Md5": [ + "D2p8n/PT13C49/oZwq4Z0A==" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Etag": [ + "\"0x8DC2770A6A58FE9\"" + ], + "Last-Modified": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Access-Tier": [ + "Hot" + ], + "X-Ms-Access-Tier-Inferred": [ + "true" + ], + "X-Ms-Blob-Type": [ + "BlockBlob" + ], + "X-Ms-Creation-Time": [ + "Wed, 07 Feb 2024 00:06:36 GMT" + ], + "X-Ms-Lease-State": [ + "available" + ], + "X-Ms-Lease-Status": [ + "unlocked" + ], + "X-Ms-Request-Id": [ + "fbc0aba3-301e-0056-5a59-59e9cd000000" + ], + "X-Ms-Server-Encrypted": [ + "true" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + }, + { + "ID": "76ccd4f096f58709", + "Request": { + "Method": "DELETE", + "URL": "https://gocloudblobtests.blob.core.windows.net/go-cloud-bucket/blob-for-reading", + "Header": { + "Accept": [ + "application/xml" + ], + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Ms-Date": [ + "CLEARED" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 202, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Wed, 07 Feb 2024 00:06:35 GMT" + ], + "Server": [ + "Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" + ], + "X-Ms-Delete-Type-Permanent": [ + "true" + ], + "X-Ms-Request-Id": [ + "fbc0abb0-301e-0056-6159-59e9cd000000" + ], + "X-Ms-Version": [ + "CLEARED" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/blob.go b/go-cloud/blob/blob.go new file mode 100644 index 000000000..a108c915d --- /dev/null +++ b/go-cloud/blob/blob.go @@ -0,0 +1,1581 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 blob provides an easy and portable way to interact with blobs +// within a storage location. Subpackages contain driver implementations of +// blob for supported services. +// +// See https://gocloud.dev/howto/blob/ for a detailed how-to guide. +// +// *blob.Bucket implements io/fs.FS and io/fs.SubFS, so it can be used with +// functions in that package. +// +// # Errors +// +// The errors returned from this package can be inspected in several ways: +// +// The Code function from gocloud.dev/gcerrors will return an error code, also +// defined in that package, when invoked on an error. +// +// The Bucket.ErrorAs method can retrieve the driver error underlying the returned +// error. +// +// # OpenTelemetry Integration +// +// OpenTelemetry supports tracing, metrics, and logs collection for multiple languages and +// backend providers. See https://opentelemetry.io. +// +// This API collects OpenTelemetry traces and metrics for the following methods: +// - Attributes +// - Copy +// - Delete +// - ListPage +// - NewRangeReader, from creation until the call to Close. (NewReader and ReadAll +// are included because they call NewRangeReader.) +// - NewWriter, from creation until the call to Close. +// +// All trace and metric names begin with the package import path. +// The traces add the method name. +// For example, "gocloud.dev/blob/Attributes". +// The metrics are "completed_calls", a count of completed method calls by driver, +// method and status (error code); and "latency", a distribution of method latency +// by driver and method. +// For example, "gocloud.dev/blob/latency". +// +// It also collects the following metrics: +// - gocloud.dev/blob/bytes_read: the total number of bytes read, by driver. +// - gocloud.dev/blob/bytes_written: the total number of bytes written, by driver. +// +// To enable trace collection in your application, see the documentation at +// https://opentelemetry.io/docs/instrumentation/go/getting-started/. +// To enable metric collection in your application, see the documentation at +// https://opentelemetry.io/docs/instrumentation/go/manual/. +package blob // import "gocloud.dev/blob" + +import ( + "bytes" + "context" + "crypto/md5" + "fmt" + "hash" + "io" + "log" + "mime" + "net/http" + "net/url" + "runtime" + "strings" + "sync" + "time" + "unicode/utf8" + + "go.opentelemetry.io/otel/metric" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/openurl" + gcdkotel "github.com/DataDog/iceberg-go/go-cloud/internal/otel" +) + +// Ensure that Reader implements io.ReadSeekCloser. +var _ = io.ReadSeekCloser(&Reader{}) + +// Reader reads bytes from a blob. +// It implements io.ReadSeekCloser, and must be closed after +// reads are finished. +type Reader struct { + b driver.Bucket + r driver.Reader + key string + ctx context.Context // Used to recreate r after Seeks + dopts *driver.ReaderOptions // " + baseOffset int64 // The base offset provided to NewRangeReader. + baseLength int64 // The length provided to NewRangeReader (may be negative). + relativeOffset int64 // Current offset (relative to baseOffset). + savedOffset int64 // Last relativeOffset for r, saved after relativeOffset is changed in Seek, or -1 if no Seek. + end func(error) // Called at Close to finish trace and metric collection. + // for metric collection; + bytesReadCounter metric.Int64Counter + bytesRead int + closed bool +} + +// Read implements io.Reader (https://golang.org/pkg/io/#Reader). +func (r *Reader) Read(p []byte) (int, error) { + if r.savedOffset != -1 { + // We've done one or more Seeks since the last read. We may have + // to recreate the Reader. + // + // Note that remembering the savedOffset and lazily resetting the + // reader like this allows the caller to Seek, then Seek again back, + // to the original offset, without having to recreate the reader. + // We only have to recreate the reader if we actually read after a Seek. + // This is an important optimization because it's common to Seek + // to (SeekEnd, 0) and use the return value to determine the size + // of the data, then Seek back to (SeekStart, 0). + saved := r.savedOffset + if r.relativeOffset == saved { + // Nope! We're at the same place we left off. + r.savedOffset = -1 + } else { + // Yep! We've changed the offset. Recreate the reader. + length := r.baseLength + if length >= 0 { + length -= r.relativeOffset + if length < 0 { + // Shouldn't happen based on checks in Seek. + return 0, gcerr.Newf(gcerr.Internal, nil, "blob: invalid Seek (base length %d, relative offset %d)", r.baseLength, r.relativeOffset) + } + } + newR, err := r.b.NewRangeReader(r.ctx, r.key, r.baseOffset+r.relativeOffset, length, r.dopts) + if err != nil { + return 0, wrapError(r.b, err, r.key) + } + _ = r.r.Close() + r.savedOffset = -1 + r.r = newR + } + } + n, err := r.r.Read(p) + r.bytesRead += n + r.relativeOffset += int64(n) + return n, wrapError(r.b, err, r.key) +} + +// Seek implements io.Seeker (https://golang.org/pkg/io/#Seeker). +func (r *Reader) Seek(offset int64, whence int) (int64, error) { + if r.savedOffset == -1 { + // Save the current offset for our reader. If the Seek changes the + // offset, and then we try to read, we'll need to recreate the reader. + // See comment above in Read for why we do it lazily. + r.savedOffset = r.relativeOffset + } + // The maximum relative offset is the minimum of: + // 1. The actual size of the blob, minus our initial baseOffset. + // 2. The length provided to NewRangeReader (if it was non-negative). + maxRelativeOffset := r.Size() - r.baseOffset + if r.baseLength >= 0 && r.baseLength < maxRelativeOffset { + maxRelativeOffset = r.baseLength + } + switch whence { + case io.SeekStart: + r.relativeOffset = offset + case io.SeekCurrent: + r.relativeOffset += offset + case io.SeekEnd: + r.relativeOffset = maxRelativeOffset + offset + } + if r.relativeOffset < 0 { + // "Seeking to an offset before the start of the file is an error." + invalidOffset := r.relativeOffset + r.relativeOffset = 0 + return 0, fmt.Errorf("Seek resulted in invalid offset %d, using 0", invalidOffset) + } + if r.relativeOffset > maxRelativeOffset { + // "Seeking to any positive offset is legal, but the behavior of subsequent + // I/O operations on the underlying object is implementation-dependent." + // We'll choose to set the offset to the EOF. + log.Printf("blob.Reader.Seek set an offset after EOF (base offset/length from NewRangeReader %d, %d; actual blob size %d; relative offset %d -> absolute offset %d).", r.baseOffset, r.baseLength, r.Size(), r.relativeOffset, r.baseOffset+r.relativeOffset) + r.relativeOffset = maxRelativeOffset + } + return r.relativeOffset, nil +} + +// Close implements io.Closer (https://golang.org/pkg/io/#Closer). +func (r *Reader) Close() error { + r.closed = true + err := wrapError(r.b, r.r.Close(), r.key) + r.end(err) + // Emit only on close to avoid an allocation on each call to Read(). + // Record bytes read metric with OpenTelemetry. + if r.bytesReadCounter != nil && r.bytesRead > 0 { + r.bytesReadCounter.Add( + r.ctx, + int64(r.bytesRead)) + } + return err +} + +// ContentType returns the MIME type of the blob. +func (r *Reader) ContentType() string { + return r.r.Attributes().ContentType +} + +// ModTime returns the time the blob was last modified. +func (r *Reader) ModTime() time.Time { + return r.r.Attributes().ModTime +} + +// Size returns the size of the blob content in bytes. +func (r *Reader) Size() int64 { + return r.r.Attributes().Size +} + +// As converts i to driver-specific types. +// See https://gocloud.dev/concepts/as/ for background information, the "As" +// examples in this package for examples, and the driver package +// documentation for the specific types supported for that driver. +func (r *Reader) As(i any) bool { + return r.r.As(i) +} + +// WriteTo reads from r and writes to w until there's no more data or +// an error occurs. +// The return value is the number of bytes written to w. +// +// It implements the io.WriterTo interface. +func (r *Reader) WriteTo(w io.Writer) (int64, error) { + // If the writer has a ReaderFrom method, use it to do the copy. + // Don't do this for our own *Writer to avoid infinite recursion. + // Avoids an allocation and a copy. + switch w.(type) { + case *Writer: + default: + if rf, ok := w.(io.ReaderFrom); ok { + n, err := rf.ReadFrom(r) + return n, err + } + } + + _, nw, err := readFromWriteTo(r, w) + return nw, err +} + +// downloadAndClose is similar to WriteTo, but ensures it's the only read. +// This pattern is more optimal for some drivers. +func (r *Reader) downloadAndClose(w io.Writer) (err error) { + if r.bytesRead != 0 { + // Shouldn't happen. + return gcerr.Newf(gcerr.Internal, nil, "blob: downloadAndClose isn't the first read") + } + driverDownloader, ok := r.r.(driver.Downloader) + if ok { + err = driverDownloader.Download(w) + } else { + _, err = r.WriteTo(w) + } + cerr := r.Close() + if err == nil && cerr != nil { + err = cerr + } + return err +} + +// readFromWriteTo is a helper for ReadFrom and WriteTo. +// It reads data from r and writes to w, until EOF or a read/write error. +// It returns the number of bytes read from r and the number of bytes +// written to w. +func readFromWriteTo(r io.Reader, w io.Writer) (int64, int64, error) { + // Note: can't use io.Copy because it will try to use r.WriteTo + // or w.WriteTo, which is recursive in this context. + buf := make([]byte, 1024*1024) + var totalRead, totalWritten int64 + for { + numRead, rerr := r.Read(buf) + if numRead > 0 { + totalRead += int64(numRead) + numWritten, werr := w.Write(buf[0:numRead]) + totalWritten += int64(numWritten) + if werr != nil { + return totalRead, totalWritten, werr + } + } + if rerr == io.EOF { + // Done! + return totalRead, totalWritten, nil + } + if rerr != nil { + return totalRead, totalWritten, rerr + } + } +} + +// Attributes contains attributes about a blob. +type Attributes struct { + // CacheControl specifies caching attributes that services may use + // when serving the blob. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control + CacheControl string + // ContentDisposition specifies whether the blob content is expected to be + // displayed inline or as an attachment. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition + ContentDisposition string + // ContentEncoding specifies the encoding used for the blob's content, if any. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding + ContentEncoding string + // ContentLanguage specifies the language used in the blob's content, if any. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language + ContentLanguage string + // ContentType is the MIME type of the blob. It will not be empty. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type + ContentType string + // Metadata holds key/value pairs associated with the blob. + // Keys are guaranteed to be in lowercase, even if the backend service + // has case-sensitive keys (although note that Metadata written via + // this package will always be lowercased). If there are duplicate + // case-insensitive keys (e.g., "foo" and "FOO"), only one value + // will be kept, and it is undefined which one. + Metadata map[string]string + // CreateTime is the time the blob was created, if available. If not available, + // CreateTime will be the zero time. + CreateTime time.Time + // ModTime is the time the blob was last modified. + ModTime time.Time + // Size is the size of the blob's content in bytes. + Size int64 + // MD5 is an MD5 hash of the blob contents or nil if not available. + MD5 []byte + // ETag for the blob; see https://en.wikipedia.org/wiki/HTTP_ETag. + ETag string + + asFunc func(any) bool +} + +// As converts i to driver-specific types. +// See https://gocloud.dev/concepts/as/ for background information, the "As" +// examples in this package for examples, and the driver package +// documentation for the specific types supported for that driver. +func (a *Attributes) As(i any) bool { + if a.asFunc == nil { + return false + } + return a.asFunc(i) +} + +// Writer writes bytes to a blob. +// +// It implements io.WriteCloser (https://golang.org/pkg/io/#Closer), and must be +// closed after all writes are done. +type Writer struct { + b driver.Bucket + w driver.Writer + key string + end func(err error) // called at Close to finish trace and metric collection + cancel func() // cancels the ctx provided to NewTypedWriter if contentMD5 verification fails + contentMD5 []byte + md5hash hash.Hash + + // Metric collection fields. + bytesWrittenCounter metric.Int64Counter + bytesWritten int + closed bool + + // These fields are non-zero values only when w is nil (not yet created). + // + // A ctx is stored in the Writer since we need to pass it into NewTypedWriter + // when we finish detecting the content type of the blob and create the + // underlying driver.Writer. This step happens inside Write or Close and + // neither of them take a context.Context as an argument. + // + // All 3 fields are only initialized when we create the Writer without + // setting the w field, and are reset to zero values after w is created. + ctx context.Context + opts *driver.WriterOptions + buf *bytes.Buffer +} + +// sniffLen is the byte size of Writer.buf used to detect content-type. +const sniffLen = 512 + +// Write implements the io.Writer interface (https://golang.org/pkg/io/#Writer). +// +// Writes may happen asynchronously, so the returned error can be nil +// even if the actual write eventually fails. The write is only guaranteed to +// have succeeded if Close returns no error. +func (w *Writer) Write(p []byte) (int, error) { + if len(w.contentMD5) > 0 { + if _, err := w.md5hash.Write(p); err != nil { + return 0, err + } + } + if w.w != nil { + return w.write(p) + } + + // If w is not yet created due to no content-type being passed in, try to sniff + // the MIME type based on at most 512 bytes of the blob content of p. + + // Detect the content-type directly if the first chunk is at least 512 bytes. + if w.buf.Len() == 0 && len(p) >= sniffLen { + return w.open(p) + } + + // Store p in w.buf and detect the content-type when the size of content in + // w.buf is at least 512 bytes. + n, err := w.buf.Write(p) + if err != nil { + return 0, err + } + if w.buf.Len() >= sniffLen { + // Note that w.open will return the full length of the buffer; we don't want + // to return that as the length of this write since some of them were written in + // previous writes. Instead, we return the n from this write, above. + _, err := w.open(w.buf.Bytes()) + return n, err + } + return n, nil +} + +// Close closes the blob writer. The write operation is not guaranteed to have succeeded until +// Close returns with no error. +// Close may return an error if the context provided to create the Writer is +// canceled or reaches its deadline. +func (w *Writer) Close() (err error) { + w.closed = true + defer func() { + w.end(err) + // Emit only on close to avoid an allocation on each call to Write(). + // Record bytes written metric with OpenTelemetry. + if w.bytesWrittenCounter != nil && w.bytesWritten > 0 { + w.bytesWrittenCounter.Add( + w.ctx, + int64(w.bytesWritten)) + } + }() + if len(w.contentMD5) > 0 { + // Verify the MD5 hash of what was written matches the ContentMD5 provided + // by the user. + md5sum := w.md5hash.Sum(nil) + if !bytes.Equal(md5sum, w.contentMD5) { + // No match! Return an error, but first cancel the context and call the + // driver's Close function to ensure the write is aborted. + w.cancel() + if w.w != nil { + _ = w.w.Close() + } + return gcerr.Newf(gcerr.FailedPrecondition, nil, "blob: the WriterOptions.ContentMD5 you specified (%X) did not match what was written (%X)", w.contentMD5, md5sum) + } + } + + defer w.cancel() + if w.w != nil { + return wrapError(w.b, w.w.Close(), w.key) + } + if _, err := w.open(w.buf.Bytes()); err != nil { + return err + } + return wrapError(w.b, w.w.Close(), w.key) +} + +// open tries to detect the MIME type of p and write it to the blob. +// The error it returns is wrapped. +func (w *Writer) open(p []byte) (int, error) { + ct := http.DetectContentType(p) + var err error + if w.w, err = w.b.NewTypedWriter(w.ctx, w.key, ct, w.opts); err != nil { + return 0, wrapError(w.b, err, w.key) + } + // Set the 3 fields needed for lazy NewTypedWriter back to zero values + // (see the comment on Writer). + w.buf = nil + w.ctx = nil + w.opts = nil + return w.write(p) +} + +func (w *Writer) write(p []byte) (int, error) { + n, err := w.w.Write(p) + w.bytesWritten += n + return n, wrapError(w.b, err, w.key) +} + +// ReadFrom reads from r and writes to w until EOF or error. +// The return value is the number of bytes read from r. +// +// It implements the io.ReaderFrom interface. +func (w *Writer) ReadFrom(r io.Reader) (int64, error) { + // If the reader has a WriteTo method, use it to do the copy. + // Don't do this for our own *Reader to avoid infinite recursion. + // Avoids an allocation and a copy. + switch r.(type) { + case *Reader: + default: + if wt, ok := r.(io.WriterTo); ok { + n, err := wt.WriteTo(w) + return n, err + } + } + + nr, _, err := readFromWriteTo(r, w) + return nr, err +} + +// uploadAndClose is similar to ReadFrom, but ensures it's the only write. +// This pattern is more optimal for some drivers. +func (w *Writer) uploadAndClose(r io.Reader) (err error) { + if w.bytesWritten != 0 { + // Shouldn't happen. + return gcerr.Newf(gcerr.Internal, nil, "blob: uploadAndClose must be the first write") + } + // When ContentMD5 is being checked, we can't use Upload. + if len(w.contentMD5) > 0 { + _, err = w.ReadFrom(r) + } else { + driverUploader, ok := w.w.(driver.Uploader) + if ok { + err = driverUploader.Upload(r) + } else { + _, err = w.ReadFrom(r) + } + } + cerr := w.Close() + if err == nil && cerr != nil { + err = cerr + } + return err +} + +// ListOptions sets options for listing blobs via Bucket.List. +type ListOptions struct { + // Prefix indicates that only blobs with a key starting with this prefix + // should be returned. + Prefix string + // Delimiter sets the delimiter used to define a hierarchical namespace, + // like a filesystem with "directories". It is highly recommended that you + // use "" or "/" as the Delimiter. Other values should work through this API, + // but service UIs generally assume "/". + // + // An empty delimiter means that the bucket is treated as a single flat + // namespace. + // + // A non-empty delimiter means that any result with the delimiter in its key + // after Prefix is stripped will be returned with ListObject.IsDir = true, + // ListObject.Key truncated after the delimiter, and zero values for other + // ListObject fields. These results represent "directories". Multiple results + // in a "directory" are returned as a single result. + Delimiter string + + // BeforeList is a callback that will be called before each call to the + // the underlying service's list functionality. + // asFunc converts its argument to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + BeforeList func(asFunc func(any) bool) error +} + +// ListIterator iterates over List results. +type ListIterator struct { + b *Bucket + opts *driver.ListOptions + page *driver.ListPage + nextIdx int +} + +// Next returns a *ListObject for the next blob. It returns (nil, io.EOF) if +// there are no more. +func (i *ListIterator) Next(ctx context.Context) (*ListObject, error) { + if i.page != nil { + // We've already got a page of results. + if i.nextIdx < len(i.page.Objects) { + // Next object is in the page; return it. + dobj := i.page.Objects[i.nextIdx] + i.nextIdx++ + return &ListObject{ + Key: dobj.Key, + ModTime: dobj.ModTime, + Size: dobj.Size, + MD5: dobj.MD5, + IsDir: dobj.IsDir, + asFunc: dobj.AsFunc, + }, nil + } + if len(i.page.NextPageToken) == 0 { + // Done with current page, and there are no more; return io.EOF. + return nil, io.EOF + } + // We need to load the next page. + i.opts.PageToken = i.page.NextPageToken + } + i.b.mu.RLock() + defer i.b.mu.RUnlock() + if i.b.closed { + return nil, errClosed + } + // Loading a new page. + p, err := i.b.b.ListPaged(ctx, i.opts) + if err != nil { + return nil, wrapError(i.b.b, err, "") + } + i.page = p + i.nextIdx = 0 + return i.Next(ctx) +} + +// ListObject represents a single blob returned from List. +type ListObject struct { + // Key is the key for this blob. + Key string + // ModTime is the time the blob was last modified. + ModTime time.Time + // Size is the size of the blob's content in bytes. + Size int64 + // MD5 is an MD5 hash of the blob contents or nil if not available. + MD5 []byte + // IsDir indicates that this result represents a "directory" in the + // hierarchical namespace, ending in ListOptions.Delimiter. Key can be + // passed as ListOptions.Prefix to list items in the "directory". + // Fields other than Key and IsDir will not be set if IsDir is true. + IsDir bool + + asFunc func(any) bool +} + +// As converts i to driver-specific types. +// See https://gocloud.dev/concepts/as/ for background information, the "As" +// examples in this package for examples, and the driver package +// documentation for the specific types supported for that driver. +func (o *ListObject) As(i any) bool { + if o.asFunc == nil { + return false + } + return o.asFunc(i) +} + +// Bucket provides an easy and portable way to interact with blobs +// within a "bucket", including read, write, and list operations. +// To create a Bucket, use constructors found in driver subpackages. +type Bucket struct { + b driver.Bucket + tracer *gcdkotel.Tracer + + bytesReadCounter metric.Int64Counter + bytesWrittenCounter metric.Int64Counter + + // ioFSCallback is set via SetIOFSCallback, which must be + // called before calling various functions implementing interfaces + // from the io/fs package. + ioFSCallback func() (context.Context, *ReaderOptions) + + // mu protects the closed variable. + // Read locks are kept to allow holding a read lock for long-running calls, + // and thereby prevent closing until a call finishes. + mu sync.RWMutex + closed bool +} + +const pkgName = "gocloud.dev/blob" + +var ( + + // OpenTelemetryViews are predefined views for OpenTelemetry metrics. + // The views include counts and latency distributions for API method calls. + // See the explanations at https://opentelemetry.io/docs/specs/otel/metrics/data-model/ for usage. + OpenTelemetryViews = append( + append( + gcdkotel.Views(pkgName), + gcdkotel.CounterView(pkgName, "/bytes_read", "Sum of bytes read from the service.")...), + gcdkotel.CounterView(pkgName, "/bytes_written", "Sum of bytes written to the service.")...) +) + +// NewBucket is intended for use by drivers only. Do not use in application code. +var NewBucket = newBucket + +// newBucket creates a new *Bucket based on a specific driver implementation. +// End users should use subpackages to construct a *Bucket instead of this +// function; see the package documentation for details. +func newBucket(b driver.Bucket) *Bucket { + providerName := gcdkotel.ProviderName(b) + + return &Bucket{ + b: b, + ioFSCallback: func() (context.Context, *ReaderOptions) { return context.Background(), nil }, + tracer: gcdkotel.NewTracer(pkgName, providerName), + bytesReadCounter: gcdkotel.BytesMeasure(pkgName, providerName, "/bytes_read", "Total bytes read from blob storage"), + bytesWrittenCounter: gcdkotel.BytesMeasure(pkgName, providerName, "/bytes_written", "Total bytes written to blob storage"), + } +} + +// As converts i to driver-specific types. +// See https://gocloud.dev/concepts/as/ for background information, the "As" +// examples in this package for examples, and the driver package +// documentation for the specific types supported for that driver. +func (b *Bucket) As(i any) bool { + if i == nil { + return false + } + return b.b.As(i) +} + +// ErrorAs converts err to driver-specific types. +// ErrorAs panics if i is nil or not a pointer. +// ErrorAs returns false if err == nil. +// See https://gocloud.dev/concepts/as/ for background information. +func (b *Bucket) ErrorAs(err error, i any) bool { + return gcerr.ErrorAs(err, i, b.b.ErrorAs) +} + +// ReadAll is a shortcut for creating a Reader via NewReader with nil +// ReaderOptions, and reading the entire blob. +// +// Using Download may be more efficient. +func (b *Bucket) ReadAll(ctx context.Context, key string) (_ []byte, err error) { + b.mu.RLock() + defer b.mu.RUnlock() + if b.closed { + return nil, errClosed + } + r, err := b.NewReader(ctx, key, nil) + if err != nil { + return nil, err + } + defer func() { _ = r.Close() }() + return io.ReadAll(r) +} + +// Download writes the content of a blob into an io.Writer w. +func (b *Bucket) Download(ctx context.Context, key string, w io.Writer, opts *ReaderOptions) error { + b.mu.RLock() + defer b.mu.RUnlock() + if b.closed { + return errClosed + } + r, err := b.NewReader(ctx, key, opts) + if err != nil { + return err + } + return r.downloadAndClose(w) +} + +// List returns a ListIterator that can be used to iterate over blobs in a +// bucket, in lexicographical order of UTF-8 encoded keys. The underlying +// implementation fetches results in pages. +// +// A nil ListOptions is treated the same as the zero value. +// +// List is not guaranteed to include all recently-written blobs; +// some services are only eventually consistent. +func (b *Bucket) List(opts *ListOptions) *ListIterator { + if opts == nil { + opts = &ListOptions{} + } + dopts := &driver.ListOptions{ + Prefix: opts.Prefix, + Delimiter: opts.Delimiter, + BeforeList: opts.BeforeList, + } + return &ListIterator{b: b, opts: dopts} +} + +// FirstPageToken is the pageToken to pass to ListPage to retrieve the first page of results. +var FirstPageToken = []byte("first page") + +// ListPage returns a page of ListObject results for blobs in a bucket, in lexicographical +// order of UTF-8 encoded keys. +// +// To fetch the first page, pass FirstPageToken as the pageToken. For subsequent pages, pass +// the pageToken returned from a previous call to ListPage. +// It is not possible to "skip ahead" pages. +// +// Each call will return pageSize results, unless there are not enough blobs to fill the +// page, in which case it will return fewer results (possibly 0). +// +// If there are no more blobs available, ListPage will return an empty pageToken. Note that +// this may happen regardless of the number of returned results -- the last page might have +// 0 results (i.e., if the last item was deleted), pageSize results, or anything in between. +// +// Calling ListPage with an empty pageToken will immediately return io.EOF. When looping +// over pages, callers can either check for an empty pageToken, or they can make one more +// call and check for io.EOF. +// +// The underlying implementation fetches results in pages, but one call to ListPage may +// require multiple page fetches (and therefore, multiple calls to the BeforeList callback). +// +// A nil ListOptions is treated the same as the zero value. +// +// ListPage is not guaranteed to include all recently-written blobs; +// some services are only eventually consistent. +func (b *Bucket) ListPage(ctx context.Context, pageToken []byte, pageSize int, opts *ListOptions) (retval []*ListObject, nextPageToken []byte, err error) { + if opts == nil { + opts = &ListOptions{} + } + if pageSize <= 0 { + return nil, nil, gcerr.Newf(gcerr.InvalidArgument, nil, "blob: pageSize must be > 0") + } + + // Nil pageToken means no more results. + if len(pageToken) == 0 { + return nil, nil, io.EOF + } + + // FirstPageToken fetches the first page. Drivers use nil. + // The public API doesn't use nil for the first page because it would be too easy to + // keep fetching forever (since the last page return nil for the next pageToken). + if bytes.Equal(pageToken, FirstPageToken) { + pageToken = nil + } + b.mu.RLock() + defer b.mu.RUnlock() + if b.closed { + return nil, nil, errClosed + } + + ctx, span := b.tracer.Start(ctx, "ListPage") + defer func() { b.tracer.End(ctx, span, err) }() + + dopts := &driver.ListOptions{ + Prefix: opts.Prefix, + Delimiter: opts.Delimiter, + BeforeList: opts.BeforeList, + PageToken: pageToken, + PageSize: pageSize, + } + retval = make([]*ListObject, 0, pageSize) + for len(retval) < pageSize { + p, err := b.b.ListPaged(ctx, dopts) + if err != nil { + return nil, nil, wrapError(b.b, err, "") + } + for _, dobj := range p.Objects { + retval = append(retval, &ListObject{ + Key: dobj.Key, + ModTime: dobj.ModTime, + Size: dobj.Size, + MD5: dobj.MD5, + IsDir: dobj.IsDir, + asFunc: dobj.AsFunc, + }) + } + // ListPaged may return fewer results than pageSize. If there are more results + // available, signalled by non-empty p.NextPageToken, try to fetch the remainder + // of the page. + // It does not work to ask for more results than we need, because then we'd have + // a NextPageToken on a non-page boundary. + dopts.PageSize = pageSize - len(retval) + dopts.PageToken = p.NextPageToken + if len(dopts.PageToken) == 0 { + dopts.PageToken = nil + break + } + } + return retval, dopts.PageToken, nil +} + +// IsAccessible returns true if the bucket is accessible, false otherwise. +// It is a shortcut for calling ListPage and checking if it returns an error +// with code gcerrors.NotFound. +func (b *Bucket) IsAccessible(ctx context.Context) (bool, error) { + _, _, err := b.ListPage(ctx, FirstPageToken, 1, nil) + if err == nil { + return true, nil + } + if gcerrors.Code(err) == gcerrors.NotFound { + return false, nil + } + return false, err +} + +// Exists returns true if a blob exists at key, false if it does not exist, or +// an error. +// It is a shortcut for calling Attributes and checking if it returns an error +// with code gcerrors.NotFound. +func (b *Bucket) Exists(ctx context.Context, key string) (bool, error) { + _, err := b.Attributes(ctx, key) + if err == nil { + return true, nil + } + if gcerrors.Code(err) == gcerrors.NotFound { + return false, nil + } + return false, err +} + +// Attributes returns attributes for the blob stored at key. +// +// If the blob does not exist, Attributes returns an error for which +// gcerrors.Code will return gcerrors.NotFound. +func (b *Bucket) Attributes(ctx context.Context, key string) (_ *Attributes, err error) { + if !utf8.ValidString(key) { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "blob: Attributes key must be a valid UTF-8 string: %q", key) + } + + b.mu.RLock() + defer b.mu.RUnlock() + if b.closed { + return nil, errClosed + } + ctx, span := b.tracer.Start(ctx, "Attributes") + defer func() { b.tracer.End(ctx, span, err) }() + + a, err := b.b.Attributes(ctx, key) + if err != nil { + return nil, wrapError(b.b, err, key) + } + var md map[string]string + if len(a.Metadata) > 0 { + // Services are inconsistent, but at least some treat keys + // as case-insensitive. To make the behavior consistent, we + // force-lowercase them when writing and reading. + md = make(map[string]string, len(a.Metadata)) + for k, v := range a.Metadata { + md[strings.ToLower(k)] = v + } + } + return &Attributes{ + CacheControl: a.CacheControl, + ContentDisposition: a.ContentDisposition, + ContentEncoding: a.ContentEncoding, + ContentLanguage: a.ContentLanguage, + ContentType: a.ContentType, + Metadata: md, + CreateTime: a.CreateTime, + ModTime: a.ModTime, + Size: a.Size, + MD5: a.MD5, + ETag: a.ETag, + asFunc: a.AsFunc, + }, nil +} + +// NewReader is a shortcut for NewRangeReader with offset=0 and length=-1. +func (b *Bucket) NewReader(ctx context.Context, key string, opts *ReaderOptions) (*Reader, error) { + return b.newRangeReader(ctx, key, 0, -1, opts) +} + +// NewRangeReader returns a Reader to read content from the blob stored at key. +// It reads at most length bytes starting at offset (>= 0). +// If length is negative, it will read till the end of the blob. +// +// For the purposes of Seek, the returned Reader will start at offset and +// end at the minimum of the actual end of the blob or (if length > 0) offset + length. +// +// Note that ctx is used for all reads performed during the lifetime of the reader. +// +// If the blob does not exist, NewRangeReader returns an error for which +// gcerrors.Code will return gcerrors.NotFound. Exists is a lighter-weight way +// to check for existence. +// +// A nil ReaderOptions is treated the same as the zero value. +// +// The caller must call Close on the returned Reader when done reading. +func (b *Bucket) NewRangeReader(ctx context.Context, key string, offset, length int64, opts *ReaderOptions) (_ *Reader, err error) { + return b.newRangeReader(ctx, key, offset, length, opts) +} + +func (b *Bucket) newRangeReader(ctx context.Context, key string, offset, length int64, opts *ReaderOptions) (_ *Reader, err error) { + b.mu.RLock() + defer b.mu.RUnlock() + if b.closed { + return nil, errClosed + } + if offset < 0 { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "blob: NewRangeReader offset must be non-negative (%d)", offset) + } + if !utf8.ValidString(key) { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "blob: NewRangeReader key must be a valid UTF-8 string: %q", key) + } + if opts == nil { + opts = &ReaderOptions{} + } + dopts := &driver.ReaderOptions{ + BeforeRead: opts.BeforeRead, + } + ctx, span := b.tracer.Start(ctx, "NewRangeReader") + defer func() { + // If err == nil, we handed the end closure off to the returned *Reader; it + // will be called when the Reader is Closed. + if err != nil { + b.tracer.End(ctx, span, err) + } + }() + var dr driver.Reader + dr, err = b.b.NewRangeReader(ctx, key, offset, length, dopts) + if err != nil { + return nil, wrapError(b.b, err, key) + } + end := func(err error) { b.tracer.End(ctx, span, err) } + r := &Reader{ + b: b.b, + r: dr, + key: key, + ctx: ctx, + dopts: dopts, + baseOffset: offset, + baseLength: length, + savedOffset: -1, + end: end, + bytesReadCounter: b.bytesReadCounter, + } + _, file, lineno, ok := runtime.Caller(2) + runtime.SetFinalizer(r, func(r *Reader) { + if !r.closed { + var caller string + if ok { + caller = fmt.Sprintf(" (%s:%d)", file, lineno) + } + log.Printf("A blob.Reader reading from %q was never closed%s", key, caller) + } + }) + return r, nil +} + +// WriteAll is a shortcut for creating a Writer via NewWriter and writing p. +// +// If opts.ContentMD5 is not set, WriteAll will compute the MD5 of p and use it +// as the ContentMD5 option for the Writer it creates. +// +// Using Upload may be more efficient. +func (b *Bucket) WriteAll(ctx context.Context, key string, p []byte, opts *WriterOptions) (err error) { + realOpts := new(WriterOptions) + if opts != nil { + *realOpts = *opts + } + if len(realOpts.ContentMD5) == 0 { + sum := md5.Sum(p) + realOpts.ContentMD5 = sum[:] + } + w, err := b.NewWriter(ctx, key, realOpts) + if err != nil { + return err + } + if _, err := w.Write(p); err != nil { + _ = w.Close() + return err + } + return w.Close() +} + +// Upload reads from an io.Reader r and writes into a blob. +// +// opts.ContentType is required. +func (b *Bucket) Upload(ctx context.Context, key string, r io.Reader, opts *WriterOptions) error { + if opts == nil || opts.ContentType == "" { + return gcerr.Newf(gcerr.InvalidArgument, nil, "blob: Upload requires WriterOptions.ContentType") + } + w, err := b.NewWriter(ctx, key, opts) + if err != nil { + return err + } + return w.uploadAndClose(r) +} + +// NewWriter returns a Writer that writes to the blob stored at key. +// A nil WriterOptions is treated the same as the zero value. +// +// If a blob with this key already exists, it will be replaced. +// The blob being written is not guaranteed to be readable until Close +// has been called; until then, any previous blob will still be readable. +// Even after Close is called, newly written blobs are not guaranteed to be +// returned from List; some services are only eventually consistent. +// +// The returned Writer will store ctx for later use in Write and/or Close. +// To abort a write, cancel ctx; otherwise, it must remain open until +// Close is called. +// +// The caller must call Close on the returned Writer, even if the write is +// aborted. +func (b *Bucket) NewWriter(ctx context.Context, key string, opts *WriterOptions) (_ *Writer, err error) { + if !utf8.ValidString(key) { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "blob: NewWriter key must be a valid UTF-8 string: %q", key) + } + if opts == nil { + opts = &WriterOptions{} + } + dopts := &driver.WriterOptions{ + CacheControl: opts.CacheControl, + ContentDisposition: opts.ContentDisposition, + ContentEncoding: opts.ContentEncoding, + ContentLanguage: opts.ContentLanguage, + ContentMD5: opts.ContentMD5, + BufferSize: opts.BufferSize, + MaxConcurrency: opts.MaxConcurrency, + BeforeWrite: opts.BeforeWrite, + DisableContentTypeDetection: opts.DisableContentTypeDetection, + IfNotExist: opts.IfNotExist, + } + if len(opts.Metadata) > 0 { + // Services are inconsistent, but at least some treat keys + // as case-insensitive. To make the behavior consistent, we + // force-lowercase them when writing and reading. + md := make(map[string]string, len(opts.Metadata)) + for k, v := range opts.Metadata { + if k == "" { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "blob: WriterOptions.Metadata keys may not be empty strings") + } + if !utf8.ValidString(k) { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "blob: WriterOptions.Metadata keys must be valid UTF-8 strings: %q", k) + } + if !utf8.ValidString(v) { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "blob: WriterOptions.Metadata values must be valid UTF-8 strings: %q", v) + } + lowerK := strings.ToLower(k) + if _, found := md[lowerK]; found { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "blob: WriterOptions.Metadata has a duplicate case-insensitive metadata key: %q", lowerK) + } + md[lowerK] = v + } + dopts.Metadata = md + } + b.mu.RLock() + defer b.mu.RUnlock() + if b.closed { + return nil, errClosed + } + ctx, cancel := context.WithCancel(ctx) + ctx, span := b.tracer.Start(ctx, "NewWriter") + end := func(err error) { b.tracer.End(ctx, span, err) } + defer func() { + if err != nil { + end(err) + } + }() + + w := &Writer{ + b: b.b, + end: end, + cancel: cancel, + key: key, + contentMD5: opts.ContentMD5, + md5hash: md5.New(), + bytesWrittenCounter: b.bytesWrittenCounter, + } + if opts.ContentType != "" || opts.DisableContentTypeDetection { + var ct string + if opts.ContentType != "" { + t, p, err := mime.ParseMediaType(opts.ContentType) + if err != nil { + cancel() + return nil, err + } + ct = mime.FormatMediaType(t, p) + } + dw, err := b.b.NewTypedWriter(ctx, key, ct, dopts) + if err != nil { + cancel() + return nil, wrapError(b.b, err, key) + } + w.w = dw + } else { + // Save the fields needed to called NewTypedWriter later, once we've gotten + // sniffLen bytes; see the comment on Writer. + w.ctx = ctx + w.opts = dopts + w.buf = bytes.NewBuffer([]byte{}) + } + _, file, lineno, ok := runtime.Caller(1) + runtime.SetFinalizer(w, func(w *Writer) { + if !w.closed { + var caller string + if ok { + caller = fmt.Sprintf(" (%s:%d)", file, lineno) + } + log.Printf("A blob.Writer writing to %q was never closed%s", key, caller) + } + }) + return w, nil +} + +// Copy the blob stored at srcKey to dstKey. +// A nil CopyOptions is treated the same as the zero value. +// +// If the source blob does not exist, Copy returns an error for which +// gcerrors.Code will return gcerrors.NotFound. +// +// If the destination blob already exists, it is overwritten. +func (b *Bucket) Copy(ctx context.Context, dstKey, srcKey string, opts *CopyOptions) (err error) { + if !utf8.ValidString(srcKey) { + return gcerr.Newf(gcerr.InvalidArgument, nil, "blob: Copy srcKey must be a valid UTF-8 string: %q", srcKey) + } + if !utf8.ValidString(dstKey) { + return gcerr.Newf(gcerr.InvalidArgument, nil, "blob: Copy dstKey must be a valid UTF-8 string: %q", dstKey) + } + if opts == nil { + opts = &CopyOptions{} + } + dopts := &driver.CopyOptions{ + BeforeCopy: opts.BeforeCopy, + } + b.mu.RLock() + defer b.mu.RUnlock() + if b.closed { + return errClosed + } + ctx, span := b.tracer.Start(ctx, "Copy") + defer func() { b.tracer.End(ctx, span, err) }() + return wrapError(b.b, b.b.Copy(ctx, dstKey, srcKey, dopts), fmt.Sprintf("%s -> %s", srcKey, dstKey)) +} + +// Delete deletes the blob stored at key. +// +// If the blob does not exist, Delete returns an error for which +// gcerrors.Code will return gcerrors.NotFound. +func (b *Bucket) Delete(ctx context.Context, key string) (err error) { + if !utf8.ValidString(key) { + return gcerr.Newf(gcerr.InvalidArgument, nil, "blob: Delete key must be a valid UTF-8 string: %q", key) + } + b.mu.RLock() + defer b.mu.RUnlock() + if b.closed { + return errClosed + } + ctx, span := b.tracer.Start(ctx, "Delete") + defer func() { b.tracer.End(ctx, span, err) }() + return wrapError(b.b, b.b.Delete(ctx, key), key) +} + +// SignedURL returns a URL that can be used to GET (default), PUT or DELETE +// the blob for the duration specified in opts.Expiry. +// +// A nil SignedURLOptions is treated the same as the zero value. +// +// It is valid to call SignedURL for a key that does not exist. +// +// If the driver does not support this functionality, SignedURL +// will return an error for which gcerrors.Code will return gcerrors.Unimplemented. +func (b *Bucket) SignedURL(ctx context.Context, key string, opts *SignedURLOptions) (string, error) { + if !utf8.ValidString(key) { + return "", gcerr.Newf(gcerr.InvalidArgument, nil, "blob: SignedURL key must be a valid UTF-8 string: %q", key) + } + dopts := new(driver.SignedURLOptions) + if opts == nil { + opts = new(SignedURLOptions) + } + switch { + case opts.Expiry < 0: + return "", gcerr.Newf(gcerr.InvalidArgument, nil, "blob: SignedURLOptions.Expiry must be >= 0 (%v)", opts.Expiry) + case opts.Expiry == 0: + dopts.Expiry = DefaultSignedURLExpiry + default: + dopts.Expiry = opts.Expiry + } + switch opts.Method { + case "": + dopts.Method = http.MethodGet + case http.MethodGet, http.MethodPut, http.MethodDelete: + dopts.Method = opts.Method + default: + return "", fmt.Errorf("blob: unsupported SignedURLOptions.Method %q", opts.Method) + } + if opts.ContentType != "" && opts.Method != http.MethodPut { + return "", fmt.Errorf("blob: SignedURLOptions.ContentType must be empty for signing a %s URL", opts.Method) + } + if opts.EnforceAbsentContentType && opts.Method != http.MethodPut { + return "", fmt.Errorf("blob: SignedURLOptions.EnforceAbsentContentType must be false for signing a %s URL", opts.Method) + } + dopts.ContentType = opts.ContentType + dopts.EnforceAbsentContentType = opts.EnforceAbsentContentType + dopts.BeforeSign = opts.BeforeSign + b.mu.RLock() + defer b.mu.RUnlock() + if b.closed { + return "", errClosed + } + sURL, err := b.b.SignedURL(ctx, key, dopts) + return sURL, wrapError(b.b, err, key) +} + +// Close releases any resources used for the bucket. +func (b *Bucket) Close() error { + b.mu.Lock() + prev := b.closed + b.closed = true + b.mu.Unlock() + if prev { + return errClosed + } + return wrapError(b.b, b.b.Close(), "") +} + +// DefaultSignedURLExpiry is the default duration for SignedURLOptions.Expiry. +const DefaultSignedURLExpiry = 1 * time.Hour + +// SignedURLOptions sets options for SignedURL. +type SignedURLOptions struct { + // Expiry sets how long the returned URL is valid for. + // Defaults to DefaultSignedURLExpiry. + Expiry time.Duration + + // Method is the HTTP method that can be used on the URL; one of "GET", "PUT", + // or "DELETE". Defaults to "GET". + Method string + + // ContentType specifies the Content-Type HTTP header the user agent is + // permitted to use in the PUT request. It must match exactly. See + // EnforceAbsentContentType for behavior when ContentType is the empty string. + // If a bucket does not implement this verification, then it returns an + // Unimplemented error. + // + // Must be empty for non-PUT requests. + ContentType string + + // If EnforceAbsentContentType is true and ContentType is the empty string, + // then PUTing to the signed URL will fail if the Content-Type header is + // present. Not all buckets support this: ones that do not will return an + // Unimplemented error. + // + // If EnforceAbsentContentType is false and ContentType is the empty string, + // then PUTing without a Content-Type header will succeed, but it is + // implementation-specific whether providing a Content-Type header will fail. + // + // Must be false for non-PUT requests. + EnforceAbsentContentType bool + + // BeforeSign is a callback that will be called before each call to the + // the underlying service's sign functionality. + // asFunc converts its argument to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + BeforeSign func(asFunc func(any) bool) error +} + +// ReaderOptions sets options for NewReader and NewRangeReader. +type ReaderOptions struct { + // BeforeRead is a callback that will be called before + // any data is read (unless NewReader returns an error before then, in which + // case it may not be called at all). + // + // Calling Seek may reset the underlying reader, and result in BeforeRead + // getting called again with a different underlying provider-specific reader.. + // + // asFunc converts its argument to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + BeforeRead func(asFunc func(any) bool) error +} + +// WriterOptions sets options for NewWriter. +type WriterOptions struct { + // BufferSize changes the default size in bytes of the chunks that + // Writer will upload in a single request; larger blobs will be split into + // multiple requests. + // + // This option may be ignored by some drivers. + // + // If 0, the driver will choose a reasonable default. + // + // If the Writer is used to do many small writes concurrently, using a + // smaller BufferSize may reduce memory usage. + BufferSize int + + // MaxConcurrency changes the default concurrency for parts of an upload. + // + // This option may be ignored by some drivers. + // + // If 0, the driver will choose a reasonable default. + MaxConcurrency int + + // CacheControl specifies caching attributes that services may use + // when serving the blob. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control + CacheControl string + + // ContentDisposition specifies whether the blob content is expected to be + // displayed inline or as an attachment. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition + ContentDisposition string + + // ContentEncoding specifies the encoding used for the blob's content, if any. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding + ContentEncoding string + + // ContentLanguage specifies the language used in the blob's content, if any. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language + ContentLanguage string + + // ContentType specifies the MIME type of the blob being written. If not set, + // it will be inferred from the content using the algorithm described at + // http://mimesniff.spec.whatwg.org/. + // Set DisableContentTypeDetection to true to disable the above and force + // the ContentType to stay empty. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type + ContentType string + + // When true, if ContentType is the empty string, it will stay the empty + // string rather than being inferred from the content. + // Note that while the blob will be written with an empty string ContentType, + // most providers will fill one in during reads, so don't expect an empty + // ContentType if you read the blob back. + DisableContentTypeDetection bool + + // ContentMD5 is used as a message integrity check. + // If len(ContentMD5) > 0, the MD5 hash of the bytes written must match + // ContentMD5, or Close will return an error without completing the write. + // https://tools.ietf.org/html/rfc1864 + ContentMD5 []byte + + // Metadata holds key/value strings to be associated with the blob, or nil. + // Keys may not be empty, and are lowercased before being written. + // Duplicate case-insensitive keys (e.g., "foo" and "FOO") will result in + // an error. + Metadata map[string]string + + // BeforeWrite is a callback that will be called exactly once, before + // any data is written (unless NewWriter returns an error, in which case + // it will not be called at all). Note that this is not necessarily during + // or after the first Write call, as drivers may buffer bytes before + // sending an upload request. + // + // asFunc converts its argument to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + BeforeWrite func(asFunc func(any) bool) error + + // IfNotExist is used for conditional writes. When set to 'true', + // if a blob exists for the same key in the bucket, the write + // operation won't succeed and the current blob for the key will + // be left untouched. An error for which gcerrors.Code will return + // gcerrors.PreconditionFailed will be returned by Write or Close. + IfNotExist bool +} + +// CopyOptions sets options for Copy. +type CopyOptions struct { + // BeforeCopy is a callback that will be called before the copy is + // initiated. + // + // asFunc converts its argument to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + BeforeCopy func(asFunc func(any) bool) error +} + +// BucketURLOpener represents types that can open buckets based on a URL. +// The opener must not modify the URL argument. OpenBucketURL must be safe to +// call from multiple goroutines. +// +// This interface is generally implemented by types in driver packages. +type BucketURLOpener interface { + OpenBucketURL(ctx context.Context, u *url.URL) (*Bucket, error) +} + +// URLMux is a URL opener multiplexer. It matches the scheme of the URLs +// against a set of registered schemes and calls the opener that matches the +// URL's scheme. +// See https://gocloud.dev/concepts/urls/ for more information. +// +// The zero value is a multiplexer with no registered schemes. +type URLMux struct { + schemes openurl.SchemeMap +} + +// BucketSchemes returns a sorted slice of the registered Bucket schemes. +func (mux *URLMux) BucketSchemes() []string { return mux.schemes.Schemes() } + +// ValidBucketScheme returns true iff scheme has been registered for Buckets. +func (mux *URLMux) ValidBucketScheme(scheme string) bool { return mux.schemes.ValidScheme(scheme) } + +// RegisterBucket registers the opener with the given scheme. If an opener +// already exists for the scheme, RegisterBucket panics. +func (mux *URLMux) RegisterBucket(scheme string, opener BucketURLOpener) { + mux.schemes.Register("blob", "Bucket", scheme, opener) +} + +// OpenBucket calls OpenBucketURL with the URL parsed from urlstr. +// OpenBucket is safe to call from multiple goroutines. +func (mux *URLMux) OpenBucket(ctx context.Context, urlstr string) (*Bucket, error) { + opener, u, err := mux.schemes.FromString("Bucket", urlstr) + if err != nil { + return nil, err + } + return applyPrefixParam(ctx, opener.(BucketURLOpener), u) +} + +// OpenBucketURL dispatches the URL to the opener that is registered with the +// URL's scheme. OpenBucketURL is safe to call from multiple goroutines. +func (mux *URLMux) OpenBucketURL(ctx context.Context, u *url.URL) (*Bucket, error) { + opener, err := mux.schemes.FromURL("Bucket", u) + if err != nil { + return nil, err + } + return applyPrefixParam(ctx, opener.(BucketURLOpener), u) +} + +func applyPrefixParam(ctx context.Context, opener BucketURLOpener, u *url.URL) (*Bucket, error) { + prefix := u.Query().Get("prefix") + singleKey := u.Query().Get("key") + if prefix != "" || singleKey != "" { + // Make a copy of u with the "prefix" and "key" parameters removed. + urlCopy := *u + q := urlCopy.Query() + q.Del("prefix") + q.Del("key") + urlCopy.RawQuery = q.Encode() + u = &urlCopy + } + bucket, err := opener.OpenBucketURL(ctx, u) + if err != nil { + return nil, err + } + if prefix != "" { + bucket = PrefixedBucket(bucket, prefix) + } + if singleKey != "" { + bucket = SingleKeyBucket(bucket, singleKey) + } + return bucket, nil +} + +var defaultURLMux = new(URLMux) + +// DefaultURLMux returns the URLMux used by OpenBucket. +// +// Driver packages can use this to register their BucketURLOpener on the mux. +func DefaultURLMux() *URLMux { + return defaultURLMux +} + +// OpenBucket opens the bucket identified by the URL given. +// +// See the URLOpener documentation in driver subpackages for +// details on supported URL formats, and https://gocloud.dev/concepts/urls/ +// for more information. +// +// In addition to driver-specific query parameters, OpenBucket supports +// the following query parameters: +// +// - prefix: wraps the resulting Bucket using PrefixedBucket with the +// given prefix. +// - key: wraps the resulting Bucket using SingleKeyBucket with the +// given key. +func OpenBucket(ctx context.Context, urlstr string) (*Bucket, error) { + return defaultURLMux.OpenBucket(ctx, urlstr) +} + +func wrapError(b driver.Bucket, err error, key string) error { + if err == nil { + return nil + } + if gcerr.DoNotWrap(err) { + return err + } + msg := "blob" + if key != "" { + msg += fmt.Sprintf(" (key %q)", key) + } + code := gcerrors.Code(err) + if code == gcerrors.Unknown { + code = b.ErrorCode(err) + } + return gcerr.New(code, err, 2, msg) +} + +var errClosed = gcerr.Newf(gcerr.FailedPrecondition, nil, "blob: Bucket has been closed") + +// PrefixedBucket returns a *Bucket based on b with all keys modified to have +// prefix, which will usually end with a "/" to target a subdirectory in the +// bucket. +// +// bucket will be closed and no longer usable after this function returns. +func PrefixedBucket(bucket *Bucket, prefix string) *Bucket { + bucket.mu.Lock() + defer bucket.mu.Unlock() + bucket.closed = true + return NewBucket(driver.NewPrefixedBucket(bucket.b, prefix)) +} + +// SingleKeyBucket returns a *Bucket based on b that always references singleKey. +// List methods will not work. +// singleKey acts as srcKey for Copy. +// +// bucket will be closed and no longer usable after this function returns. +func SingleKeyBucket(bucket *Bucket, singleKey string) *Bucket { + bucket.mu.Lock() + defer bucket.mu.Unlock() + bucket.closed = true + return NewBucket(driver.NewSingleKeyBucket(bucket.b, singleKey)) +} diff --git a/go-cloud/blob/blob_fs.go b/go-cloud/blob/blob_fs.go new file mode 100644 index 000000000..b3e9a44a2 --- /dev/null +++ b/go-cloud/blob/blob_fs.go @@ -0,0 +1,232 @@ +// Copyright 2023 The Go Cloud Development Kit 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 +// +// https://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 blob + +import ( + "context" + "fmt" + "io" + "io/fs" + "path/filepath" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +// Ensure that Bucket implements various io/fs interfaces. +var ( + _ = fs.FS(&Bucket{}) + _ = fs.SubFS(&Bucket{}) +) + +// iofsFileInfo describes a single file in an io/fs.FS. +// It implements fs.FileInfo and fs.DirEntry. +type iofsFileInfo struct { + lo *ListObject + name string +} + +func (f *iofsFileInfo) Name() string { return f.name } +func (f *iofsFileInfo) Size() int64 { return f.lo.Size } +func (f *iofsFileInfo) Mode() fs.FileMode { return fs.ModeIrregular } +func (f *iofsFileInfo) ModTime() time.Time { return f.lo.ModTime } +func (f *iofsFileInfo) IsDir() bool { return false } +func (f *iofsFileInfo) Sys() any { return f.lo } +func (f *iofsFileInfo) Info() (fs.FileInfo, error) { return f, nil } +func (f *iofsFileInfo) Type() fs.FileMode { return fs.ModeIrregular } + +// iofsOpenFile describes a single open file in an io/fs.FS. +// It implements fs.FileInfo and fs.File. +type iofsOpenFile struct { + *Reader + name string +} + +func (f *iofsOpenFile) Name() string { return f.name } +func (f *iofsOpenFile) Mode() fs.FileMode { return fs.ModeIrregular } +func (f *iofsOpenFile) IsDir() bool { return false } +func (f *iofsOpenFile) Sys() any { return f.r } +func (f *iofsOpenFile) Stat() (fs.FileInfo, error) { return f, nil } + +// iofsDir describes a single directory in an io/fs.FS. +// It implements fs.FileInfo, fs.DirEntry, and fs.File. +type iofsDir struct { + b *Bucket + key string + name string + // If opened is true, we've read entries via openOnce(). + opened bool + entries []fs.DirEntry + offset int +} + +func newDir(b *Bucket, key, name string) *iofsDir { + return &iofsDir{b: b, key: key, name: name} +} + +func (d *iofsDir) Name() string { return d.name } +func (d *iofsDir) Size() int64 { return 0 } +func (d *iofsDir) Mode() fs.FileMode { return fs.ModeDir } +func (d *iofsDir) Type() fs.FileMode { return fs.ModeDir } +func (d *iofsDir) ModTime() time.Time { return time.Time{} } +func (d *iofsDir) IsDir() bool { return true } +func (d *iofsDir) Sys() any { return d } +func (d *iofsDir) Info() (fs.FileInfo, error) { return d, nil } +func (d *iofsDir) Stat() (fs.FileInfo, error) { return d, nil } +func (d *iofsDir) Read([]byte) (int, error) { + return 0, &fs.PathError{Op: "read", Path: d.key, Err: fs.ErrInvalid} +} +func (d *iofsDir) Close() error { return nil } +func (d *iofsDir) ReadDir(count int) ([]fs.DirEntry, error) { + if err := d.openOnce(); err != nil { + return nil, err + } + n := len(d.entries) - d.offset + if n == 0 && count > 0 { + return nil, io.EOF + } + if count > 0 && n > count { + n = count + } + list := make([]fs.DirEntry, n) + for i := range list { + list[i] = d.entries[d.offset+i] + } + d.offset += n + return list, nil +} + +func (d *iofsDir) openOnce() error { + if d.opened { + return nil + } + d.opened = true + + // blob expects directories to end in the delimiter, except at the top level. + prefix := d.key + if prefix != "" { + prefix += "/" + } + listOpts := ListOptions{ + Prefix: prefix, + Delimiter: "/", + } + ctx, _ := d.b.ioFSCallback() + + // Fetch all the directory entries. + // Conceivably we could only fetch a few here, and fetch the rest lazily + // on demand, but that would add significant complexity. + iter := d.b.List(&listOpts) + for { + item, err := iter.Next(ctx) + if err == io.EOF { + break + } + if err != nil { + return err + } + name := filepath.Base(item.Key) + if item.IsDir { + d.entries = append(d.entries, newDir(d.b, item.Key, name)) + } else { + d.entries = append(d.entries, &iofsFileInfo{item, name}) + } + } + // There is no such thing as an empty directory in Bucket, so if + // we didn't find anything, it doesn't exist. + if len(d.entries) == 0 { + return fs.ErrNotExist + } + return nil +} + +// SetIOFSCallback sets a callback that is used during Open and calls on the objects +// returned from Open. +// +// fn should return a context.Context and *ReaderOptions that can be used in +// calls to List and NewReader on b. It may be called more than once. +// +// If SetIOFSCallback is never called, io.FS functions will use context.Background +// and a default ReaderOptions. +func (b *Bucket) SetIOFSCallback(fn func() (context.Context, *ReaderOptions)) { + b.ioFSCallback = fn +} + +// Open implements fs.FS.Open (https://pkg.go.dev/io/fs#FS). +func (b *Bucket) Open(path string) (fs.File, error) { + if !fs.ValidPath(path) { + return nil, &fs.PathError{Op: "open", Path: path, Err: fs.ErrInvalid} + } + + // Check if it's a file. If not, assume it's a directory until proven otherwise. + ctx, readerOpts := b.ioFSCallback() + var isDir bool + var key, name string // name is the last part of the path + if path == "." { + // Root is always a directory, but blob doesn't want the "." in the key. + isDir = true + key, name = "", "." + } else { + exists, _ := b.Exists(ctx, path) + isDir = !exists + key, name = path, filepath.Base(path) + } + + // If it's a directory, list the directory contents. We can't do this lazily + // because we need to error out here if it doesn't exist. + if isDir { + dir := newDir(b, key, name) + err := dir.openOnce() + if err != nil { + if err == fs.ErrNotExist && path == "." { + // The root directory must exist. + return dir, nil + } + return nil, &fs.PathError{Op: "open", Path: path, Err: err} + } + return dir, nil + } + + // It's a file; open it and return a wrapper. + r, err := b.NewReader(ctx, path, readerOpts) + if err != nil { + code := gcerrors.Code(err) + switch code { + case gcerrors.NotFound: + err = fmt.Errorf("%w: %w", err, fs.ErrNotExist) + case gcerrors.PermissionDenied: + err = fmt.Errorf("%w: %w", err, fs.ErrPermission) + } + return nil, &fs.PathError{Op: "open", Path: path, Err: err} + } + return &iofsOpenFile{r, filepath.Base(path)}, nil +} + +// Sub implements fs.SubFS.Sub. +// +// SetIOFSCallback must be called prior to calling this function. +func (b *Bucket) Sub(dir string) (fs.FS, error) { + if b.ioFSCallback == nil { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "blob: Sub -- SetIOFSCallback must be called before Sub") + } + if dir == "." { + return b, nil + } + // blob expects directories to end in the delimiter, except at the top level. + pb := PrefixedBucket(b, dir+"/") + pb.SetIOFSCallback(b.ioFSCallback) + return pb, nil +} diff --git a/go-cloud/blob/blob_fs_test.go b/go-cloud/blob/blob_fs_test.go new file mode 100644 index 000000000..bf0673fcf --- /dev/null +++ b/go-cloud/blob/blob_fs_test.go @@ -0,0 +1,149 @@ +// Copyright 2023 The Go Cloud Development Kit 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 +// +// https://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 blob_test + +import ( + "context" + "io/fs" + "sort" + "testing" + "testing/fstest" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/memblob" +) + +var fsFiles = []string{ + "a/very/deeply/nested/sub/dir/with/a/file.txt", + "baz.txt", + "bazfoo.txt", + "dir/foo.txt", + "dir/subdir/foo.txt", + "foo.txt", + "foobar.txt", +} + +func initBucket(t *testing.T, files []string) *blob.Bucket { + t.Helper() + + ctx := context.Background() + + b := memblob.OpenBucket(nil) + for _, f := range files { + if err := b.WriteAll(ctx, f, []byte("data"), nil); err != nil { + t.Fatal(err) + } + } + return b +} + +// TestIOFS runs the test/fstest test suite for fs.FS. +func TestIOFS(t *testing.T) { + tests := []struct { + Description string + Files []string + }{ + { + Description: "empty bucket", + }, + { + Description: "non-empty bucket", + Files: fsFiles, + }, + } + + for _, test := range tests { + t.Run(test.Description, func(t *testing.T) { + b := initBucket(t, test.Files) + defer b.Close() + if err := fstest.TestFS(b, test.Files...); err != nil { + t.Error(err) + } + }) + } +} + +// TestGlob does some basic verification that fs.Glob works as expected +// when given a blob.Bucket. +func TestGlob(t *testing.T) { + b := initBucket(t, fsFiles) + defer b.Close() + + tests := []struct { + Pattern string + Want []string + }{ + { + Pattern: "*", + Want: []string{"a", "baz.txt", "bazfoo.txt", "dir", "foo.txt", "foobar.txt"}, + }, + { + Pattern: "foo*", + Want: []string{"foo.txt", "foobar.txt"}, + }, + { + Pattern: "*foo*", + Want: []string{"bazfoo.txt", "foo.txt", "foobar.txt"}, + }, + } + for _, test := range tests { + t.Run(test.Pattern, func(t *testing.T) { + if got, err := fs.Glob(b, test.Pattern); err != nil { + t.Fatalf("Failed to glob: %v", err) + } else if diff := cmp.Diff(got, test.Want); diff != "" { + t.Error(diff) + } + }) + } +} + +// TestWalkDir does some basic verification that fs.WalkDir works as expected +// when given a blob.Bucket. +func TestWalkDir(t *testing.T) { + b := initBucket(t, fsFiles) + defer b.Close() + + var got []string + fn := func(path string, _ fs.DirEntry, err error) error { + if err != nil { + t.Errorf("WalkFunc with path %s got error: %v", path, err) + return err + } + got = append(got, path) + return nil + } + if err := fs.WalkDir(b, ".", fn); err != nil { + t.Fatalf("WalkDir got an unexpected error: %v", err) + } + // We want all of the files, plus the directories. + want := append(fsFiles, + ".", + "a", + "a/very", + "a/very/deeply", + "a/very/deeply/nested", + "a/very/deeply/nested/sub", + "a/very/deeply/nested/sub/dir", + "a/very/deeply/nested/sub/dir/with", + "a/very/deeply/nested/sub/dir/with/a", + "dir", + "dir/subdir", + ) + sort.Strings(want) + if diff := cmp.Diff(got, want); diff != "" { + t.Error(diff) + } +} diff --git a/go-cloud/blob/blob_reader_test.go b/go-cloud/blob/blob_reader_test.go new file mode 100644 index 000000000..3c498d439 --- /dev/null +++ b/go-cloud/blob/blob_reader_test.go @@ -0,0 +1,71 @@ +// Copyright 2022 The Go Cloud Development Kit 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 +// +// https://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 blob_test + +import ( + "bytes" + "context" + "io" + "testing" + "testing/iotest" + + "github.com/DataDog/iceberg-go/go-cloud/blob/memblob" +) + +// TestReader verifies that blob.Reader implements io package interfaces correctly. +func TestReader(t *testing.T) { + const myKey = "testkey" + + bucket := memblob.OpenBucket(nil) + defer bucket.Close() + + // Get some random data, of a large enough size to require multiple + // reads/writes given our buffer size of 1024. + data, err := randomData(1024*10 + 10) + if err != nil { + t.Fatal(err) + } + + // Write the data to a key. + ctx := context.Background() + bucket.WriteAll(ctx, myKey, data, nil) + + // Create a blob.Reader. + r1, err := bucket.NewReader(ctx, myKey, nil) + if err != nil { + t.Fatal(err) + } + r1.Close() + if err := iotest.TestReader(r1, data); err != nil { + t.Error(err) + } + + // Create another blob.Reader to exercise the ReadFrom code path + r2, err := bucket.NewReader(ctx, myKey, nil) + if err != nil { + t.Fatal(err) + } + defer r2.Close() + + var buffer bytes.Buffer + n, err := io.Copy(&buffer, r2) + if err != nil { + t.Fatal(err) + } else if n != int64(len(data)) { + t.Fatal("wrote fewer bytes than expected") + } else if !bytes.Equal(buffer.Bytes(), data) { + t.Fatal("wrote invalid bytes") + } +} diff --git a/go-cloud/blob/blob_test.go b/go-cloud/blob/blob_test.go new file mode 100644 index 000000000..7730e5442 --- /dev/null +++ b/go-cloud/blob/blob_test.go @@ -0,0 +1,652 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 blob + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "net/url" + "strings" + "sync" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +var ( + errFake = errors.New("fake") + errNotFound = errors.New("fake not found") +) + +func TestExists(t *testing.T) { + tests := []struct { + Description string + Err error + Want bool + WantErr bool + }{ + { + Description: "no error -> exists", + Err: nil, + Want: true, + WantErr: false, + }, + { + Description: "notfound error -> !exists", + Err: errNotFound, + Want: false, + WantErr: false, + }, + { + Description: "other error -> error", + Err: errFake, + Want: false, + WantErr: true, + }, + } + + for _, test := range tests { + t.Run(test.Description, func(t *testing.T) { + drv := &fakeAttributes{attributesErr: test.Err} + b := NewBucket(drv) + defer b.Close() + got, gotErr := b.Exists(context.Background(), "key") + if got != test.Want { + t.Errorf("got %v want %v", got, test.Want) + } + if (gotErr != nil) != test.WantErr { + t.Errorf("got err %v want %v", gotErr, test.WantErr) + } + }) + } +} + +// fakeAttributes implements driver.Bucket. Only Attributes is implemented, +// returning a zero Attributes struct and attributesErr. +type fakeAttributes struct { + driver.Bucket + attributesErr error +} + +func (b *fakeAttributes) Attributes(ctx context.Context, key string) (*driver.Attributes, error) { + if b.attributesErr != nil { + return nil, b.attributesErr + } + return &driver.Attributes{}, nil +} + +func (b *fakeAttributes) ErrorCode(err error) gcerrors.ErrorCode { + if err == errNotFound { + return gcerrors.NotFound + } + return gcerrors.Unknown +} + +func (b *fakeAttributes) Close() error { return nil } + +// Verify that ListIterator works even if driver.ListPaged returns empty pages. +func TestListIterator(t *testing.T) { + ctx := context.Background() + want := []string{"a", "b", "c"} + db := &fakeLister{ + pages: [][]string{{"a"}, {}, {}, {"b", "c"}, {}, {}}, + wantPageSizes: []int{0, 0, 0, 0, 0, 0}, + } + b := NewBucket(db) + defer b.Close() + iter := b.List(nil) + var got []string + for { + obj, err := iter.Next(ctx) + if err == io.EOF { + break + } + if err != nil { + t.Fatal(err) + } + got = append(got, obj.Key) + } + if !cmp.Equal(got, want) { + t.Errorf("got %v, want %v", got, want) + } +} + +// Verify that ListPage works even if driver.ListPaged returns empty pages. +func TestListPage(t *testing.T) { + ctx := context.Background() + want := [][]string{{"a", "b"}, {"c", "d"}, {"e"}} + db := &fakeLister{ + pages: [][]string{{}, {"a", "b"}, {}, {}, {"c"}, {}, {"d"}, {}, {}, {"e"}}, + wantPageSizes: []int{2, 2, 2, 2, 2, 1, 1, 2, 2, 2}, + } + b := NewBucket(db) + defer b.Close() + + nextToken := FirstPageToken + got := [][]string{} + for { + page, token, err := b.ListPage(ctx, nextToken, 2, nil) + if err == io.EOF { + break + } + if err != nil { + t.Fatal(err) + } + gotPage := make([]string, len(page)) + for i, o := range page { + gotPage[i] = o.Key + } + got = append(got, gotPage) + nextToken = token + } + if !cmp.Equal(got, want) { + t.Errorf("got %v, want %v", got, want) + } +} + +// fakeLister implements driver.Bucket. Only ListPaged is implemented, +// returning static data from pages. +type fakeLister struct { + driver.Bucket + pages [][]string + wantPageSizes []int +} + +func (b *fakeLister) ListPaged(ctx context.Context, opts *driver.ListOptions) (*driver.ListPage, error) { + if len(b.pages) != len(b.wantPageSizes) { + return nil, fmt.Errorf("invalid fakeLister setup") + } + if len(b.pages) == 0 { + return &driver.ListPage{}, nil + } + page := b.pages[0] + wantPageSize := b.wantPageSizes[0] + b.pages = b.pages[1:] + b.wantPageSizes = b.wantPageSizes[1:] + if opts.PageSize != wantPageSize { + return nil, fmt.Errorf("got page size %d, want %d", opts.PageSize, wantPageSize) + } + var objs []*driver.ListObject + for _, key := range page { + objs = append(objs, &driver.ListObject{Key: key}) + } + return &driver.ListPage{Objects: objs, NextPageToken: []byte{1}}, nil +} + +func (*fakeLister) Close() error { return nil } +func (*fakeLister) ErrorCode(err error) gcerrors.ErrorCode { return gcerrors.Unknown } + +type stubReader struct { + driver.Reader + downloaded bool +} + +func (r *stubReader) Download(w io.Writer) error { + r.downloaded = true + return nil +} + +func (*stubReader) Close() error { return nil } + +type stubWriter struct { + driver.Writer + uploaded bool +} + +func (w *stubWriter) Upload(r io.Reader) error { + w.uploaded = true + return nil +} + +func (*stubWriter) Close() error { return nil } + +// loaderBucket implements driver.Bucket's NewTypedWriter and NewRangedReader methods, +// returning stubReader and stubWriter. It is used to verify that the special driver.Uploader +// and driver.Downloader overrides work when called. +type loaderBucket struct { + driver.Bucket + w stubWriter + r stubReader +} + +func (b *loaderBucket) NewTypedWriter(ctx context.Context, key, contentType string, opts *driver.WriterOptions) (driver.Writer, error) { + return &b.w, nil +} + +func (b *loaderBucket) NewRangeReader(ctx context.Context, key string, offset, length int64, opts *driver.ReaderOptions) (driver.Reader, error) { + return &b.r, nil +} + +func (*loaderBucket) Close() error { return nil } + +func TestUploader(t *testing.T) { + ctx := context.Background() + lb := &loaderBucket{} + b := NewBucket(lb) + defer b.Close() + err := b.Upload(ctx, "key", nil, &WriterOptions{ContentType: "text/html"}) + if err != nil { + t.Fatalf("Upload failed: %v", err) + } + if !lb.w.uploaded { + t.Error("Uploader wasn't called") + } +} + +func TestDownloader(t *testing.T) { + ctx := context.Background() + lb := &loaderBucket{} + b := NewBucket(lb) + defer b.Close() + err := b.Download(ctx, "key", nil, nil) + if err != nil { + t.Fatalf("Download failed: %v", err) + } + if !lb.r.downloaded { + t.Error("Downloader wasn't called") + } +} + +func TestSeekAfterReadFailure(t *testing.T) { + const filename = "f.txt" + + ctx := context.Background() + + bucket := NewBucket(&oneTimeReadBucket{first: true}) + defer bucket.Close() + + reader, err := bucket.NewRangeReader(ctx, filename, 0, 100, nil) + if err != nil { + t.Fatalf("failed NewRangeReader: %v", err) + } + defer reader.Close() + + b := make([]byte, 10) + + _, err = reader.Read(b) + if err != nil { + t.Fatalf("failed Read#1: %v", err) + } + + _, err = reader.Seek(0, io.SeekStart) + if err != nil { + t.Fatalf("failed Seek#1: %v", err) + } + + // This Read will force a recreation of the reader via NewRangeReader, + // which will fail. + _, err = reader.Read(b) + if err == nil { + t.Fatalf("unexpectedly succeeded Read#2: %v", err) + } + + _, err = reader.Seek(0, io.SeekStart) + if err != nil { + t.Fatalf("failed Seek#2: %v", err) + } +} + +// oneTimeReadBucket implements driver.Bucket for TestSeekAfterReadFailure. +// It returns a fake reader that succeeds once, then fails. +type oneTimeReadBucket struct { + driver.Bucket + first bool +} + +type workingReader struct { + driver.Reader +} + +func (r *workingReader) Read(p []byte) (int, error) { + return len(p), nil +} + +func (r *workingReader) Attributes() *driver.ReaderAttributes { return &driver.ReaderAttributes{} } +func (r *workingReader) Close() error { return nil } + +func (b *oneTimeReadBucket) NewRangeReader(ctx context.Context, key string, offset, length int64, opts *driver.ReaderOptions) (driver.Reader, error) { + if b.first { + b.first = false + return &workingReader{}, nil + } + return nil, errFake +} + +func (b *oneTimeReadBucket) ErrorCode(err error) gcerrors.ErrorCode { return gcerrors.Unknown } +func (b *oneTimeReadBucket) Close() error { return nil } + +// erroringBucket implements driver.Bucket. All interface methods that return +// errors are implemented, and return errFake. +// In addition, when passed the key "work", NewRangeReader and NewTypedWriter +// will return a Reader/Writer respectively, that always return errFake +// from Read/Write and Close. +type erroringBucket struct { + driver.Bucket +} + +type erroringReader struct { + driver.Reader +} + +func (r *erroringReader) Read(p []byte) (int, error) { + return 0, errFake +} + +func (r *erroringReader) Close() error { + return errFake +} + +type erroringWriter struct { + driver.Writer +} + +func (r *erroringWriter) Write(p []byte) (int, error) { + return 0, errFake +} + +func (r *erroringWriter) Close() error { + return errFake +} + +func (b *erroringBucket) Attributes(ctx context.Context, key string) (*driver.Attributes, error) { + return nil, errFake +} + +func (b *erroringBucket) ListPaged(ctx context.Context, opts *driver.ListOptions) (*driver.ListPage, error) { + return nil, errFake +} + +func (b *erroringBucket) NewRangeReader(ctx context.Context, key string, offset, length int64, opts *driver.ReaderOptions) (driver.Reader, error) { + if key == "work" { + return &erroringReader{}, nil + } + return nil, errFake +} + +func (b *erroringBucket) NewTypedWriter(ctx context.Context, key, contentType string, opts *driver.WriterOptions) (driver.Writer, error) { + if key == "work" { + return &erroringWriter{}, nil + } + return nil, errFake +} + +func (b *erroringBucket) Copy(ctx context.Context, dstKey, srcKey string, opts *driver.CopyOptions) error { + return errFake +} + +func (b *erroringBucket) Delete(ctx context.Context, key string) error { + return errFake +} + +func (b *erroringBucket) SignedURL(ctx context.Context, key string, opts *driver.SignedURLOptions) (string, error) { + return "", errFake +} + +func (b *erroringBucket) Close() error { + return errFake +} + +func (b *erroringBucket) ErrorCode(err error) gcerrors.ErrorCode { + return gcerrors.Unknown +} + +// TestErrorsAreWrapped tests that all errors returned from the driver are +// wrapped exactly once by the portable type. +func TestErrorsAreWrapped(t *testing.T) { + ctx := context.Background() + buf := bytes.Repeat([]byte{'A'}, sniffLen) + b := NewBucket(&erroringBucket{}) + + // verifyWrap ensures that err is wrapped exactly once. + verifyWrap := func(description string, err error) { + if err == nil { + t.Errorf("%s: got nil error, wanted non-nil", description) + return + } + if _, ok := err.(*gcerr.Error); !ok { + t.Errorf("%s: not wrapped: %v", description, err) + } + if s := err.Error(); !strings.HasPrefix(s, "blob ") { + t.Logf("short form of error: %v", err) + t.Logf("with details: %+v", err) + t.Errorf("%s: Error() for wrapped error doesn't start with blob: prefix: %s", description, s) + } + } + + _, err := b.Attributes(ctx, "") + verifyWrap("Attributes", err) + + iter := b.List(nil) + _, err = iter.Next(ctx) + verifyWrap("ListIterator.Next", err) + + _, err = b.NewRangeReader(ctx, "", 0, 1, nil) + verifyWrap("NewRangeReader", err) + _, err = b.ReadAll(ctx, "") + verifyWrap("ReadAll", err) + + // Providing ContentType means driver.NewTypedWriter is called right away. + _, err = b.NewWriter(ctx, "", &WriterOptions{ContentType: "foo"}) + verifyWrap("NewWriter", err) + err = b.WriteAll(ctx, "", buf, &WriterOptions{ContentType: "foo"}) + verifyWrap("WriteAll", err) + + // Not providing ContentType means driver.NewTypedWriter is only called + // after writing sniffLen bytes. + w, _ := b.NewWriter(ctx, "", nil) + _, err = w.Write(buf) + verifyWrap("NewWriter (no ContentType)", err) + w.Close() + err = b.WriteAll(ctx, "", buf, nil) + verifyWrap("WriteAll (no ContentType)", err) + + r, _ := b.NewRangeReader(ctx, "work", 0, 1, nil) + _, err = r.Read(buf) + verifyWrap("Reader.Read", err) + + err = r.Close() + verifyWrap("Reader.Close", err) + + w, _ = b.NewWriter(ctx, "work", &WriterOptions{ContentType: "foo"}) + _, err = w.Write(buf) + verifyWrap("Writer.Write", err) + + err = w.Close() + verifyWrap("Writer.Close", err) + + err = b.Copy(ctx, "", "", nil) + verifyWrap("Copy", err) + + err = b.Delete(ctx, "") + verifyWrap("Delete", err) + + _, err = b.SignedURL(ctx, "", nil) + verifyWrap("SignedURL", err) + + err = b.Close() + verifyWrap("Close", err) +} + +var ( + testOpenOnce sync.Once + testOpenGot *url.URL +) + +// TestBucketIsClosed verifies that all Bucket functions return an error +// if the Bucket is closed. +func TestBucketIsClosed(t *testing.T) { + ctx := context.Background() + buf := bytes.Repeat([]byte{'A'}, sniffLen) + + bucket := NewBucket(&erroringBucket{}) + bucket.Close() + + if _, err := bucket.Attributes(ctx, ""); err != errClosed { + t.Error(err) + } + iter := bucket.List(nil) + if _, err := iter.Next(ctx); err != errClosed { + t.Error(err) + } + + if _, err := bucket.NewRangeReader(ctx, "", 0, 1, nil); err != errClosed { + t.Error(err) + } + if _, err := bucket.ReadAll(ctx, ""); err != errClosed { + t.Error(err) + } + if _, err := bucket.NewWriter(ctx, "", nil); err != errClosed { + t.Error(err) + } + if err := bucket.WriteAll(ctx, "", buf, nil); err != errClosed { + t.Error(err) + } + if _, err := bucket.NewRangeReader(ctx, "work", 0, 1, nil); err != errClosed { + t.Error(err) + } + if err := bucket.Copy(ctx, "", "", nil); err != errClosed { + t.Error(err) + } + if err := bucket.Delete(ctx, ""); err != errClosed { + t.Error(err) + } + if _, err := bucket.SignedURL(ctx, "", nil); err != errClosed { + t.Error(err) + } + if err := bucket.Close(); err != errClosed { + t.Error(err) + } +} + +func TestURLMux(t *testing.T) { + ctx := context.Background() + + mux := new(URLMux) + fake := &fakeOpener{} + mux.RegisterBucket("foo", fake) + mux.RegisterBucket("err", fake) + + if diff := cmp.Diff(mux.BucketSchemes(), []string{"err", "foo"}); diff != "" { + t.Errorf("Schemes: %s", diff) + } + if !mux.ValidBucketScheme("foo") || !mux.ValidBucketScheme("err") { + t.Errorf("ValidBucketScheme didn't return true for valid scheme") + } + if mux.ValidBucketScheme("foo2") || mux.ValidBucketScheme("http") { + t.Errorf("ValidBucketScheme didn't return false for invalid scheme") + } + + for _, tc := range []struct { + name string + url string + wantErr bool + }{ + { + name: "empty URL", + wantErr: true, + }, + { + name: "invalid URL", + url: ":foo", + wantErr: true, + }, + { + name: "invalid URL no scheme", + url: "foo", + wantErr: true, + }, + { + name: "unregistered scheme", + url: "bar://mybucket", + wantErr: true, + }, + { + name: "func returns error", + url: "err://mybucket", + wantErr: true, + }, + { + name: "no query options", + url: "foo://mybucket", + }, + { + name: "empty query options", + url: "foo://mybucket?", + }, + { + name: "query options", + url: "foo://mybucket?aAa=bBb&cCc=dDd", + }, + { + name: "multiple query options", + url: "foo://mybucket?x=a&x=b&x=c", + }, + { + name: "fancy bucket name", + url: "foo:///foo/bar/baz", + }, + { + name: "using api scheme prefix", + url: "blob+foo:///foo/bar/baz", + }, + { + name: "using api+type scheme prefix", + url: "blob+bucket+foo:///foo/bar/baz", + }, + } { + t.Run(tc.name, func(t *testing.T) { + _, gotErr := mux.OpenBucket(ctx, tc.url) + if (gotErr != nil) != tc.wantErr { + t.Fatalf("got err %v, want error %v", gotErr, tc.wantErr) + } + if gotErr != nil { + return + } + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + // Repeat with OpenBucketURL. + parsed, err := url.Parse(tc.url) + if err != nil { + t.Fatal(err) + } + _, gotErr = mux.OpenBucketURL(ctx, parsed) + if gotErr != nil { + t.Fatalf("got err %v want nil", gotErr) + } + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + }) + } +} + +type fakeOpener struct { + u *url.URL // last url passed to OpenBucketURL +} + +func (o *fakeOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*Bucket, error) { + if u.Scheme == "err" { + return nil, errors.New("fail") + } + o.u = u + return nil, nil +} diff --git a/go-cloud/blob/blob_writer_test.go b/go-cloud/blob/blob_writer_test.go new file mode 100644 index 000000000..459cb9544 --- /dev/null +++ b/go-cloud/blob/blob_writer_test.go @@ -0,0 +1,207 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 blob_test + +import ( + "bytes" + "context" + "crypto/rand" + "fmt" + "io" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/memblob" +) + +// TestWriteReturnValues verifies that blob.Writer returns the correct n +// even when it is doing content sniffing. +func TestWriteReturnValues(t *testing.T) { + ctx := context.Background() + + for _, withContentType := range []bool{true, false} { + t.Run(fmt.Sprintf("withContentType %v", withContentType), func(t *testing.T) { + bucket := memblob.OpenBucket(nil) + defer bucket.Close() + + var opts *blob.WriterOptions + if withContentType { + opts = &blob.WriterOptions{ContentType: "application/octet-stream"} + } + w, err := bucket.NewWriter(ctx, "testkey", opts) + if err != nil { + t.Fatalf("couldn't create writer with options: %v", err) + } + defer func() { + if err := w.Close(); err != nil { + t.Errorf("failed to close writer: %v", err) + } + }() + n, err := io.CopyN(w, rand.Reader, 182) + if err != nil || n != 182 { + t.Fatalf("CopyN(182) got %d, want 182: %v", n, err) + } + n, err = io.CopyN(w, rand.Reader, 1812) + if err != nil || n != 1812 { + t.Fatalf("CopyN(1812) got %d, want 1812: %v", n, err) + } + }) + } +} + +func randomData(nBytes int64) ([]byte, error) { + var buf bytes.Buffer + n, err := io.CopyN(&buf, rand.Reader, nBytes) + if err != nil || n != nBytes { + return nil, fmt.Errorf("failed to get random data (%d want %d): %v", n, nBytes, err) + } + return buf.Bytes(), nil +} + +// Ensure that blob.Reader implements io.WriterTo. +var _ io.WriterTo = &blob.Reader{} + +// Ensure that blob.Writer implements io.ReaderFrom. +var _ io.ReaderFrom = &blob.Writer{} + +func TestReadFrom(t *testing.T) { + const dstKey = "dstkey" + + // Get some random data, of a large enough size to require multiple + // reads/writes given our buffer size of 1024. + data, err := randomData(1024*10 + 10) + if err != nil { + t.Fatal(err) + } + + bucket := memblob.OpenBucket(nil) + defer bucket.Close() + + // Create a blob.Writer and write to it using ReadFrom given a buffer + // holding the random data. + ctx := context.Background() + w, err := bucket.NewWriter(ctx, dstKey, nil) + if err != nil { + t.Fatal(err) + } + n, err := w.ReadFrom(bytes.NewBuffer(data)) + if err != nil || n != int64(len(data)) { + t.Fatalf("failed to ReadFrom (%d want %d): %v", n, len(data), err) + } + if err := w.Close(); err != nil { + t.Fatal(err) + } + + // Verify the data was copied correctly. + got, err := bucket.ReadAll(ctx, dstKey) + if err != nil { + t.Fatal(err) + } + if !cmp.Equal(got, data) { + t.Errorf("got %v, want %v", got, data) + } +} + +func TestWriteTo(t *testing.T) { + const srcKey = "srckey" + + // Get some random data, of a large enough size to require multiple + // reads/writes given our buffer size of 1024. + data, err := randomData(1024*10 + 10) + if err != nil { + t.Fatal(err) + } + + bucket := memblob.OpenBucket(nil) + defer bucket.Close() + + // Write the data to a key. + ctx := context.Background() + if err := bucket.WriteAll(ctx, srcKey, data, nil); err != nil { + t.Fatal(err) + } + + // Create a blob.Reader for that key and read from it, writing to a buffer. + r, err := bucket.NewReader(ctx, srcKey, nil) + if err != nil { + t.Fatal(err) + } + var buf bytes.Buffer + n, err := r.WriteTo(&buf) + if err != nil || n != int64(len(data)) { + t.Fatalf("failed to WriteTo (%d want %d): %v", n, len(data), err) + } + if err := r.Close(); err != nil { + t.Fatal(err) + } + + // Verify the data was copied correctly. + got := buf.Bytes() + if !cmp.Equal(got, data) { + t.Errorf("got %v, want %v", got, data) + } +} + +// TestCopyBytes uses io.Copy to copy bytes from one key to another. +func TestCopyBytes(t *testing.T) { + const srcKey = "testkey-src" + const dstKey = "testkey-dst" + + ctx := context.Background() + + // Get some random data, of a large enough size to require multiple + // reads/writes given our buffer size of 1024. + data, err := randomData(1024*10 + 10) + if err != nil { + t.Fatal(err) + } + + bucket := memblob.OpenBucket(nil) + defer bucket.Close() + + // Write the data to srcKey. + bucket.WriteAll(ctx, srcKey, data, nil) + + // Create a reader for srcKey. + r, err := bucket.NewReader(ctx, srcKey, nil) + if err != nil { + t.Fatalf("failed to create reader: %v", err) + } + + // Create a writer for dstKey. + w, err := bucket.NewWriter(ctx, dstKey, nil) + if err != nil { + t.Fatalf("failed to create writer: %v", err) + } + + // Copy the data. + io.Copy(w, r) + if err := r.Close(); err != nil { + t.Fatal(err) + } + if err := w.Close(); err != nil { + t.Fatal(err) + } + + // Verify the data was copied correctly. + got, err := bucket.ReadAll(ctx, dstKey) + if err != nil { + t.Fatal(err) + } + if !cmp.Equal(got, data) { + t.Errorf("got %v, want %v", got, data) + } +} diff --git a/go-cloud/blob/driver/driver.go b/go-cloud/blob/driver/driver.go new file mode 100644 index 000000000..eadff4555 --- /dev/null +++ b/go-cloud/blob/driver/driver.go @@ -0,0 +1,479 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 driver defines interfaces to be implemented by blob drivers, which +// will be used by the blob package to interact with the underlying services. +// Application code should use package blob. +package driver // import "gocloud.dev/blob/driver" + +import ( + "context" + "errors" + "io" + "strings" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +// ReaderOptions controls Reader behaviors. +type ReaderOptions struct { + // BeforeRead is a callback that must be called exactly once before + // any data is read, unless NewRangeReader returns an error before then, in + // which case it should not be called at all. + // asFunc allows drivers to expose driver-specific types; + // see Bucket.As for more details. + BeforeRead func(asFunc func(any) bool) error +} + +// Reader reads an object from the blob. +type Reader interface { + io.ReadCloser + + // Attributes returns a subset of attributes about the blob. + // The portable type will not modify the returned ReaderAttributes. + Attributes() *ReaderAttributes + + // As allows drivers to expose driver-specific types; + // see Bucket.As for more details. + As(any) bool +} + +// Downloader has an optional extra method for readers. +// It is similar to io.WriteTo, but without the count of bytes returned. +type Downloader interface { + // Download is similar to io.WriteTo, but without the count of bytes returned. + Download(w io.Writer) error +} + +// Writer writes an object to the blob. +type Writer interface { + io.WriteCloser +} + +// Uploader has an optional extra method for writers. +type Uploader interface { + // Upload is similar to io.ReadFrom, but without the count of bytes returned. + Upload(r io.Reader) error +} + +// WriterOptions controls behaviors of Writer. +type WriterOptions struct { + // BufferSize changes the default size in byte of the maximum part Writer can + // write in a single request, if supported. Larger objects will be split into + // multiple requests. + BufferSize int + // MaxConcurrency changes the default concurrency for uploading parts. + MaxConcurrency int + // CacheControl specifies caching attributes that services may use + // when serving the blob. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control + CacheControl string + // ContentDisposition specifies whether the blob content is expected to be + // displayed inline or as an attachment. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition + ContentDisposition string + // ContentEncoding specifies the encoding used for the blob's content, if any. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding + ContentEncoding string + // ContentLanguage specifies the language used in the blob's content, if any. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language + ContentLanguage string + // ContentMD5 is used as a message integrity check. + // The portable type checks that the MD5 hash of the bytes written matches + // ContentMD5. + // If len(ContentMD5) > 0, driver implementations may pass it to their + // underlying network service to guarantee the integrity of the bytes in + // transit. + ContentMD5 []byte + // Metadata holds key/value strings to be associated with the blob. + // Keys are guaranteed to be non-empty and lowercased. + Metadata map[string]string + // When true, the driver should attempt to disable any automatic + // content-type detection that the provider applies on writes with an + // empty ContentType. + DisableContentTypeDetection bool + // BeforeWrite is a callback that must be called exactly once before + // any data is written, unless NewTypedWriter returns an error, in + // which case it should not be called. + // asFunc allows drivers to expose driver-specific types; + // see Bucket.As for more details. + BeforeWrite func(asFunc func(any) bool) error + + // IfNotExist is used for conditional writes. + // When set to true, if a blob exists for the same key in the bucket, the write operation + // won't take place. + IfNotExist bool +} + +// CopyOptions controls options for Copy. +type CopyOptions struct { + // BeforeCopy is a callback that must be called before initiating the Copy. + // asFunc allows drivers to expose driver-specific types; + // see Bucket.As for more details. + BeforeCopy func(asFunc func(any) bool) error +} + +// ReaderAttributes contains a subset of attributes about a blob that are +// accessible from Reader. +type ReaderAttributes struct { + // ContentType is the MIME type of the blob object. It must not be empty. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type + ContentType string + // ModTime is the time the blob object was last modified. + ModTime time.Time + // Size is the size of the object in bytes. + Size int64 +} + +// Attributes contains attributes about a blob. +type Attributes struct { + // CacheControl specifies caching attributes that services may use + // when serving the blob. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control + CacheControl string + // ContentDisposition specifies whether the blob content is expected to be + // displayed inline or as an attachment. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition + ContentDisposition string + // ContentEncoding specifies the encoding used for the blob's content, if any. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding + ContentEncoding string + // ContentLanguage specifies the language used in the blob's content, if any. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language + ContentLanguage string + // ContentType is the MIME type of the blob object. It must not be empty. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type + ContentType string + // Metadata holds key/value pairs associated with the blob. + // Keys will be lowercased by the portable type before being returned + // to the user. If there are duplicate case-insensitive keys (e.g., + // "foo" and "FOO"), only one value will be kept, and it is undefined + // which one. + Metadata map[string]string + // CreateTime is the time the blob object was created. If not available, + // leave as the zero time. + CreateTime time.Time + // ModTime is the time the blob object was last modified. + ModTime time.Time + // Size is the size of the object in bytes. + Size int64 + // MD5 is an MD5 hash of the blob contents or nil if not available. + MD5 []byte + // ETag for the blob; see https://en.wikipedia.org/wiki/HTTP_ETag. + ETag string + // AsFunc allows drivers to expose driver-specific types; + // see Bucket.As for more details. + // If not set, no driver-specific types are supported. + AsFunc func(any) bool +} + +// ListOptions sets options for listing objects in the bucket. +type ListOptions struct { + // Prefix indicates that only results with the given prefix should be + // returned. + Prefix string + // Delimiter sets the delimiter used to define a hierarchical namespace, + // like a filesystem with "directories". + // + // An empty delimiter means that the bucket is treated as a single flat + // namespace. + // + // A non-empty delimiter means that any result with the delimiter in its key + // after Prefix is stripped will be returned with ListObject.IsDir = true, + // ListObject.Key truncated after the delimiter, and zero values for other + // ListObject fields. These results represent "directories". Multiple results + // in a "directory" are returned as a single result. + Delimiter string + // PageSize sets the maximum number of objects to be returned. + // 0 means no maximum; driver implementations should choose a reasonable + // max. It is guaranteed to be >= 0. + PageSize int + // PageToken may be filled in with the NextPageToken from a previous + // ListPaged call. + PageToken []byte + // BeforeList is a callback that must be called exactly once during ListPaged, + // before the underlying service's list is executed. + // asFunc allows drivers to expose driver-specific types; + // see Bucket.As for more details. + BeforeList func(asFunc func(any) bool) error +} + +// ListObject represents a specific blob object returned from ListPaged. +type ListObject struct { + // Key is the key for this blob. + Key string + // ModTime is the time the blob object was last modified. + ModTime time.Time + // Size is the size of the object in bytes. + Size int64 + // MD5 is an MD5 hash of the blob contents or nil if not available. + MD5 []byte + // IsDir indicates that this result represents a "directory" in the + // hierarchical namespace, ending in ListOptions.Delimiter. Key can be + // passed as ListOptions.Prefix to list items in the "directory". + // Fields other than Key and IsDir will not be set if IsDir is true. + IsDir bool + // AsFunc allows drivers to expose driver-specific types; + // see Bucket.As for more details. + // If not set, no driver-specific types are supported. + AsFunc func(any) bool +} + +// ListPage represents a page of results return from ListPaged. +type ListPage struct { + // Objects is the slice of objects found. If ListOptions.PageSize > 0, + // it should have at most ListOptions.PageSize entries. + // + // Objects should be returned in lexicographical order of UTF-8 encoded keys, + // including across pages. I.e., all objects returned from a ListPage request + // made using a PageToken from a previous ListPage request's NextPageToken + // should have Key >= the Key for all objects from the previous request. + Objects []*ListObject + // NextPageToken should be left empty unless there are more objects + // to return. The value may be returned as ListOptions.PageToken on a + // subsequent ListPaged call, to fetch the next page of results. + // It can be an arbitrary []byte; it need not be a valid key. + NextPageToken []byte +} + +// Bucket provides read, write and delete operations on objects within it on the +// blob service. +type Bucket interface { + // ErrorCode should return a code that describes the error, which was returned by + // one of the other methods in this interface. + ErrorCode(error) gcerrors.ErrorCode + + // As converts i to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + As(i any) bool + + // ErrorAs allows drivers to expose driver-specific types for returned + // errors. + // See https://gocloud.dev/concepts/as/ for background information. + ErrorAs(error, any) bool + + // Attributes returns attributes for the blob. If the specified object does + // not exist, Attributes must return an error for which ErrorCode returns + // gcerrors.NotFound. + // The portable type will not modify the returned Attributes. + Attributes(ctx context.Context, key string) (*Attributes, error) + + // ListPaged lists objects in the bucket, in lexicographical order by + // UTF-8-encoded key, returning pages of objects at a time. + // Services are only required to be eventually consistent with respect + // to recently written or deleted objects. That is to say, there is no + // guarantee that an object that's been written will immediately be returned + // from ListPaged. + // opts is guaranteed to be non-nil. + ListPaged(ctx context.Context, opts *ListOptions) (*ListPage, error) + + // NewRangeReader returns a Reader that reads part of an object, reading at + // most length bytes starting at the given offset. If length is negative, it + // will read until the end of the object. If the specified object does not + // exist, NewRangeReader must return an error for which ErrorCode returns + // gcerrors.NotFound. + // opts is guaranteed to be non-nil. + // + // The returned Reader *may* also implement Downloader if the underlying + // implementation can take advantage of that. The Download call is guaranteed + // to be the only call to the Reader. For such readers, offset will always + // be 0 and length will always be -1. + NewRangeReader(ctx context.Context, key string, offset, length int64, opts *ReaderOptions) (Reader, error) + + // NewTypedWriter returns Writer that writes to an object associated with key. + // + // A new object will be created unless an object with this key already exists. + // Otherwise any previous object with the same key will be replaced. + // The object may not be available (and any previous object will remain) + // until Close has been called. + // + // contentType sets the MIME type of the object to be written. + // opts is guaranteed to be non-nil. + // + // The caller must call Close on the returned Writer when done writing. + // + // Implementations should abort an ongoing write if ctx is later canceled, + // and do any necessary cleanup in Close. Close should then return ctx.Err(). + // + // The returned Writer *may* also implement Uploader if the underlying + // implementation can take advantage of that. The Upload call is guaranteed + // to be the only non-Close call to the Writer.. + NewTypedWriter(ctx context.Context, key, contentType string, opts *WriterOptions) (Writer, error) + + // Copy copies the object associated with srcKey to dstKey. + // + // If the source object does not exist, Copy must return an error for which + // ErrorCode returns gcerrors.NotFound. + // + // If the destination object already exists, it should be overwritten. + // + // opts is guaranteed to be non-nil. + Copy(ctx context.Context, dstKey, srcKey string, opts *CopyOptions) error + + // Delete deletes the object associated with key. If the specified object does + // not exist, Delete must return an error for which ErrorCode returns + // gcerrors.NotFound. + Delete(ctx context.Context, key string) error + + // SignedURL returns a URL that can be used to GET the blob for the duration + // specified in opts.Expiry. opts is guaranteed to be non-nil. + // If not supported, return an error for which ErrorCode returns + // gcerrors.Unimplemented. + SignedURL(ctx context.Context, key string, opts *SignedURLOptions) (string, error) + + // Close cleans up any resources used by the Bucket. Once Close is called, + // there will be no method calls to the Bucket other than As, ErrorAs, and + // ErrorCode. There may be open readers or writers that will receive calls. + // It is up to the driver as to how these will be handled. + Close() error +} + +// SignedURLOptions sets options for SignedURL. +type SignedURLOptions struct { + // Expiry sets how long the returned URL is valid for. It is guaranteed to be > 0. + Expiry time.Duration + + // Method is the HTTP method that can be used on the URL; one of "GET", "PUT", + // or "DELETE". Drivers must implement all 3. + Method string + + // ContentType specifies the Content-Type HTTP header the user agent is + // permitted to use in the PUT request. It must match exactly. See + // EnforceAbsentContentType for behavior when ContentType is the empty string. + // If this field is not empty and the bucket cannot enforce the Content-Type + // header, it must return an Unimplemented error. + // + // This field will not be set for any non-PUT requests. + ContentType string + + // If EnforceAbsentContentType is true and ContentType is the empty string, + // then PUTing to the signed URL must fail if the Content-Type header is + // present or the implementation must return an error if it cannot enforce + // this. If EnforceAbsentContentType is false and ContentType is the empty + // string, implementations should validate the Content-Type header if possible. + // If EnforceAbsentContentType is true and the bucket cannot enforce the + // Content-Type header, it must return an Unimplemented error. + // + // This field will always be false for non-PUT requests. + EnforceAbsentContentType bool + + // BeforeSign is a callback that will be called before each call to the + // the underlying service's sign functionality. + // asFunc converts its argument to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + BeforeSign func(asFunc func(any) bool) error +} + +// prefixedBucket implements Bucket by prepending prefix to all keys. +type prefixedBucket struct { + base Bucket + prefix string +} + +// NewPrefixedBucket returns a Bucket based on b with all keys modified to have +// prefix. +func NewPrefixedBucket(b Bucket, prefix string) Bucket { + return &prefixedBucket{base: b, prefix: prefix} +} + +func (b *prefixedBucket) ErrorCode(err error) gcerrors.ErrorCode { return b.base.ErrorCode(err) } +func (b *prefixedBucket) As(i any) bool { return b.base.As(i) } +func (b *prefixedBucket) ErrorAs(err error, i any) bool { return b.base.ErrorAs(err, i) } +func (b *prefixedBucket) Attributes(ctx context.Context, key string) (*Attributes, error) { + return b.base.Attributes(ctx, b.prefix+key) +} + +func (b *prefixedBucket) ListPaged(ctx context.Context, opts *ListOptions) (*ListPage, error) { + var myopts ListOptions + if opts != nil { + myopts = *opts + } + myopts.Prefix = b.prefix + myopts.Prefix + page, err := b.base.ListPaged(ctx, &myopts) + if err != nil { + return nil, err + } + for _, p := range page.Objects { + p.Key = strings.TrimPrefix(p.Key, b.prefix) + } + return page, nil +} + +func (b *prefixedBucket) NewRangeReader(ctx context.Context, key string, offset, length int64, opts *ReaderOptions) (Reader, error) { + return b.base.NewRangeReader(ctx, b.prefix+key, offset, length, opts) +} + +func (b *prefixedBucket) NewTypedWriter(ctx context.Context, key, contentType string, opts *WriterOptions) (Writer, error) { + if key == "" { + return nil, errors.New("invalid key (empty string)") + } + return b.base.NewTypedWriter(ctx, b.prefix+key, contentType, opts) +} + +func (b *prefixedBucket) Copy(ctx context.Context, dstKey, srcKey string, opts *CopyOptions) error { + return b.base.Copy(ctx, b.prefix+dstKey, b.prefix+srcKey, opts) +} + +func (b *prefixedBucket) Delete(ctx context.Context, key string) error { + return b.base.Delete(ctx, b.prefix+key) +} + +func (b *prefixedBucket) SignedURL(ctx context.Context, key string, opts *SignedURLOptions) (string, error) { + return b.base.SignedURL(ctx, b.prefix+key, opts) +} +func (b *prefixedBucket) Close() error { return b.base.Close() } + +// singleKeyBucket implements Bucket by hardwiring a specific key. +type singleKeyBucket struct { + base Bucket + key string +} + +// NewSingleKeyBucket returns a Bucket based on b that always references key. +func NewSingleKeyBucket(b Bucket, key string) Bucket { + return &singleKeyBucket{base: b, key: key} +} + +func (b *singleKeyBucket) ErrorCode(err error) gcerrors.ErrorCode { return b.base.ErrorCode(err) } +func (b *singleKeyBucket) As(i any) bool { return b.base.As(i) } +func (b *singleKeyBucket) ErrorAs(err error, i any) bool { return b.base.ErrorAs(err, i) } +func (b *singleKeyBucket) Attributes(ctx context.Context, _ string) (*Attributes, error) { + return b.base.Attributes(ctx, b.key) +} + +func (b *singleKeyBucket) ListPaged(ctx context.Context, opts *ListOptions) (*ListPage, error) { + return nil, errors.New("List not supported for SingleKey buckets") +} + +func (b *singleKeyBucket) NewRangeReader(ctx context.Context, _ string, offset, length int64, opts *ReaderOptions) (Reader, error) { + return b.base.NewRangeReader(ctx, b.key, offset, length, opts) +} + +func (b *singleKeyBucket) NewTypedWriter(ctx context.Context, _, contentType string, opts *WriterOptions) (Writer, error) { + return b.base.NewTypedWriter(ctx, b.key, contentType, opts) +} + +func (b *singleKeyBucket) Copy(ctx context.Context, dstKey, _ string, opts *CopyOptions) error { + return b.base.Copy(ctx, dstKey, b.key, opts) +} + +func (b *singleKeyBucket) Delete(ctx context.Context, _ string) error { + return b.base.Delete(ctx, b.key) +} + +func (b *singleKeyBucket) SignedURL(ctx context.Context, _ string, opts *SignedURLOptions) (string, error) { + return b.base.SignedURL(ctx, b.key, opts) +} +func (b *singleKeyBucket) Close() error { return b.base.Close() } diff --git a/go-cloud/blob/drivertest/bindata.go b/go-cloud/blob/drivertest/bindata.go new file mode 100644 index 000000000..a9ee194bf --- /dev/null +++ b/go-cloud/blob/drivertest/bindata.go @@ -0,0 +1,146 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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. +// +// This file was auto-generated using go-bindata (https://github.com/jteeuwen/go-bindata). + +package drivertest + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "strings" +) + +func bindataRead(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + gz.Close() + + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + return buf.Bytes(), nil +} + +var _testLargeJpg = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfc\x65\x54\x9b\xd1\xba\x2e\x0c\x3f\xc1\x82\x07\x2f\x0e\x45\x0a\x05\x4a\x8b\x16\x97\xb6\x78\xd1\x16\xd7\x22\xc5\xdd\x82\x07\x77\x2f\xd0\xa2\xc1\x9d\x40\x71\x77\x2f\x4e\xa1\x40\xd1\x40\xf1\x42\xd0\x94\x52\xf8\xc6\x5a\x67\x9d\xfd\xae\xbd\xf6\xda\xdf\x58\xfb\x1d\x7b\x9f\xf7\xcf\x99\x63\x5c\xff\x92\x99\x5c\x79\xe6\x3d\x6f\xbd\x72\xff\xed\x7e\x03\x20\x51\x96\x57\x92\x07\x40\x18\x00\x00\x02\x40\x00\x70\xbf\x02\xbc\x04\x70\x71\x70\xc0\x38\xd8\xb8\x60\x30\x18\x0f\x0f\x17\x9f\x90\x82\x88\x90\x80\x80\x90\x86\x8c\x1c\x42\xc1\x40\xcb\xc4\xc8\x40\x4b\x4f\xcf\xcc\xc6\xcb\xc1\xcc\xc2\xc3\x4a\x4f\xcf\xf9\xfc\x31\xcf\x33\x3e\x41\x41\x41\x26\x0e\x51\x49\x11\x7e\x09\x5e\x01\x41\xfe\xbf\x6c\x02\xc2\xc3\xc3\x23\x24\x20\xa4\x26\x22\xa2\xe6\x7f\x48\xff\x90\xff\xbf\xbc\xee\x7b\x00\x52\x5c\xd0\x05\xe6\x1e\x26\x88\x05\xc0\x20\x05\x61\x92\x82\xee\x07\x00\x26\x00\x00\x61\x83\xfe\xba\x80\xbf\x2d\x10\x06\x26\x16\x36\x0e\x18\x17\x0f\x9f\xe0\x7e\x00\x68\x24\x01\x30\x40\x98\x98\x18\x58\x98\xd8\xd8\x58\x58\x00\x00\x0a\x00\x61\x60\x02\x58\xa4\xd8\x64\x0f\xf9\x64\x71\xc8\x35\xdf\x81\x59\x5c\x29\xf8\x83\x93\xf3\x71\x59\x5f\xd4\xf5\x52\x6a\xcd\x9c\xb2\x09\x98\xbb\x85\xe0\xe1\x53\x3d\xa0\xa6\xa1\x65\x7f\xc4\xc1\xf9\x98\x4b\x50\x48\xf8\xb9\x88\xa8\xd8\xcb\x57\x72\xf2\x0a\x8a\x4a\xca\x6f\xde\x6a\xeb\xe8\xea\xe9\x1b\x58\x58\x5a\xbd\xb7\xb6\xb1\xb5\x73\xf7\xf0\xf4\xf2\x86\xfa\xf8\x86\x86\x85\x47\x44\x46\x45\xc7\xa4\xa4\x7e\x48\x4b\xcf\xf8\xf8\x29\xb3\xa0\xb0\xa8\xb8\xa4\xb4\xac\xbc\xe2\x73\x7d\x43\x63\x53\x73\x4b\x6b\x5b\x5f\xff\xc0\xe0\xd0\xf0\xc8\xe8\xd8\xec\xdc\xfc\xd7\x85\xc5\x6f\x4b\xcb\x9b\x5b\xc8\xed\x9d\x1f\xbb\x7b\xfb\x07\xa8\xb3\xf3\x8b\xcb\xab\x6b\xf4\xaf\x9b\xbf\xf0\x02\x01\x98\xa0\xff\xbd\xfe\x29\x2f\x52\x00\x03\x84\x81\x85\x85\x89\x05\xfe\x0b\x2f\x10\x86\xf7\x5f\x5e\x40\x8a\x85\xfd\x90\x0f\x87\x4c\x56\x13\xfc\xce\x95\x9c\x85\x3f\x18\x97\xe2\x45\x72\x7e\x5d\x2f\x1e\xab\x80\xd6\x29\xa5\xb9\xdb\x0c\x3e\x15\x9b\xe0\x26\x3b\xea\x2f\xd4\xfe\xca\xec\x5f\x23\x16\xf2\xff\x8a\xd9\xbf\x11\xfb\x7f\x78\x2d\x03\x84\x98\x20\x00\x83\x14\x93\x14\x90\x06\xae\x6f\x38\x0b\x60\xf8\xff\x01\x82\xee\x32\xd8\x14\x9a\xff\x17\xff\x17\xff\x22\xde\xb0\x25\xb3\x68\xfd\xec\x7d\xeb\xc9\x36\x8d\xb9\x57\x71\x0f\x38\x46\xba\x1a\x1f\x66\x5b\xd3\x94\xa7\x7d\x8d\x90\x1d\x81\x83\x35\xe5\x28\x80\xff\x09\x80\x82\xe5\x28\x34\x40\xff\xdf\x62\xd1\x53\x46\x85\x04\x38\x50\x05\xc4\x62\xfa\x3a\x51\x11\xe1\x66\xbf\x79\x85\xc4\x6d\x56\x12\x08\x43\xbb\x95\x33\x94\x50\x52\xc9\xd5\xf9\x01\x52\x37\x34\x3d\xe2\x6a\x0b\xdb\x4c\xc5\x80\x83\xa6\x22\xae\x24\xd1\x13\x80\x42\x53\x0e\xa0\xd0\x4c\x96\x03\x28\xb4\xde\xa7\xba\x5c\xc2\xc1\x9a\xaa\x6b\x92\x72\x8f\xcd\xc4\x63\x00\x9a\x90\x72\x0e\x38\x02\x8c\x8e\x46\xea\x37\xaa\x5a\x5d\xc4\x82\x3b\xfa\x9a\x06\x13\x30\xe3\x8f\x20\x81\x92\x9d\xf7\x00\xfe\x65\x10\xcd\xa1\xeb\x5e\x20\x55\x67\xb7\xe3\xb0\x25\x94\xce\x8f\xbc\x47\xe8\xc7\x3a\x5e\x87\x28\x56\x93\x9b\x7d\x86\x9c\x75\x5b\x4b\x72\x8e\x71\x2f\x3b\x8e\xaf\xbb\x0c\xb5\xf0\x3a\xe4\xd6\x5a\xa8\xee\xab\xae\xa6\x9f\x3d\xfc\xe5\xa0\x1d\xbb\x04\xe4\xc5\x5a\xe3\x37\x28\xe6\xb0\x6f\xf5\x5d\xb5\x70\x78\x95\x4c\xb9\x8f\xd3\x27\x73\x10\x76\xeb\x4f\x71\x2f\xc4\x6b\xbd\x69\xb9\x38\x62\x6c\xe8\x91\xdb\x80\x94\xf8\xea\xaf\xd7\x4b\x7c\xd8\x66\x22\x34\xcb\x62\x48\x04\x63\x03\xe8\x38\xb9\x69\x1b\x27\x4f\x53\xf6\xae\x2a\x80\xcb\x00\xe0\x2c\x88\xf9\x97\x20\x30\xf1\xd7\x03\xa2\x45\x06\x7e\x23\x43\x20\xf7\xdc\xf7\x26\xc6\x4b\x16\x8e\x11\xc3\xf9\x37\x3c\xe6\x04\xd9\xfc\xc3\x3b\x1e\x0b\x4c\x3c\xf9\x9f\x39\x2d\xff\x15\xc4\xb9\x14\xdd\xe8\x46\xf8\x6b\xa1\xe6\x9b\x79\x6f\x84\x73\xf5\x0d\x03\x09\xb2\x6b\x14\x8f\xa7\xe8\x6f\x16\x1b\xed\x1e\x60\x2c\xf7\xd9\x46\xf7\xbc\x7a\xd4\x15\x74\x5a\xa5\x93\x79\x0f\x0c\x1c\x66\x45\x3f\x5c\xa9\x8b\x66\xba\x98\x4e\xb8\x00\x35\x6e\x4c\x85\x35\x5d\xa7\xd7\x1e\x88\xed\xd9\x16\xa7\xf0\xfd\x4e\x67\xb3\xc8\x3e\x0f\x9d\x70\xb2\x33\xc5\x73\x3c\x96\x9e\xf3\x17\xf0\xe6\xcd\x0a\xfc\xf4\xb8\xf1\x9a\xd5\x75\x7a\x97\xe3\x0c\xf1\x3a\x44\x30\x82\x04\x0c\xe0\x47\xac\xbc\x6d\x68\xf3\x52\x2c\x91\xb7\x14\x31\x83\x28\x03\xe7\x89\xc4\xfe\x0a\x2d\xf5\xf3\x6f\x5e\xa0\x5e\x99\x2f\xbe\x39\xc7\xc7\x19\xa2\x1c\x36\x97\x4c\x54\xbe\x40\x3b\x91\x59\x12\xc6\xe1\xb2\x0a\xfd\x90\xa6\x96\xe0\x6d\x6b\x8a\xfd\x53\x6a\x33\xce\x70\xf9\x91\x87\xae\x64\xfb\x27\x3f\x77\xcc\x6c\x17\xef\xea\x12\xda\xd3\xbc\xa9\xf9\xfc\x84\xf4\x45\x3d\xfd\xf1\x9b\xb9\x43\x19\xa6\x97\x82\x31\x85\x6c\x31\x85\x7e\xd5\x7a\x7a\x2f\x2c\x5b\xdb\x62\x28\xe9\x53\x7e\x02\x18\x1d\x4e\xeb\x86\xa8\xee\xa8\x5d\x43\xad\x54\x43\x70\x24\xa1\x46\xe0\x09\x47\xce\x0a\x6c\x4a\x6d\xe9\xd0\x90\xcf\xff\xd9\xfc\xcf\x63\x2d\x95\x55\x27\xaf\x8f\x67\x07\x7b\x55\xad\x97\x34\xf4\x4c\x43\x30\xb1\x95\x6e\x46\x5b\xaf\x99\x86\xd1\xe7\xcb\xac\xa6\x5d\x33\x84\x61\xfb\x8b\xe7\x94\x89\xf7\x00\x81\xbd\x02\xd5\x79\xd7\x4a\x44\x0a\xbf\x2b\x59\x89\x8a\x7b\x70\x88\xc8\xee\xa1\xd6\xd2\xed\xe3\x19\xf3\x20\x7e\xe4\x44\x0b\xdb\x76\x34\x5d\x68\xee\x37\x86\xca\xc2\x86\xd3\xc0\x68\x6b\x96\x71\xec\x30\x3c\x96\x38\x27\x5c\x81\x18\xe0\xfc\xf7\x3d\x10\xa7\x6c\x49\xf2\xcd\xf6\xbc\x5b\xf5\xa8\xa7\xdc\x84\x1f\xca\xda\xbc\x50\x7f\x7c\x6b\x85\x94\x54\xcd\x54\x95\x56\x6b\xa1\x9b\xff\x38\x3e\xd8\x2a\x15\x29\x82\xd9\xcc\x2a\x74\x44\x50\xa8\xc7\xb5\x61\xd0\x87\xe3\x0e\x0b\xad\xd6\x4f\x58\x16\xe9\xc1\x8f\x01\xf6\x83\x65\x18\x5f\x5d\x9b\x92\x6d\x85\x4d\x4e\xaf\x6c\x60\x7e\xe0\xd2\xcb\x85\x32\x13\xe7\x7d\x2a\x6e\x6e\x41\x7f\x70\x88\x86\x6a\x4c\x3d\xd6\xfa\xc4\xba\x6d\x74\x9e\xe7\xcf\x34\xdb\x19\x6a\x8e\xa4\xa6\xc0\xd2\xfc\xa6\x01\x8e\x53\x29\x80\xde\x03\xda\x73\x8c\xe2\xfb\xef\x52\xbf\x0c\xad\xf8\x68\xcb\x68\x89\x6d\x27\xde\x75\x2a\x58\xbf\x43\x11\x28\xe9\x6d\xc4\xd0\x41\xf3\xe5\x36\x9f\x20\x55\x5b\xa7\x56\x77\xe7\x19\x5b\x8e\x4d\x16\x6b\x7d\x35\x34\x18\xe7\x41\xdb\x1c\x6f\xd0\x29\x4d\xc5\xdb\x8d\xcd\x60\xaf\xe9\x2e\x93\x1f\x1c\x8b\xa1\x73\xb5\xfb\x27\x46\x6a\x39\x5b\x74\x39\x4f\x87\x9b\x9f\x2f\x77\x65\x4f\x1b\xf9\x97\xbb\x39\xfe\x02\x25\x88\x8a\x1e\x27\x2a\xdf\x68\x0c\x15\x79\x50\xbe\xfc\xcd\x38\x3e\x95\xf2\xce\x99\x3a\xe5\x65\x86\x63\xe8\x93\x4b\x38\xb1\xee\x4b\x74\x1a\xfc\xc0\x06\x63\xf2\xb4\xe9\xb8\x74\xea\x05\x9c\xfe\x82\x87\x5f\x00\xbd\x68\x8b\x3d\xff\xa6\x64\xdb\xf3\xdd\x01\xb1\x7d\x02\x0a\xd2\xaf\xca\x6d\xa0\x63\xf3\xe9\x68\x69\xc5\x2f\xd6\x05\xa3\xdd\x0c\x36\xe0\x7b\xbe\x78\xcb\x1d\xa9\x8e\x8b\x3e\xe9\x33\x80\x39\x32\x9e\x19\xcb\x8f\xea\x51\x46\x8d\x51\x7a\x9d\x27\xbd\xf4\xbe\xa6\x00\x1d\xff\xa2\x68\xfc\x61\x20\x3d\xc8\x99\xdf\xf6\xfb\x41\xd4\xf1\x50\x16\x3f\x92\x7d\x74\x28\xe0\x4c\x64\x4a\x68\xaf\x29\x63\xe1\x7a\xba\x68\x61\xb6\x2a\xb9\x76\xec\x73\x76\xa8\x0c\xd5\xbf\x62\xcd\x8f\xf1\x00\xf7\x97\xcf\xb4\xd9\x16\x13\x6f\x95\xd1\x45\xcb\x2a\x5d\x89\x45\xc2\xce\xa3\xdf\x06\xac\xb9\xd4\x4b\xc4\xa7\xc1\xba\x48\xe9\xa8\x1b\xd3\xb0\x19\xf3\xf7\xe4\x6b\x52\x2f\x5e\x44\x8a\x48\xa1\xf7\x4d\xcc\x6f\xae\x07\x82\xe8\x46\x66\x6d\x47\x3c\x0e\x3d\xcd\xc4\x4b\x7c\x8e\x73\x55\xed\xa1\xe4\x9b\xab\x6b\xa5\xae\x54\xf5\x5b\x8e\x73\xea\x39\xfb\x74\xd9\xc8\xec\xed\x7b\x20\xdc\x8f\x47\xf8\x59\x5f\x4c\x19\x0c\xfb\x2f\x4f\x93\xc0\x67\x33\x31\x6a\xd9\xb8\x74\x79\x45\x37\x73\xd7\x96\x70\x94\xa2\xca\xd0\x86\xfe\xcc\x75\xdf\x50\x8a\x00\x9d\x5a\x26\xe7\xed\x6c\x55\xf5\x85\x9d\xfc\xe7\x0a\x2b\x2f\x7e\x9a\xc8\x30\xcd\x54\xb5\x9f\x68\xbc\xf2\x06\x4c\xce\xa7\x7b\x00\x02\x36\x94\xcb\xff\x7e\xb0\xfc\x56\xd3\x70\x6d\x59\xb4\xe3\x49\x02\x7d\x82\xa1\xf7\xa6\x0c\x63\x32\x45\x88\xe2\xd7\xf9\x6d\xd2\xcc\x00\x77\x46\xdc\x45\x9c\xe6\xcd\x15\xf1\x82\x11\x63\x24\x76\x08\x3d\xcc\x6f\x51\xfd\xbf\xe8\xf4\xf0\x39\x81\x82\x98\xff\x63\xc0\xcc\x42\xf5\xb4\xdf\x03\x61\xe6\x87\x47\xd9\x5d\xeb\x9f\x5e\xa4\x8f\x5d\xef\x9b\x60\x6f\x1a\xab\xff\xe6\x1e\xae\x1b\x4b\x6c\xe3\x48\xaa\x3c\xc1\xa2\x27\x3f\x31\x55\x57\x0e\x79\xc5\xd9\xcf\x1c\x47\x7b\x8a\x88\xbe\x03\xa7\xaa\xb5\x19\x3b\xab\xc0\x3e\xb2\x88\x97\xbc\x35\x0b\x07\xbb\x67\x02\x57\x68\x36\x72\x43\xcc\x79\x52\x93\x07\x5b\xab\x2a\x1a\xa7\xde\xb1\x12\x68\xb6\xe4\xfc\xcc\x17\x83\x31\x9b\x0a\x75\x97\x08\xc5\xd3\xa0\xe8\x77\x5f\x25\xa4\x9d\xf9\x47\xf0\x96\x29\x42\x7a\x2e\x36\xe6\x03\xd9\x4f\xc3\x11\x51\xf9\x01\x33\xac\x23\xb2\x8f\x5b\x72\x4a\xa5\x5a\xe0\xb8\x12\xe2\x5b\xf6\xd2\x0f\x6c\xc7\x0e\x36\x92\xfb\x0b\x89\xef\x01\xe5\xf3\x2c\x15\x1b\x09\x26\x94\xf2\xae\x7a\xee\x7c\x96\xaa\x4c\x64\x64\x70\x5c\x8a\xb8\x1f\xed\x9e\xc4\xe3\x0d\x06\xeb\xbe\x35\xae\x75\x90\x0f\x0f\xbd\xff\x4e\xb6\x59\x80\xa4\xfa\xa6\x49\x64\x0d\x54\xfa\x35\x0a\xb2\x54\xd4\x19\xde\xf1\xdb\x6b\x9d\x70\xa6\x4e\xf7\xe5\x91\x1c\x60\xb7\x64\x38\x54\xf7\x58\x0e\xb0\x88\xc3\x6f\xc3\x56\x70\xc4\x0d\xc1\x8a\x23\x7b\x01\xe3\xf7\xcd\x4c\xff\x27\x51\x6a\x01\x0c\x5f\xb5\x20\x3d\x06\xf8\x21\xa1\xbf\xc9\x2d\x19\x38\x18\xfd\x39\xc4\xbe\x88\xa9\xfd\x5c\x1e\x74\xc5\x31\xdb\xd1\xb6\xea\xaf\x7d\xda\xd3\x38\xfa\x39\xe5\x44\xf1\xe9\x27\x8b\x18\xd5\x71\xdc\x29\x6d\x86\x20\xb1\xeb\x98\x04\x3d\x2d\x4b\xce\x03\xfc\x5c\x5c\x41\x50\xf4\x26\x82\x72\xbf\x8b\x63\xce\xa2\xb3\xb6\x45\x9f\xb2\xc5\x6a\x6f\xcc\x2f\x44\x9c\x76\xfd\xd0\xc4\x6a\x8b\x29\x72\xd1\xd7\x71\x3e\x73\x37\xf4\xfd\x6f\x22\xb4\x78\x51\xa3\xe6\xef\x4f\x7f\xa2\xf6\x20\x9d\xd2\x7d\xf7\x00\x05\xbc\xb3\x5d\x4c\xad\xd5\xc1\xa3\xd3\x80\xa5\x9c\x8d\x3f\x39\x82\xcd\xb5\x61\x1a\x5c\xac\xa9\x39\xcc\x35\x52\x21\x3b\x29\xa7\xf4\xff\xe7\xd4\x68\xdb\xff\x62\x14\xa7\x59\xe6\xb5\x22\xad\x93\xcd\xb6\x44\x26\xd8\x60\x4e\x04\xf2\x40\x6f\x6d\x7c\xdd\xf7\x7d\x3d\xc6\x9c\x77\x7f\xf1\x47\xb2\x83\x0e\x2f\x84\x26\x6e\x45\xd1\x7e\xdb\xab\xbc\x75\x55\x22\x99\x5b\x72\x63\x0f\xb1\xc2\xa7\x44\x45\x4f\x4c\xcc\x3d\xcb\x1c\x3b\xde\x48\xfe\x6c\xb5\x12\x9a\xe8\x53\xfc\x16\x2b\xde\xe5\xbf\xdb\x5a\xad\x72\x0f\x44\xdd\xb1\x7d\x75\x4e\x71\x7c\xf8\xa8\x31\x82\x84\x4a\xf0\x4d\x1a\x78\xfe\x4a\x3a\x1e\x08\x50\x75\x98\x51\xa0\xd6\x66\x0d\x7e\xf3\xab\x42\x0d\x84\xf8\x24\x18\x8b\x88\x5e\xfe\x52\x2f\xd9\x79\x3c\xa0\x45\xff\x4e\x39\xfc\x35\xe9\xa2\x50\x5d\xd0\x3b\x14\x47\xbf\xf0\x44\x8d\xc9\xe1\x10\xb4\xa0\x5f\x85\x8c\x8f\x99\xf0\xc6\x8c\xd0\x5d\x86\xe9\x45\xf9\x84\x9c\x8f\x23\xe5\x6a\xf6\xc2\x39\xef\x5e\xf1\x8b\x84\xd2\x16\x56\x2c\x1d\xf5\xb0\xcb\xe2\x45\x7f\x69\xfb\x80\xbc\xcc\x57\xbf\xba\x3a\x0f\x1d\xbb\xf6\xe1\x10\x06\xb4\xc6\x68\xd1\xe1\x4d\x57\x9c\xf6\xcc\xd6\xa7\x2e\xa3\x90\x16\x42\x05\x30\x42\x46\x6c\xf1\xb3\x6e\xb8\xbe\x91\x64\xc6\xd0\x1f\xa5\x87\xa1\xbe\x02\x6e\x5f\x26\xce\x70\x80\x6d\xe2\xec\xd4\x1b\xdd\x16\x39\x66\x0f\x2c\x8f\x41\x40\xe5\x1f\x23\x2a\xa5\x4e\xf7\xb8\xb8\x45\x1a\xe4\x3a\xbd\xdc\xa6\xfd\x43\x2c\xea\x54\x8d\x6c\x73\xce\x5e\x1a\x9a\x0d\x7a\x4f\x89\x2b\xc4\xa3\xdc\xdd\xa1\xeb\xa7\x8f\x4a\xd9\xc4\x62\xa8\xb4\x53\xbf\xbc\x95\x78\xfa\x26\xce\x4d\xe4\x38\x78\x16\x26\x15\x3f\x22\xa8\x1b\x0d\xf5\xde\x8a\x5f\xfb\xe4\x4d\xd9\x55\x2f\xa1\xeb\xa5\x25\x35\xd0\x1e\xdf\x2a\xdb\xf3\x2b\x42\x20\x0e\x95\x6a\x32\x6a\x15\xe4\x1c\xe4\x4c\x7f\x75\x56\x95\xdc\xf2\xbd\x58\xcd\x8d\x13\x63\xe2\xef\x1f\x0d\xa6\xc8\x8f\x7f\x33\x37\xbe\xff\xa3\x01\x34\xee\x30\xbe\xaa\xcf\xd3\xc1\x20\x7a\xa9\x2c\xa6\x2b\xf6\xf8\xba\xdc\x83\x2d\x81\x6c\xd8\x4a\xd0\x86\x88\x68\x4d\xf7\x50\xa0\x40\xd3\x69\x53\xee\x2c\xc5\xf9\x4f\xba\xb0\x70\x23\x1c\xd1\x93\x09\x9f\x93\xfe\x13\xc2\xef\xd0\x50\xe3\x36\x94\x5a\x1d\x7d\xdc\x6c\xf7\x8d\xc8\xc7\xed\xe3\xcb\x21\x69\x1e\x0d\x30\x11\xbc\x34\xba\x83\x49\xb2\x7e\x8a\x00\xd7\x5a\x0a\x4a\xd4\x97\xd0\x6a\xe4\x85\x80\xdf\x8a\xd6\xac\xd8\x5d\x91\xa8\xd3\x80\x56\x5f\x3a\x7c\xc7\x63\x32\x7a\x1b\xc8\x79\x1a\xdf\x1c\x75\x21\xea\xc0\x64\xe9\xa4\xf0\xb3\xf8\x71\x2a\x9d\x6f\xcc\x8f\x5b\x86\xd3\x1f\xe7\xfd\xfc\x75\xcf\x6d\x1f\x7e\xef\x16\xc1\xa2\xd2\xf0\xa5\x9f\x06\x17\x95\x31\xb8\xf6\x96\xce\x72\xf6\x60\xfc\x9d\x15\xda\x0b\xcf\x4c\xc8\xba\xfb\x10\x35\x38\x9c\x89\x80\x64\x85\xb6\xef\x1e\xa1\xb3\xfd\x97\x78\x2e\x3e\x75\xcd\x79\xd0\x61\x50\xe7\x9b\x4f\x84\x4e\x42\xd4\xcf\xd1\x1a\xe0\xaa\x09\x1f\xa2\xb6\x07\xe9\x72\x1a\x38\x6e\x6a\xdc\x2c\x27\x83\xbe\x56\xf0\x97\xec\x5f\x2c\x5c\x87\xd7\xa9\xe9\xad\x33\xcf\x0a\x0b\xa0\xd7\x03\x3f\xa3\x56\x04\x2b\xe5\x59\x1f\x16\x3f\x7d\x24\x3d\x35\xdb\xc6\xcd\x14\x2a\xa6\xdc\x9a\x7e\x77\xf0\xf3\x32\x47\x26\x49\x95\x03\xeb\x26\xce\x8d\x13\x13\x9e\xb5\xa5\x1e\xb1\xc9\x45\xf7\x26\xd4\x9e\x1e\xa3\x3a\x6f\xe7\xa2\xda\xef\x29\x85\xed\xf3\xe9\x68\xb3\xae\x88\xb7\x92\x5f\x2b\x73\xa5\xf1\x3a\xb8\xdc\xef\x01\xb2\x81\x51\xe3\xd2\x5d\xa7\xdc\x1c\xbb\xf0\xa9\xde\x78\x50\xa1\x47\xbd\x5f\xbb\x6a\x0f\xe1\x20\xdf\xed\xaf\x09\xc0\x1b\x65\xe7\x55\x2f\xfa\xea\x13\xcd\x3c\xc6\x18\x1d\xdb\xfb\x6a\x9e\x98\x55\x5c\x21\x24\x6d\x69\x9f\x29\x89\x2c\x8f\xfb\xbe\x14\x67\xfb\xda\x47\x0d\xab\xe4\x60\xbc\x84\x4f\xf4\x4c\x63\xf5\x8e\x12\x16\x5b\xf7\x00\xa0\x4e\x2f\xc5\x19\xb7\xaa\x97\xc1\xbd\x8b\x41\xd3\x43\xd3\x2b\x72\x89\xac\x06\xfc\x56\x29\xc3\xf3\xa1\x79\x6a\x8b\x0e\xc8\xdc\x31\xcf\x64\x3d\xeb\x12\x6e\x17\x12\x5f\x0d\x8c\x19\x39\x0a\x20\x4c\x17\x0f\xb9\x1e\xe9\x65\xc2\xdd\xf4\xfb\x95\xf4\xde\x4d\xb6\xb4\xa0\x40\xfe\x4a\x8a\xf8\xf3\xb2\x9a\xb3\xa4\xb8\x69\xf0\x07\x28\xf9\x90\x77\xed\x01\x3f\xd4\x62\xe0\xd9\x28\x4e\xa9\x13\xd4\x9a\x95\x8c\xf8\x9b\x24\x7a\x57\x68\x3f\xb1\x6c\xf9\x05\x6c\x5c\xc2\x76\xda\xff\x0b\x58\x68\xb7\x9b\xea\xf6\xa9\xab\x4f\x21\x91\xbb\x62\xf2\xe6\xfc\xc5\x99\x15\x11\x93\xae\x86\x28\x78\x8f\x7b\x4a\x8a\x11\x1d\x70\xeb\x6d\xcb\x3e\xf1\xb3\xd9\xeb\x9c\x27\xec\x75\xdc\x40\xf6\xd5\x81\x6b\x62\x1f\x4c\x32\xe4\x70\x4b\x37\xd2\xf1\x7d\x0a\x47\xdb\xfb\xb3\x9b\xcf\xaf\xbe\x74\x7f\xa4\xa4\x5f\x27\xbf\x15\xa5\xa8\xa4\x6e\x49\x7f\xe1\x9a\xc7\xfb\xc8\xb1\xe8\x4a\x84\xc1\xce\x91\x60\xf3\x2e\xbe\xc0\x09\x6a\x6e\x6b\x65\x91\x72\xd6\x84\x9c\xa3\x2c\xf2\x67\x2f\xfc\x64\xe2\x5c\xdb\xc7\xe6\x46\xf0\xcc\x88\x3c\x04\xf7\xee\x05\x8c\x88\x6e\xb0\x4d\xad\x95\xae\x33\x67\xc4\x2c\xee\x6d\x04\xb6\x9a\x82\x09\x91\xc3\xb0\x84\x56\x5c\x61\x39\x78\x7a\x91\xa8\xd2\xff\xc9\x8c\x13\xdc\xeb\x73\xfc\xd1\x4f\x43\x36\x15\x8a\x38\x7e\x75\x84\x24\x77\x5c\xdd\xa9\x77\x82\x04\xc7\x93\xf9\x26\xdf\x2a\x6f\x92\x72\x53\x2e\x32\x95\x07\x98\x4d\x10\x02\x19\xc6\x0d\x4e\x04\xdf\x8c\xd4\xe3\x17\xf5\x72\xef\x6a\x56\xc6\xad\xfc\x2d\xcf\x14\x3d\x7a\xac\x87\x9d\xd4\xc0\xac\xd5\xbe\xaf\x1f\x90\x7e\x97\x67\x14\xc6\x62\xb4\xc1\x30\xf8\xfb\x2b\x3e\x06\x4a\xe6\xc1\x35\x46\x2c\x2f\x5a\x6e\x03\x27\x7e\x76\x2b\x39\xfd\x46\xf7\x79\xf5\x3b\x82\x8e\x4f\xa3\x9e\x44\x53\xc8\xd9\xe6\xe3\x0b\x43\x02\xc5\xab\x97\x8e\x64\x9c\x7b\x94\x32\x94\x6e\x57\x1b\x86\x06\x1d\x45\x96\x9c\x13\x50\xaf\x3a\x54\xaa\x71\x7b\x57\xfa\xb8\xcc\xac\x8e\x12\xe9\xc7\x07\x5c\x5f\x00\xf0\xb4\x39\x4c\xf2\xa3\xc1\x4a\xbf\x87\x32\xb6\xd1\x99\x4c\xcd\x9b\x2d\xf9\x6a\x2b\xeb\x8d\x55\x2d\xe1\x5c\x52\xc1\x24\xfe\x02\x1a\x8c\x74\x8e\x04\x6e\x58\x73\xde\x56\x50\x54\xc3\x75\x78\x8e\xe3\x42\xd0\x87\xd1\x6d\x47\x2e\x62\xf1\xdd\x43\xb5\xc8\x8d\xdc\xf6\xb2\x0a\x06\xfb\x01\xad\x11\x0a\x50\x9d\xca\x73\xa6\x68\x38\xfe\x3d\x40\x70\x1b\xe0\x5c\x0a\xb5\x59\x5e\xfb\x42\xb2\xa2\xf4\xf5\x23\x20\xfb\xa3\xfd\xdb\x1d\x2f\xda\x67\x8e\xf8\xbc\xc4\xbd\x31\x4e\x81\xe8\x62\xd0\xd2\x96\x09\xa3\x21\x56\x64\x6a\xb9\xc4\xe7\x7b\x82\xb8\x79\xdb\x9e\x14\x1d\xda\x89\x5a\x47\xfa\xa8\xdd\x3d\xa1\xd4\x9a\x03\x05\x87\xe4\x7a\xde\x03\x54\xab\xf7\x40\x9f\x77\x50\xf5\x3e\xca\x08\x77\x47\x44\xe3\x3b\x39\xec\x99\xaf\xc7\x15\x42\x0e\x1d\x80\x72\x3a\x3b\x7f\xa3\xca\x31\xa0\x73\x68\xcf\xf3\x91\x54\xf9\x2d\xdc\x62\x4f\xf6\xc4\xa4\x4c\x82\xa3\x90\x93\xba\x2e\x96\x7b\x3a\x6d\xc2\x67\x78\x28\x80\x7f\x76\xbd\xff\x2a\xc3\xb5\x42\xce\x95\xb2\x87\xef\x73\x70\x7b\xfe\x14\xc3\x6f\x0d\x70\xed\xd0\xd6\x2b\xe2\x52\xe6\x8b\x52\x5d\xf1\x8d\x4e\x25\x4f\x69\xc2\x6f\x93\x35\x88\xb6\x87\x63\x17\x23\x1b\x8b\x72\x7f\x77\x07\x69\xf8\x6a\x80\xc3\xa0\x33\x8e\x97\xea\xb1\x99\x0e\xfc\x8a\xfa\x3a\x1a\xb8\x04\x21\xed\x7e\x9e\x97\x8c\x21\x9d\x9f\x97\x97\xf9\x30\x60\x85\xd4\x08\x32\x74\x86\x33\x55\x06\x0a\x63\xec\xc6\x78\x2f\x91\xa5\x25\x89\x59\x5c\x4d\xe1\x65\xde\x64\x67\x0c\x91\xce\x32\x03\x1f\x2f\xfb\x27\x2a\xe6\xac\x58\xf2\x15\x1a\x38\xe1\x84\x7b\x8f\x01\x4e\x4b\xe4\xb1\x8e\x32\x53\x9c\xc4\xab\x42\x42\x6b\xfa\xc4\x72\x04\xfb\x5c\xe3\x84\xca\xa6\x77\x1c\xdb\xec\xa5\x52\x8d\x93\xa0\x8f\xdb\xcc\xc8\xb0\x8b\x1c\x07\x90\x78\x68\x3c\x59\x8c\x2a\xed\x4b\x77\x42\xc5\x46\x5b\x7a\x82\xe9\x58\xa5\xf9\x18\x23\x3a\x22\x87\xba\x84\xef\x81\xb0\x7a\x9d\x7a\x47\xee\xd7\x6d\x9f\x58\x47\x96\x58\xc8\xa6\x72\xbf\x7b\x9d\xc8\x30\xbd\xde\xf7\xed\x2c\xa9\xb6\x62\xf8\x5a\x34\xca\xa3\xc5\xc9\x35\xe6\x86\x5b\xd9\xbe\x28\x32\x32\xe1\xdf\xba\x79\x88\x88\xd2\xf9\x54\x3b\x73\xc4\x5b\x6d\xe1\x30\xa6\xf5\x96\xab\x55\xe2\x74\xf8\x97\xae\x71\xf1\xfe\x3d\x40\x5e\x44\xe4\xee\xf1\xdb\x34\x31\xb9\x98\x46\x7a\x53\x86\x71\x6f\x96\x25\x41\x0f\x52\x5e\xf2\xa7\x84\x1e\x39\xf1\x3a\x77\x25\x1c\x9a\xdd\x45\x8b\xba\x98\xcb\x8a\x5d\x22\xea\x6b\x16\x27\x84\x47\xfd\x81\x31\xf8\x05\x36\x1a\x38\x13\x42\x9b\xe4\xa4\xf7\xac\x52\x45\x08\xdb\x43\x79\x41\x47\xea\xbf\x26\x00\xbf\xee\x2c\x9a\x3b\xa1\xdb\xfd\xde\xe0\x3d\x39\xa8\xde\xac\x84\xbe\xa3\xf0\xaf\x77\x5d\x36\x6f\xcb\x06\xde\x3c\x1b\x56\xcb\x19\x29\xcb\x5f\xf0\x97\x2b\x21\xa5\x58\x34\xa8\xf2\x27\x23\x01\x36\x48\x04\x12\xe4\x83\x08\xaf\xe1\x10\xdf\x82\x0e\xde\xb9\xad\xf4\x0e\x4b\xc5\xf7\xcf\xf0\xf0\x4f\x56\x04\x5f\x67\x29\x74\xb7\xd6\x94\xaa\xa2\xe1\x27\xb5\x26\xb6\x35\xfd\x30\xcb\x26\xe7\x67\x6e\x02\xd9\x16\x82\xa0\x7d\x0f\x5d\xf1\x12\xe8\xe2\xab\xaf\xd4\x0a\x94\x07\x6c\xa5\x77\xfa\xe3\x67\xcf\xb7\xed\x03\xd8\x95\x48\xf8\x45\xac\x24\x71\x05\x81\x1b\xf1\x19\x39\x00\x6b\x2b\xe6\x31\x1e\x66\x27\xf0\x84\x32\xa3\x0c\x1a\xab\x34\x3b\x4e\x30\x8e\x66\xe1\xe2\xef\xcd\xb6\x84\x68\x49\x3e\xf6\xf8\x13\xa4\xf2\x55\x1a\x39\x76\x83\x97\x20\x10\xe6\x02\xbd\x84\x13\x89\x71\x82\x05\xff\x67\x6b\x22\xfa\xbe\x77\xf5\xce\xf9\xb6\xe4\xeb\xdf\x6b\xf1\x68\x77\xb1\x2e\xa5\x42\x1a\x46\x7b\x26\xa0\x88\xc1\x1c\xcf\x46\x63\x83\xc5\xfe\x05\xbf\xed\x7e\x9c\x64\x4d\xa5\x71\x46\xe0\x10\x3d\x8d\xcd\x04\xd9\x7f\x03\x3d\x1f\x3c\xb7\x5b\xce\xfc\xf1\x15\x77\x85\x0e\xd6\x93\xd0\x3f\x97\x58\xec\x17\x90\x93\xed\x95\x54\xe5\x5a\xa6\x0d\x00\xc0\xbe\xd1\x49\x88\xbf\x28\x24\xf2\xc2\x23\xdc\xc7\x5b\x3c\xa7\x2e\x2e\xd5\xd8\x0a\x78\x44\x6c\x6b\xf3\x77\x37\x45\x71\x85\xa9\x42\xa9\xde\xa8\xfb\xa3\xad\x32\x51\xfc\x56\x21\x97\x24\x78\xea\xb4\x6e\xf2\xad\x02\x2a\x60\xf0\xeb\x77\x13\xc6\xe9\x9f\xf5\xae\x6e\x2b\x34\xc8\x7e\xd0\xb7\x10\x5c\xe9\x6d\x0d\x1c\xd5\x7b\x20\xea\xd2\x94\x09\x9a\xae\x4a\x27\x97\x93\x3f\x67\xc1\xd4\x95\x03\xc2\xf2\x98\x62\xb3\x98\xb7\x58\xee\xa4\xeb\xbb\xc3\x99\xbd\x15\x35\x4f\x36\xec\xab\xfa\xf5\x7d\xb6\x2d\xfe\x4b\x80\xbb\xf6\x2d\xf6\x06\x5a\x42\xa0\x18\x37\x98\x5f\x9d\x63\x4a\xb0\x14\x9d\xd9\x2e\xc3\x27\x43\xa4\xf7\x55\x06\x24\x53\x3a\x23\x07\x50\x17\xc4\x44\xa8\x94\xb1\x38\x48\xc4\x94\x4e\x67\x02\x59\x94\x69\xd5\x68\x3f\xb5\xc5\xa3\xe5\x15\x8d\xc6\x04\xe8\xc8\x5e\x7f\x69\x4b\x65\xdd\xda\xca\xd8\xa0\x96\xb6\xb9\xd8\xc6\x2e\xa5\x08\x73\x02\x27\x66\xaf\x90\x73\xa4\x14\xf3\x29\x75\xaa\xf6\x69\xf5\x75\x6e\x99\xde\x47\xc6\xa7\x59\xb6\xd7\x93\xc4\xd2\xf8\x87\x81\x74\xb7\x0a\xce\xa4\x85\x7a\x07\xe5\x94\x5d\xa5\xa4\xfd\xaf\x20\xeb\xd7\x18\x9d\xfc\x8a\x0b\x72\x5c\x3d\x24\x50\xe6\xc5\xd0\x5b\xd9\x99\xed\x53\xd3\xd8\xa3\x0e\x85\x92\x2a\x5b\xc2\x14\x60\x26\x0c\xf3\x00\xac\xd6\x00\x3a\xe1\x5a\x81\x49\x35\x1c\x4c\xcc\x20\x32\x34\xe7\xcc\x5a\x5f\x78\x8d\x04\xc3\x24\x7d\x28\x8b\xff\x6a\xea\x84\x29\x42\xc9\xf8\xb5\x23\x42\x9b\xcf\x4f\x9f\xf7\x3b\x47\xa3\x46\x42\x9d\xd2\x2a\x95\x8d\xf3\x98\x3c\x13\xdc\xba\x3e\x4e\x12\xf9\xf5\x8a\x20\xb8\xd1\xfb\xe6\x8b\x26\xf8\xe4\x03\xf0\x71\x67\xb1\xd1\x9c\x56\x66\x6f\xe6\x2b\x38\x44\xad\x29\xcd\x2a\x9c\x9a\x7e\xfb\x7d\x69\x0d\xeb\x66\x42\xe3\x9f\xfa\x4d\x02\xf1\x88\xa4\x8e\x60\x2f\x01\xc6\xa2\x04\xee\x66\x38\x46\x61\x3a\xe5\x07\x12\x05\xbb\x94\xd0\x41\xc0\x67\x3d\x51\x8a\xe9\xdb\xa1\xce\x89\xbf\x65\xfa\xe3\x2d\xba\x8e\x91\x24\xaa\x1e\x86\xba\x09\xf7\x3c\x88\xc4\x3b\xd7\xd2\xc3\x37\x50\x67\xad\xec\x71\xda\x3a\xaa\x0c\x62\xd7\x1f\x65\x47\x02\x79\x06\x97\xe3\x59\x23\xac\xf2\xe7\xc6\xda\x32\xdb\x75\x3d\x88\xdc\x2e\xb6\x15\x08\x31\x74\x4e\x7d\xbe\xea\x43\x54\xce\x87\x42\x84\x1c\xf3\x59\xeb\xc9\xe1\x14\xc2\x00\xb8\x11\xa5\xf3\x0d\x3d\x54\xab\x4a\x24\xb6\xe3\x3b\xc8\x14\xea\x9c\x7f\xf5\x21\x19\x13\xc3\xde\xe4\xdf\x8e\x01\x09\xfd\xec\x8c\x1c\xa0\x33\xcf\x9a\xa2\x42\x93\x42\x52\xf2\x22\x8c\x17\x19\x6c\xc2\x70\x9a\xb3\xf0\x94\xca\xde\xc0\x71\x72\x5d\xfc\xcb\x1a\x65\xa4\x28\x56\xa8\xc9\xe9\x3d\xe0\x82\xac\x86\x6a\x19\x34\x45\xa2\xfa\xa1\xa6\xbc\xdc\xb3\x6c\x00\xd3\x89\xe7\x1f\x1b\xcc\x55\x2a\x21\x6d\x80\xb3\x74\x2b\x59\x4d\x46\x88\x68\xbe\x84\xce\xd6\x52\x43\x49\x9b\x07\x38\x19\x04\x14\xcf\x58\x02\xb6\xb0\x35\x3b\x16\x05\x0f\xb1\x9f\x78\xfa\x61\x31\xbb\x79\x8f\x60\xfb\x6f\x6e\x31\xd1\xa1\x0b\x4d\x17\xd7\x66\xb9\x77\x1b\x12\x7d\xe4\xe2\xd5\x56\x8b\x02\x4b\xa9\x0f\x8d\x89\x22\xfb\x6c\x9f\x6e\x25\xec\x6a\x2e\x94\x7e\xcc\x16\xd5\xd6\xe0\xf7\x0b\x51\x73\xe3\xc4\xac\x5f\x94\x12\x82\xba\xab\x3d\x25\xca\xea\xfc\xd3\xb3\xc1\xf6\x32\x14\xbd\x98\xab\x54\x85\x6e\xde\x72\x2a\xbd\x82\x1e\xdf\x8d\x9a\xe9\x95\xff\x59\xd0\xd6\x9d\x4f\x9d\xbf\xb8\x07\x0e\x75\x02\x2b\x37\xe9\xd4\xf1\xd0\xf7\x80\xca\x52\xf3\x11\xb9\x62\xd9\xcb\x72\xf7\xd4\xc3\xe4\xe0\x49\xee\xbd\x00\xfe\x05\x5c\x33\xf5\x27\x14\x84\x5e\x14\x20\x70\x58\x83\xf0\xb4\xa0\x22\x4f\xe6\x1b\x6e\xe6\x9d\x78\x67\x4b\xfc\xe0\xdd\x57\x2f\x54\x40\xc1\x46\xce\xb1\x12\xb6\xc4\xf1\x16\x3c\x21\x9b\x16\xcb\x02\x1d\x67\xe0\xe6\xf9\x69\xb0\xed\x93\xf9\x67\x35\xbb\x49\xa0\x9f\xf6\x79\xf3\xfe\x7e\x9b\xab\x3c\xd2\xcb\x42\x9c\x98\x25\x6e\xc1\x9f\xa1\x88\x87\x4d\x59\x83\x52\xe2\xab\x7f\x32\x19\xd7\xbe\xe4\x65\x6e\x21\x59\xa5\xc6\x3a\x07\xbd\xef\x18\xd0\x16\x45\xfb\x0b\x33\x74\x51\xe9\x3f\x76\xc5\x8b\xd2\x2d\x09\xf5\x90\xdf\x5d\xa4\x3e\x80\xe8\xd7\x69\x25\xa4\x8a\x7e\x51\xdd\x84\x8f\x0c\x05\x79\x3a\xa9\x05\x4d\x49\xa7\xd9\xae\xf8\x6b\x9d\x7e\x39\xc5\x63\x6f\x4f\x59\xad\x6b\x19\x96\xe0\x8d\x03\xd7\xf0\xcd\xad\x17\x7b\x68\xd8\xe8\x50\x8d\x61\xe9\xa0\x10\x35\xf3\x98\x42\xea\x06\xa7\xe9\x89\x35\x3d\xc9\x76\x54\xcf\xbe\x94\xb9\xb5\x7f\xb0\x74\x4d\x80\x68\xca\x50\x09\x22\x28\x6c\x6e\x16\x4e\x8e\x7e\xa3\x39\x96\x5d\x56\xe8\xc9\xa4\x0a\x1a\xb6\x5b\x12\x38\xc7\xeb\x61\x70\xcb\x14\x3f\xdd\x70\x68\xfb\xe6\xd7\x8c\xf0\xb0\xe5\xae\xf8\xca\xd1\x92\x91\x42\xbe\x82\xd4\xd1\xe1\xd7\x67\x7e\xba\xe4\xe0\xf8\x0e\xdb\xad\x95\xb7\x33\xcc\xb9\xba\xdc\x67\xe3\x2c\x84\xf5\x71\x97\xe6\x60\x06\x71\x0d\xb0\x29\x2a\x71\x8b\x38\xb9\x5c\x9f\x37\xed\x1d\xd3\x72\xc9\x7a\xf2\xb3\x11\x82\x10\x05\xc6\x4e\xa9\xb4\x71\x9b\x4c\x8e\xd8\x5b\x3f\xa1\xa2\x07\xee\xdf\x87\x4b\x0b\xca\xcc\xb5\x93\x71\x31\xe7\x5a\x87\x8b\xbd\x03\x21\x68\x91\x51\xa1\xce\xbb\x56\x4f\xb6\xf3\x12\x6a\x96\x3a\x66\x8b\x12\xa5\xdd\x53\xc4\xfb\xc6\xcf\x11\x0b\xcf\x92\x0b\xca\x30\x61\xd8\x80\x8f\x49\xce\xe9\xd3\x57\x51\x41\x45\x46\x46\x22\xbb\xcc\x24\xf0\x10\xf7\x04\x49\x51\x84\xcc\x9c\x04\x7b\xd1\xbe\x62\xc8\xf2\x2c\x3b\x67\xfb\xcb\xe3\x71\x8b\xc3\x85\x66\x1b\x38\x2e\x76\x95\x4a\x8f\x0c\x78\xb6\xf8\x2d\x66\xa3\x58\xdc\x34\x86\x99\xaf\x66\xf0\xbe\x8a\x1c\xf0\x68\xda\x37\x26\xfe\x38\x3f\x29\x04\x55\x49\x3a\xc7\x52\x5c\x00\x13\xad\x56\xe8\x69\x63\x2c\x76\x71\x62\x6b\xb6\xf9\xc1\xc1\xbe\xe5\x56\x2a\x32\x6c\xf7\xe3\xe7\x1d\xe9\x32\x69\xd7\xf0\xdb\xf6\x10\x17\x37\x9a\x2c\x97\x5b\x5f\xeb\xee\xc0\xcb\x7d\xc1\xd0\x4c\xe0\xcc\xfe\x1e\x88\xf4\x1d\x55\x20\x35\xe6\x29\xc5\xbc\x4e\xc9\xcb\x0a\x1e\x7a\x26\x70\xe7\xbb\x20\x9c\x53\x06\x1d\xee\x73\xb0\x6a\x69\x6c\x6b\x6d\xd6\xa0\x44\x4a\xf3\xf3\x12\xf3\x13\xcb\x4b\xa5\xfd\xf4\xc4\x9e\x28\x7a\xe0\xd2\xf0\x66\x20\x85\xd5\x53\x87\x86\x02\xb4\x83\x89\x74\x20\x31\x89\x72\x3a\x5a\x22\x07\x29\xe1\xab\x4f\xac\x7f\x23\xce\x39\x9c\xf5\x48\x24\xd1\xb3\x17\xf3\x35\x31\x30\x62\x4b\x7e\xee\x29\x3a\xe8\xd2\x25\x8c\x76\x64\x2c\x1b\x7d\x12\xf9\xb3\x19\xc5\x6c\x84\x21\x79\xbe\x98\xb7\x6f\xa2\xd6\xb4\xc6\x73\xba\x50\xbb\x46\x3d\xe7\x89\xfb\x53\xf5\x1b\x68\x4b\xe1\xe9\xce\xcd\x8d\xc5\x39\x1c\xe2\x89\x92\x1e\x50\x7d\xda\x3f\xe9\xd8\x93\x72\x70\xc2\x74\x50\x40\xff\x94\x86\x2e\x7a\x43\xf7\x93\x11\x74\x78\x98\x91\xaf\xd3\x72\x26\x5d\xc5\xcf\x71\x03\xc2\x2e\x8c\x5a\xe7\x71\x9f\xf0\xca\xa5\x45\x1b\x16\x2f\xaf\x28\x48\x55\xd2\x99\xac\x3d\x23\x62\x7d\x7d\x84\x64\x9d\x26\x37\xde\x69\x6c\xac\x2e\xc0\x8a\x27\xc5\x48\xf8\xd8\x43\x01\x42\x52\x05\x81\x85\x8c\x95\x5f\xb5\x2d\x08\x8d\x1a\x98\xbb\xf5\xd3\xdd\x5c\x6e\xe7\xed\xeb\x4b\x3d\x3a\x35\xba\x07\x20\x6c\x8d\x5d\xf5\x5f\x9d\xd2\x31\x7b\xb9\x60\x3b\xc1\x93\xb8\x23\x0c\xdc\x7b\x7a\x35\xcc\x69\x31\x72\x2c\x02\x4f\xb1\x30\x53\xb8\x13\xd1\x25\x33\xc3\x1b\x59\x25\xc9\x6e\xde\x9c\x89\xf8\xc4\x74\x92\x3e\xe0\x35\x98\xe0\x2d\x79\xa5\xb1\x3d\x23\x63\xc8\xc1\xb1\x57\x3b\xb1\xc8\x30\x43\x7b\xe6\x3e\x77\x1a\x3a\x08\x73\x05\xad\xb5\x20\x4a\xaa\x11\xbe\xf1\x78\x84\x75\x11\x26\x9d\xe6\xf9\xf6\xbf\xb1\xbc\xcc\x21\x7a\x05\xc7\xfe\x87\xfa\x0e\x46\x49\xbe\x47\xba\x97\xdb\x97\x6d\x6c\x39\xb6\x54\x13\xcd\x8d\x11\xe9\x4d\x36\x94\xe7\x5d\xcb\x4a\x9c\xf9\x8b\x7c\x65\x47\xa3\x38\x8b\xb8\xcb\xdb\xca\x02\x74\x79\xb9\xba\xe3\xe6\x92\x23\x9c\x53\x02\x55\x17\x3d\xe9\xe2\x8b\x64\xe0\x9a\xea\xaf\xa6\xf1\x48\x84\xc8\x52\x6b\x30\x74\x79\x8b\x4e\x2a\x5d\xc3\x89\x67\x05\x71\xe1\xf8\xae\x22\x34\x70\xcd\x04\x9b\xff\x55\x61\x2f\xda\x15\x6c\xf8\xcb\xc7\x83\xf2\xaa\xbf\xc7\xaa\x32\x1e\x98\x5b\xfc\xb2\x10\x21\x13\x9e\x56\x93\xb4\x1f\x96\xa2\xda\x9b\xb5\x17\xfb\xb3\x1e\xf5\x73\x41\xa0\x35\x46\xae\x51\x81\x69\x77\xad\xdd\x39\xd6\x3b\x62\xb1\x37\x15\x44\xef\xdc\x19\xb2\x79\x3e\x3c\x87\xe5\xae\x13\x48\xb7\x1f\x5b\x0a\x55\x1e\xc4\xb2\xa9\x9a\x89\x70\xec\xc4\x93\x98\x06\x5b\xd0\x62\x19\x81\xd4\x86\x25\x6d\x6d\xfe\x5a\xd1\x27\xec\xf4\x7e\x63\xfc\x54\x35\xdd\xcb\x4c\xb8\x5c\x62\x11\x36\x8a\x38\x64\x14\x44\xb1\xee\x5f\x3d\x57\x77\xfa\xc8\xf1\x65\x74\x44\x73\x98\xfa\x66\x31\xdf\xdf\xac\x33\x7d\x45\x26\xcf\x21\xf8\x59\xeb\x2e\xba\x33\xdc\xfd\x1e\x20\x2e\x9e\x69\x38\x21\x2e\xbe\x68\x4e\xf6\xa9\x2a\xfe\x94\xf3\xcb\x64\xdb\x13\x0e\x11\x59\xd0\x1d\xe8\x22\x44\x51\xe8\x94\xea\x3e\xe1\x89\xfe\xf1\x58\x97\x99\x34\x17\x74\x5b\x39\x1b\xc8\xe4\x6f\x9c\xa5\xd1\xf6\x9b\xaa\xd6\x82\x4e\x1e\x2b\xca\x05\xa2\xd6\x2a\x84\xcc\x15\x47\x51\x04\xb2\xa1\xfc\x17\x6b\x47\xdb\xbe\xbd\x63\x59\x4d\xc2\x48\x44\x28\x97\x16\x09\xa6\x37\x37\xed\x8e\x63\x91\xb9\x46\x1c\x8e\xf4\xc2\x21\x4d\x48\xcf\x64\xcc\xc7\x58\xa4\x49\x72\xae\x41\x14\x0d\x7a\x9e\xce\x58\x6b\x19\x32\x56\xcd\x2f\x05\x1d\xe7\x6c\x29\x5b\x37\x95\x2c\xb3\xfa\xd3\x9d\x39\xfb\x3f\x0e\xc9\x56\x66\x76\x36\x3c\xc8\x34\x9e\xe8\xec\xe3\xee\x67\x73\xa8\xa9\x9e\x0e\xe1\xc4\x8c\x43\xbf\xa9\xc8\x51\xe8\x6b\xea\x8d\x5a\xa5\x7a\x03\xe3\x0b\x9e\xcb\x97\xac\x9c\xb6\xef\x93\x82\x3c\xa8\xfb\x5a\x73\x44\xb5\xc9\x16\xc5\xf7\x2d\x44\xe3\x9b\xd1\xe5\x56\xe7\x37\x0f\x38\x76\xd5\xb1\x85\x41\xdd\x0c\x8f\x65\x47\x77\x4b\x02\x75\x12\x79\xba\xc8\xa4\x38\xe4\x8d\x01\xa1\x0b\x1e\x02\x40\x79\x0e\x4e\x25\x4a\xb1\x30\x3c\xd4\xab\xce\x49\xd7\x7d\xf7\x0e\xe6\x3e\x4e\x7a\x38\x47\x01\xaa\x2f\xbb\xb5\xeb\x6a\x69\x26\xdf\x33\xa1\x6b\x6b\x0d\xf5\x9a\x13\x84\x1d\xdf\x0a\x27\x1e\x1a\x25\xc6\x48\xb1\x41\x33\x74\x67\x6a\x3c\x7e\xff\xc1\x95\xa5\x1c\xfb\x38\x90\x45\xc7\x76\xcd\xcc\x34\xdc\x6d\x77\xf5\x87\x5c\xf5\xf3\x5c\x03\xda\xf1\xa1\x9c\xde\x16\x00\x3a\x8c\xe9\xf4\x2b\x59\x32\x5e\xf9\x90\x89\xe5\x69\x0e\x65\xcd\xbf\x84\x43\xe8\xd1\xc6\x28\x02\xf5\xb9\xea\xcd\x19\xde\x8d\x94\x35\x6d\xb3\xe0\x3e\x17\xa5\x4b\xcc\x64\x13\x14\x45\xc8\x2b\x42\xf1\xc5\xc9\x6e\x12\x09\x92\x5c\xba\xaf\xc4\xed\x18\x61\xf5\x5a\x70\x9e\xd7\x6e\xd5\x2b\xa1\x17\x0c\xdc\x4b\xfe\x04\x95\x52\xf5\x9b\x7e\xdc\xc3\x5a\x55\xa8\xb8\xd0\xf5\x35\x98\x58\xcc\x28\x8a\xb1\xa4\x4d\x3e\xde\xd5\x6b\xa2\x81\x65\x57\xa8\xda\x48\x61\x50\x91\x97\xe3\xd4\x78\xcc\x30\xef\x23\x52\x02\x19\x03\xa0\x4c\x49\x0e\xd6\x1e\xa3\x9e\xe6\x94\x61\xf2\x88\xb9\x48\x19\x08\x5a\x6e\xf8\x92\x09\x8c\x3c\x6a\x71\x54\xfb\xfd\x36\xe2\xa5\xb3\x8f\x44\x96\xfe\xcb\x23\x70\x04\xb8\x2b\xe0\xb0\xa2\x05\x35\x52\x7b\x7a\xe4\xab\xb0\xd4\xaf\xc0\xc6\xc2\x4f\x91\x34\xd2\x73\x79\x43\xbb\x75\xf9\xe4\xe5\x71\xd7\xdb\x0a\x4a\x7d\xf2\xf7\xa0\xd1\x1e\xe4\x25\x1c\x52\x72\x47\x6c\x47\xe0\xbd\x31\xfe\x4a\x97\xc7\x62\xac\x99\x15\xb1\x6b\x92\x6a\x22\x77\xca\x3b\x66\xef\x8c\x17\xfd\xde\xc8\x67\x96\xca\x84\x6f\x58\x7d\xdf\xa4\xfd\xdf\xd7\x55\x7c\x98\x06\xc7\xe5\xe7\x2e\x8d\x1f\x98\x44\x48\xf8\xa8\x99\xa7\x0d\x09\xcc\x53\x5e\x4b\xaa\xfa\xee\xb8\x74\x53\x1d\x75\x2d\x6d\xd0\x0d\xd1\x7c\xe1\xf9\x4c\x54\xc8\x51\x23\x5d\x0d\x78\xde\x58\xcd\xae\xd9\xd6\xaa\x95\x3e\x9c\xa6\x4d\xdf\x79\xde\x73\x38\xc5\x4a\xaf\x8b\x77\x9a\x68\x48\x8b\x08\x3d\x9e\xc9\xfe\xc4\xfc\x67\xc5\x1a\x41\xb9\xde\x32\x96\x2c\xc3\xc4\x08\x9d\x1d\xbd\xe8\xf4\xfa\xd5\x8f\x9d\xb2\x86\xca\x70\xf2\x8d\xd8\x15\xb9\x95\x36\xd8\x3f\x92\xe2\x80\x36\xec\x27\x4a\xa6\x27\x24\xda\x12\x42\x7d\x68\xe8\xe8\x31\x27\xdd\xb8\xbd\xb7\x9a\xc3\x33\x21\xd4\x2b\x76\xe3\x58\x5a\xcb\xc6\xef\x18\x8c\x23\xf9\xad\xe9\x43\x57\x18\x73\x2f\x8c\xd6\x0f\x33\x0c\x28\x9a\xa8\x68\xb1\x3b\xd3\x4a\x53\x2c\xbc\x5a\x52\xcd\x80\x04\x17\xbe\x6f\x41\x5c\xc0\x66\xb5\xb3\xbf\x26\x32\x88\x7c\x69\xf5\x35\xad\x26\x1d\x5b\xb1\xb9\x34\x57\x99\xc8\x08\xcd\xe1\x42\x67\xe8\x60\xae\x78\x6a\xbf\xf9\x94\x6a\xc3\x59\x71\xe7\x47\x60\xe4\xc8\xfb\x69\x09\xf0\xd3\x7d\xa1\xae\x0b\x22\x54\xb8\x9f\x41\x82\xa3\x93\x8b\xa7\xaf\x17\xc7\x28\x70\x68\x12\x84\x7a\xaa\x9d\xce\x14\xf5\x80\xbc\x43\x71\x02\xd3\xc7\x4e\x89\x79\xc3\xe3\x24\x06\xe8\xac\xf2\x97\x45\xe9\x04\x07\x6d\x7f\x5f\x1f\xf6\xfc\xc1\x6c\xcb\x22\xdd\x7b\x84\x3b\xdc\xa9\x7f\xda\x19\x51\x88\x82\x98\xaa\x1c\xab\x2a\xef\xa3\x92\x74\x20\x9b\xe6\x92\x01\xf6\x53\x47\xc7\xbc\x97\x13\x8e\x68\xf9\xe4\x6f\x34\x04\x8c\x7c\x77\x72\x01\xa2\xa7\xbf\xfb\x0f\x8b\x6d\x4e\x71\xe4\x20\xc1\xd9\x1a\x60\xc3\xe2\x7d\x17\x3d\x43\x05\x7a\xcd\x30\x6d\xea\x65\x6c\x5b\x00\xe8\xd9\x82\x3d\x13\x29\x86\x63\xb4\xac\xd3\x41\x7f\x2e\xf6\x2d\xe4\x1a\xd9\x71\x74\xb9\x78\xbd\xa2\x26\xea\xda\xbd\x15\x5f\x68\x8e\xf1\x57\x70\xde\xcc\x21\x0b\x78\xe1\x62\x04\xff\xc5\x6a\xda\x71\xe4\x0b\x32\x95\xd6\x1f\x2e\x87\x1e\x9a\xb4\xb4\x26\x90\x3f\x19\x88\xeb\x72\xf8\x4c\x54\x49\x3d\x29\xb3\xb1\x7b\x06\x27\x5c\x99\xdb\x82\xd0\x1f\x4c\xf0\x14\x78\xad\xe6\x49\x8e\xfe\x62\x31\xfa\x33\x2d\xee\xb1\x7f\x62\xb2\xbf\x01\xc1\x5a\x82\x5a\x2b\xe8\xe5\x47\x65\xb8\xb7\xe6\xc0\x46\x39\xe6\xbf\x4e\x11\xa0\xc5\x86\xe5\xe7\x74\x20\xf5\xf9\x6c\x3f\x93\x36\x72\x26\x0e\x47\x85\x16\x14\x68\xe5\xf3\xb5\x5d\xc0\xb2\xfb\x32\xf8\x15\x14\x66\x84\x6f\xca\xaa\xd4\xc9\xa0\xa5\xaf\x4f\xbb\xb2\x17\x33\xe3\xb6\x04\x99\x3c\x7d\x33\xa4\x60\xbe\xd3\x38\xe3\x62\x70\xf6\x8f\x00\x77\x34\x0a\x3c\x70\x4c\xae\xf0\x61\xc5\xb0\xfe\xe0\x41\xeb\x72\xd3\x55\xa1\x1f\xf9\xfe\xb0\xf2\x96\xfb\x56\x5e\xf4\x75\xb5\x98\xd1\x54\xb1\x0d\xcd\x80\xeb\x63\xae\xf3\xa7\x6e\x8a\x12\x3f\xda\xa7\x88\xfd\xc5\x67\xfc\xa5\x48\x8f\x8f\xdf\x7e\x11\xe5\xaf\x63\x8f\xbe\x55\x05\xdc\x13\x91\x10\x26\x3b\x7e\xe9\x2b\xef\x70\x64\x63\xbc\x2e\xf4\x81\x93\x8a\xc8\x15\x2b\xc0\x64\x37\xd5\x8a\x7a\x3a\x68\xa8\xf1\x79\x7c\xf3\xb7\x37\xe0\xdf\xc7\xda\x2e\x9d\x6a\x2d\x74\xa4\x42\xc6\xd9\xa3\xa9\x6c\xa1\xe5\x26\x03\x87\x30\xc5\x22\x19\x16\x32\x27\x1e\x44\x09\x8a\x57\x8a\x92\x6c\x24\x15\x85\x04\x71\x1d\xfb\x8b\xa3\x08\x5e\xa0\xe8\x65\x96\x56\x4b\x33\x7d\x07\x86\x89\xa5\xf1\xf7\x1f\xd5\x36\xe5\x28\xa6\x50\x3a\x5c\x8e\xd4\x90\x6b\xa3\x15\xf2\xbf\x0b\x18\xed\x9b\xab\x0a\x5f\x58\x16\x4d\x8b\x02\x4c\xd7\xee\x31\xc0\x05\x56\xee\xf3\xbd\xbe\x22\x44\x5e\x42\xfd\x16\x02\x04\xad\x59\x5b\x31\xc9\xd5\x3f\xa2\x4e\x53\xc9\xbe\x4d\x10\x19\x52\xb0\xb8\x13\x3a\xf6\x7d\xd4\x69\x5d\xad\x5f\x74\x55\xcf\x16\xd3\x5f\x91\x3d\x8d\xd3\xf8\x37\xbb\xa1\x97\x1e\x40\x50\x25\x12\xdb\x8c\x3a\x3b\x69\x22\x7e\x4e\x8e\x24\x47\xef\x7f\x47\x4d\xbc\xf7\x97\x3a\x7d\xb3\x7f\xc2\xdb\x58\xfe\x0e\xf1\xb3\x55\xc2\x25\xb4\x06\xc7\xcd\xbe\x64\xc1\xff\x41\xc9\x61\xe6\x71\x6e\xb9\x6f\x84\x42\xe3\xef\x28\xbd\xe3\xa9\x72\x4a\xeb\x81\x66\x32\xdb\x35\xa6\x16\x7b\x7b\x9f\xe2\x24\x5e\xca\x87\x60\xd6\xb3\x63\x19\xea\x5c\x2e\xd4\xd7\xa6\x58\x6e\x3d\x43\x56\x15\xcf\x66\x9e\x31\x59\x52\x42\x4f\x56\x89\x3f\xdc\xe3\xe6\xf3\xfe\x72\x95\x76\x4f\x25\xbf\x6e\xbf\xaa\x0f\x8f\x9d\xc8\xb0\x6b\xbb\x07\xda\x47\x46\xa7\x5e\x5f\x55\x3b\x13\xfb\xf3\xdf\x03\x61\x09\xee\xd5\x76\x49\x13\x76\xb3\x8a\x4a\x4d\x6e\xbe\x81\x61\xba\xaa\x4f\xfb\xec\x71\xe1\x41\x75\xa3\xcc\xef\x5d\x7a\xc4\xb3\x9f\xce\xc2\xc4\xa4\xf1\xf6\x22\x55\xa3\x6b\x1e\x89\xe6\x6a\x83\x12\x8e\x36\x40\x73\x92\x87\xb1\xe8\x68\xbf\x32\x68\xec\xc0\x55\x20\xfd\x2c\xf2\x9c\x39\x3c\xd4\x48\xd4\xb8\xd7\x90\xde\x7a\x0e\xa3\xad\x9b\xc2\x3e\x19\xfa\xb4\x8f\x3d\x56\x40\xb5\xe1\x25\xb0\xf3\x29\x8f\x5e\x47\xbd\x1f\x02\x69\x6c\x8c\x6b\x1b\xdc\x1a\xbd\xfa\x7d\x75\xce\x7e\x2e\x22\x9d\x61\x07\x9c\x78\xb4\xbb\x3b\x96\xf6\x93\x03\x34\x1a\x18\x60\x4a\x37\x18\x9f\xdc\xdf\x9a\xf6\xff\x00\x0d\xf7\xe5\x7f\xad\x17\xfe\x9f\x23\x29\x9b\x70\x1a\x63\x46\xee\xe1\x9e\x0d\xe6\xc8\x1d\xe7\xb0\x67\xd9\xc1\x95\x30\x49\x1f\x93\xbb\x65\x84\x83\xeb\xaf\xc5\x22\x1b\xe1\x82\x29\x95\x10\x50\x62\x32\xf0\x87\x7b\xec\x8e\x83\x26\x68\x93\x75\x96\x3d\x9e\xb2\xf0\xfc\xd4\x45\x74\x52\x61\xc7\xa4\xb1\xf8\x1e\x18\x8e\xb3\xbc\xc1\x07\xba\xe5\x80\x1f\xff\x7e\xf3\x73\xf5\xb8\xcf\x94\xa7\xc7\x9f\xc3\x89\xda\x5c\xf8\x6a\xf9\xee\x81\x43\x5d\xab\xcd\x06\xbd\x0b\xc3\xb7\x46\x66\xf2\x85\x89\xc5\xee\xf7\x00\xc5\x56\x1c\x5a\x5e\xbf\xa8\x29\xc2\x82\x8e\xa8\xcb\xf9\x34\x4f\xf3\x44\xf7\x16\x1c\xf8\xb4\x83\xcf\xea\xd1\x8e\xc5\x0e\xcc\xeb\x62\x0b\x26\x56\xf1\xb7\xf4\x4a\x04\x11\xcd\x48\xa9\x4e\xbe\x47\x84\x9b\xa0\x90\x06\xa1\x63\xc3\x1b\xf6\xdf\x8d\xd3\x1d\xf7\x1d\x8e\xe4\xf5\xa0\x6b\x65\x6d\x95\x4f\x61\xfe\x02\x07\xf7\x63\x10\x8b\x52\x5e\x8d\xd2\xd4\xf8\xe9\x9c\x9a\x44\x57\x8d\xb2\x65\xe8\xd8\x98\xa8\x77\xf5\x00\x86\x28\x38\x24\xde\xbc\xfe\x57\x41\x1a\xf1\x8f\x91\x3f\xdf\xe8\x12\xec\xe7\xee\xe8\x6f\xc5\xbb\xbf\x5e\xda\x34\xaa\xec\x99\xd0\x99\xfd\x02\x4a\x04\x12\xa0\x17\x08\xe7\x7a\xb4\xe7\xe6\xa1\x52\x73\x75\x9c\x73\xf3\x4f\x1c\x9a\x15\x63\xc9\xce\x2a\xe1\x3a\xdc\xcd\x78\x4d\xb0\x4c\x21\x06\x8c\x6a\x8d\x14\x8b\x9b\x36\x0e\x78\xc6\x25\xf9\xe2\x55\x4c\x9f\x0f\x93\x38\x95\x30\x07\xe3\xc7\x4a\xa1\xe8\xad\x89\x17\x0c\x02\xfd\x19\xcd\x02\x63\x75\x05\x03\x3e\x52\x5d\xd9\x1a\xe0\xc4\x5b\x66\x3c\xd7\xad\x78\x1d\x9b\x15\xd2\xa2\x38\x16\x42\x7e\x7d\xa5\xcb\x5b\xee\xb5\xe7\xd8\xaf\x53\x61\x62\x99\xa8\xee\x30\x2a\x32\x39\xc2\xeb\x94\x7a\xff\x5d\xae\xea\x51\xe0\x4c\x74\x4a\xc8\x62\x0b\x92\x70\x42\xbb\x0d\xf5\x96\x79\xf3\x64\xfe\x57\x82\xbc\x66\xb6\x17\xb3\xaf\xc5\xbe\x0c\x83\x7a\xf4\x1d\xab\x2d\x2d\x05\x31\xe5\xc4\x97\x42\xee\xcf\xbc\x9f\x86\x5c\xdb\x4b\x77\x32\x4f\xe3\xe5\x91\x83\x9a\x87\xf1\x5b\xc6\xdc\xfd\xd7\x54\xc9\x93\xbe\x55\xef\x5f\x2c\x5d\xde\x03\x97\xf8\x97\x27\x60\xff\x67\x73\x3c\x0e\xcc\x2d\xf3\x8e\x0b\x3f\x2e\xee\x50\x99\x6a\x2f\x72\x3b\x20\x03\x8b\x05\x0a\xa5\x2b\xc3\x24\xf1\x16\x1a\x85\x70\x0c\x98\x84\xb7\x2c\x2a\xa1\x90\x82\xeb\xe9\x66\xcb\x03\x43\xb7\x19\x89\x77\x62\x41\x5c\x4b\xa9\x5b\xac\x2a\x8e\x6c\xae\x3e\x24\x93\x60\x05\x7f\xe4\x61\xcc\xcf\x4b\x08\x91\x6d\x66\xa2\xc0\xd2\xc0\x36\xe6\x57\xdf\x3f\x76\xf1\xa5\x21\x1e\xf6\x3e\x8c\xea\x47\xbf\x9d\x85\x86\x68\xd2\x25\x2c\x35\xc0\x61\xe8\xf1\x01\xee\x0a\x39\x1e\x88\x0f\x6f\xbe\x3b\x17\x8c\x55\x36\xaa\x60\xb7\x0c\x99\x57\xed\xf7\xbc\x5f\xe5\x7d\xfd\x69\x7c\x9c\x56\x72\x87\x3c\xbf\xc0\x6c\x05\x3a\x75\xd3\x29\xb6\xda\x20\x2d\x06\xab\x29\x47\x9e\x35\x45\x68\xc7\x3e\x74\x46\xe2\x65\x25\x1a\x6c\xec\xc8\xad\x2b\x63\xc6\x4f\x56\x9d\x77\x19\xa3\x86\x49\x0c\x67\x14\xb3\xd4\x00\x77\x25\xa4\xe9\xdc\x0d\x3d\x79\xf1\x15\xfe\x49\xf6\xcd\xb7\xb8\x18\x43\xba\xc6\x8e\x46\xa5\x8c\xc2\xb8\xe0\x7d\x1d\x77\x19\x46\xf6\x2d\xe7\xe0\x69\x53\x53\x55\x6f\x6b\x51\x22\xee\xf4\xc7\x49\xc1\xee\xb9\xd9\x8c\x97\x7d\x87\xb9\x38\x9f\x4f\x4b\x22\xe9\x9f\xf3\x0d\x2d\x4f\x7c\x2f\x26\x95\xe8\xf9\x12\x7d\xf0\xa0\xbb\x94\xb1\xf1\xa2\xa6\xb9\x62\xd9\x66\x59\x6e\xe2\xcf\x76\xf0\xc3\x70\x25\xb6\x24\x81\xe3\x09\x68\x50\x18\xf6\x62\x62\x87\xe7\xa3\x56\x1f\x32\x3a\xa8\x5e\x58\x7c\xc4\x71\x8c\x40\x03\xb1\xd8\xc6\xae\xe8\xdd\x07\xd0\x21\x23\x68\x76\x73\x4e\xe2\x89\x15\x21\xdf\x07\x53\x1e\x7a\xc6\x8e\x33\xfb\x8a\xb2\x8d\xe8\x77\xe1\x9a\x32\x20\x79\x80\x92\xfd\xdf\xd9\x23\x25\xf6\x36\x81\xbb\x35\x0f\x4f\x45\xef\x74\x0d\xee\x94\x5d\x6e\xe8\x2c\x4c\x42\x61\x93\x2d\xf2\x35\x4a\xaa\xb1\x48\xac\xe3\x75\x8a\x13\xa9\x14\x7f\x77\x06\xe5\x71\x67\xe5\x80\x84\xe2\xfa\x69\x8c\xbf\x75\x63\x47\x82\x2e\xd5\x0d\x0c\x47\x9b\x03\xa6\xa6\x40\xef\x31\x72\x8d\x70\x08\x1f\x48\xe6\x26\xde\x82\x49\xfc\xde\xba\x84\x67\xf5\x11\xb9\x50\xbe\x94\x65\x76\x1c\xae\x95\x60\xda\x35\x92\xcc\x0b\xf3\xc8\xca\x21\x9b\xbd\x07\x74\x16\x6b\x5e\x93\x26\xb3\x0e\xb3\xf7\x70\xe7\x6e\xdc\x03\xbc\xdc\xdf\xfc\x0d\xcd\x3c\x9f\x12\x99\x2e\xe7\xf7\x77\x3c\x69\x3e\x8c\x8b\xf9\xf5\xbb\x9f\x64\x9f\xb6\xba\x71\xf8\xea\x22\x6e\xd4\x31\x5d\x6b\x2e\x09\xc7\x37\x04\x74\x98\x7c\xf3\x5b\x03\x67\x21\xb5\x6a\x5f\x8c\x63\x20\xdf\x3e\x3f\x2c\x65\xf6\x12\x83\xdf\x10\x86\xf1\x8c\x41\x7d\x47\xdf\x94\xf2\xc2\xaa\x11\x85\x69\x4f\x6e\x28\x78\x35\x0b\xc7\xb4\x61\x63\x75\xcf\x3e\xbf\x28\x67\xe9\x68\xf8\x7a\xab\x50\xca\x84\xbb\x57\xdf\xa0\x53\xe3\xbf\x04\xe0\x57\x09\xcc\xff\x11\x3b\x37\x86\x0c\xb6\xb2\x87\xf6\xc7\xd3\xbd\xd3\x9f\x8f\xb3\x38\x87\x13\x2b\x6c\xf2\xa6\xf2\x96\x57\xd0\x25\x75\xb7\xe9\x8e\xa7\xc0\x43\x8f\x4d\x15\xf5\x97\x8b\xab\x82\xb8\x90\x52\x7f\xb8\xc7\xa4\xf0\x56\x5e\x08\x52\xa6\x29\xf0\xa8\xc9\x8b\xb9\x9b\xf4\x4c\xbe\xf8\xed\x3b\x8d\x1d\xfc\x9a\x57\xca\xf9\x9d\x36\x5b\xa7\x62\x06\x6f\x0f\xc8\x68\x38\xda\xdf\xda\xbe\xd8\xe6\xc1\xa2\x0a\xb3\x3e\x6b\x7c\x93\x87\xa8\x73\x31\xe0\x93\x18\x77\x82\x90\x70\x47\x11\x35\xc4\x52\x92\x7d\x5b\xda\xa4\x4f\x71\xa9\xfe\x8e\x94\xb8\x63\xe9\x34\xec\x5b\x7b\xd0\x34\xf3\xa4\x8e\xd0\x4c\xc0\x6d\x9b\xf0\x7d\xc7\xfa\xc6\xd5\x27\x57\xd6\x35\x7b\xb1\x60\xab\x94\xb3\x17\x63\xa5\x22\x43\xea\x42\xc7\xa7\xe1\xb8\x7c\x31\x40\x86\x33\xbd\xd6\x34\xa7\x20\x28\x63\x8b\xc8\x6b\xae\x7f\xf9\xd5\x4d\x3c\xd2\x5c\x24\xc2\x35\x57\xef\x0a\x73\xad\x43\xa5\xaf\xed\x7d\x21\x8a\x63\xe0\x64\x8b\xc1\xb2\x7d\xbf\x6c\x5b\xd6\x69\xf7\xf1\x22\x0c\xc7\x97\x98\xdb\x7d\xf8\x3a\xe8\x34\x13\x3d\xbb\xd2\xa7\xe3\xa4\xda\x59\x88\xf7\x94\x21\x20\xa8\x1d\x1d\x64\x70\xd1\x4d\xbc\xa7\xd3\xc6\x98\x9b\xde\x54\x17\x16\xaf\x80\xb9\x06\x7b\xba\xa4\xf7\xd2\x9a\x5a\x31\x59\x5b\xa6\x07\x30\xc3\x6f\x96\x7b\x68\x06\x66\xd3\xc0\x98\x59\xcb\x64\x7b\x33\x1d\x8a\x9e\x2b\xfb\x6b\x23\xfd\xa9\xf1\x8c\xa3\xd0\x04\x97\x1f\x5d\x4b\xda\x56\x1a\x7e\x92\x1c\x94\xad\xb2\xd2\x9f\x13\x45\x56\xc5\x5e\x23\x38\xec\x02\x24\xe5\x25\x59\xff\xd2\x9d\xb9\x1c\xf6\x7f\x71\x3a\xef\x7b\x15\xfa\x74\xb4\x4d\x71\x91\xd9\xa2\x0c\x4e\xb4\x0a\xd1\x0d\xd5\x9b\x33\x6f\x0d\xef\x07\x1b\x65\x33\x46\x34\x72\xf7\x75\x91\xa3\x53\x1c\x9f\x9a\xe4\xf5\x7b\x1f\xf5\xaa\x19\x60\xfc\x71\xcd\x8d\xe8\x9c\xa7\x8f\x9b\xfe\x6b\x19\x54\xd5\x52\x97\xda\x0c\xf7\x27\x91\x58\x0c\x20\x93\x2f\x0f\x60\x94\xdb\x2d\x17\x97\x24\x96\x8e\xfb\xf9\xf1\x0f\x12\xda\xe9\x7f\x4a\xe0\xba\x74\x35\x11\x38\xb5\x9a\x8a\xfd\x79\x6c\x9e\x8e\x82\xd7\x85\x3e\x69\xc4\x51\xe1\x43\xe6\xba\x5e\x1c\xca\x30\x8a\x23\x57\xbd\x35\x50\xaf\xee\x81\x95\xba\x5f\x33\x7a\x7a\xad\xbf\xf9\x3f\xca\xca\x08\xc0\x06\x76\x53\x5c\xd7\x8b\x7d\x15\xfa\x99\x18\x57\xec\x97\xdd\x0c\xbe\x8c\x64\xd4\xdd\xd6\x84\xc6\xfd\x8e\x39\x16\x3c\x21\xb4\x5d\x7e\x9f\x22\x88\x7e\x32\x37\x4a\xd0\x50\x6e\xd2\xd5\x8a\x80\xa0\xba\xc3\x76\xd0\xde\x5b\xdc\xaa\xce\x72\xb6\xac\xf5\xde\x6c\x43\xb0\x9c\x52\x51\xe6\xbc\x97\x32\x4c\x72\x18\xb8\x23\xc5\x35\xde\x7d\x8c\x6c\x4d\xa8\x47\xb1\xd8\x47\x44\xfd\x4f\x99\x91\x5c\x7e\xa1\xc6\xb8\xff\x3e\x35\x2d\x3a\x51\xf9\x4f\xfc\xde\x7f\x11\xd4\x7f\xdd\x4d\xf2\xb1\x2d\xe4\x65\x0c\x70\x96\x17\x43\xca\x74\xfc\x84\x56\x46\x39\xb1\xc1\xbd\xd1\x2d\xc0\x7e\xb6\x61\x1d\x7d\x1e\x4b\x74\xcb\xda\xe8\xb3\x38\x68\xb3\x2c\xae\xc2\x1d\x9e\x6a\x3f\x28\xb5\xa1\x02\xba\x07\x16\x6b\xfa\xfb\xde\xa8\xf0\xa6\x92\xa4\xcb\x3e\xc4\x8c\x60\xfc\x00\x9a\xf9\x87\x94\x1a\x94\xb8\x15\x20\xe4\x69\x0a\x31\x31\x10\x7c\xff\x62\x26\xa7\xa2\x65\x54\xb2\x2e\x97\x7b\xb2\x8b\xd2\x8e\x7f\x59\xc5\xa7\xd0\x28\xfa\x65\xef\x23\x85\x8f\xc1\xae\xb9\xdf\x03\x29\x0f\xc3\x2c\xcd\x3b\x4c\xb7\x84\xf3\x38\xc2\x24\x64\x1d\xb7\x0c\x49\xd9\x5c\xc6\xb6\xd5\x77\xce\xd3\xaf\x6f\x90\xfb\x32\x8c\xd3\xa5\x2e\x13\x4f\xdc\x4d\x28\x51\x72\x79\x51\x82\x7b\xbb\xcd\x81\x15\x78\x6f\xe6\x75\x55\x32\xff\x9d\x4f\xe5\x1e\x09\xe4\xb7\x4f\x94\xd0\xe9\xa2\xfb\x6c\x4b\x6b\x9f\xfe\x65\xfc\x81\x46\x67\xcb\xb0\x54\xcb\x15\x42\x1e\x85\xd3\x6d\x0d\xdf\x4f\x35\x5e\x55\x2e\xab\x2b\x67\xe5\xa0\x91\x4a\x3b\xff\x11\xc9\x5b\x88\xc2\x1c\x0e\x5a\xfe\x2c\x58\x4d\xa1\x15\x67\xb1\xd3\xb7\x1b\x7c\x01\x87\xa8\xce\xf0\x3c\x3a\x6d\x0e\xf9\xd1\x42\xca\xd7\x12\x43\xa6\x46\xce\x5e\x8b\x0b\xc6\x68\xc9\x8b\xa0\xf3\x0c\xa2\x31\xb5\x7b\xc0\x3f\xce\x3a\x9c\x3e\x50\x1a\x3f\x70\x0e\xf3\xd5\x6d\xa6\xc3\xca\x53\x49\x59\x5a\xe4\xda\x6f\x08\x9d\xed\x78\x60\x34\x27\x64\x1a\x29\xc5\x1a\x6a\x18\xcc\xf6\x51\x29\x15\x4a\xd3\xab\xa3\xa5\x20\xfb\xed\xb7\x9f\x06\x78\x46\x23\xb8\xd6\x0c\x15\x93\xd9\xca\x44\x88\x46\xca\x2d\x56\x59\xa4\x4c\xde\x3d\x70\x83\x37\xf8\x45\xec\x5c\xb1\x34\x3f\x5a\x38\x7a\x32\xdd\xb1\xa8\x59\x00\x4a\xd1\x87\x0d\x02\xb6\x9a\x26\xf6\x7e\xa8\xfa\xbe\xa6\x8c\x1f\xf3\xea\x3c\x30\xcf\x4f\xe4\x9c\x92\xa2\x95\x77\x0c\xe8\x4f\x85\x87\xbf\xbf\xf2\x9a\x2b\x51\xe4\x65\x78\x6b\x1e\x4e\x00\xde\x0a\xd4\x08\x5c\xf4\xf6\x28\x71\x7d\x91\x62\x5d\xab\xff\x33\x6b\x7a\xae\x1a\x85\xc0\x75\x53\xbb\x0b\x06\xfb\x2d\xf9\xf0\x62\x03\x89\xd8\xb2\x65\x15\xae\x6c\x0a\xf2\x04\xa9\x96\xa9\x1d\x13\xd2\x2d\x26\x2a\x05\x24\x13\x83\xa1\x89\xc9\x33\x31\xc7\x5a\x8c\xe7\x72\xdc\xc9\x27\xc9\x07\x36\x98\x7b\x53\x78\x82\x87\x9b\xbf\x35\xdd\x9f\xa5\x8d\x61\x76\x53\x8f\x54\x8a\xad\x47\x0b\x4e\x60\xcc\x4d\xcd\xf3\x22\x83\x21\x98\xae\x3b\x9d\xb0\x13\x13\x9e\x7b\x80\xf2\xd2\xaf\x35\xb0\x1f\xae\x37\x4c\x61\x53\x68\x3f\xb6\xe4\x7d\x7c\x96\xf0\xa1\x0e\xfa\x7c\xa0\x8b\xa7\xbd\xb1\xed\x6b\x0d\xe1\x27\x51\xab\xf7\xec\xc0\x01\x74\x12\xd4\x3b\x04\x0c\x02\x36\xc6\x76\xbe\x89\x83\xf1\x56\x47\x55\xc5\xb9\x8b\x32\xc1\xb5\x5f\x2a\x20\xb9\x50\x51\xd1\x9b\xdf\x17\x08\xbd\x69\x41\x02\x63\xe2\x51\xb3\xe6\x78\xd9\x03\x45\x0d\x7e\xbf\x6c\x7c\x63\x02\xd9\xfa\x19\x47\x2a\x3a\x3d\x32\x21\xfa\x4d\x79\x6e\xf3\x7f\x32\x59\x72\x22\x07\xf8\x38\x0f\xa9\x80\x8d\x85\xe7\xde\xaa\xe6\xed\x9d\x85\xac\xd4\x67\x27\x7c\xec\xb9\x59\xf4\xde\xac\xdc\x99\xf7\xe0\x56\x09\xf7\x74\x44\x85\x28\xe7\x0a\x24\xd8\xe6\x72\xcf\xdd\x03\x0d\x1d\xa2\x3e\xb8\xf8\x46\x8f\x76\x56\xa9\x03\x15\x24\x21\x94\x43\xb7\x2c\x5f\x33\x8d\x69\x91\xaa\x1f\x41\x4f\xb2\xbf\x84\x61\xae\xdc\x68\x80\x0b\x27\x83\x91\x66\x7e\x31\xbf\x0c\x07\xc4\x1e\xe5\x15\xdf\xbe\x6a\xad\xff\x38\xfe\xa4\xe3\xdc\xc9\x26\x6d\x8c\x53\xf4\xa7\xba\xc9\xe5\xa5\x11\xec\x83\xb8\xef\xe2\x94\x29\xa5\xe0\xa8\x43\xc7\xbb\xab\x9d\xd7\xf2\x07\x74\x3b\x1b\xc8\xee\x20\xa3\x69\xf0\x67\xa8\xb5\x5c\xed\xdc\xc5\xb7\xd9\x59\x8a\x57\xdc\xb9\xe2\xb9\xad\x53\xbe\xc8\x3b\x3e\xb4\x53\x80\x7a\xdf\x99\x91\x21\x86\x65\xe8\x0f\x66\x7a\xd7\xe4\xbc\x39\xa1\x25\x34\xff\x9e\x09\xda\x6e\xcc\xc5\xcd\xe0\x61\x2e\x9f\xa1\xb7\xf0\xbe\x3b\xe6\x20\xf3\x58\x2d\x2b\x05\x68\xc7\x14\xcc\x16\x86\x76\x34\xa7\x26\x2b\x64\x40\x23\x25\x16\x0b\xec\xae\x51\xfb\x57\x5b\x4a\xd4\x9c\x16\x71\xb9\x21\x1d\x9f\x05\xa4\x83\x03\x99\x55\x9c\x8e\xc9\xf6\x33\x8a\x28\xb4\x7b\x96\xbe\x91\x49\x15\x34\x77\xb1\xd9\xfb\xba\x9c\x56\x16\x2d\x72\xb2\xb1\x49\x28\xd3\xfd\x60\xb3\x06\x97\x21\xa5\x4d\x3e\x80\x7a\xed\x0c\x6a\x5a\x51\xe4\x03\xde\x3a\x54\x0f\x04\x96\x6c\x75\xc2\xca\xa1\xd1\x44\x8f\x27\xc5\xee\x3c\x43\x2b\x6e\x79\xe7\xb7\x92\x99\xeb\xdb\x3f\x46\x4a\x77\x9c\x1b\x32\x27\x96\xfa\x66\x6d\x76\xc7\xf3\x08\x4a\xbe\xdf\x22\x7a\xa1\xad\xc8\xbb\xee\xef\xf6\x78\x2c\x5f\xf2\xa5\xaf\x6e\xc7\xca\xb8\x45\x79\xd5\x73\xaf\x66\xbe\xb6\xda\x5f\xca\x49\xda\x65\x98\xbb\x2d\x27\x12\xef\x36\xa8\x98\x1c\xfd\x12\xeb\x8f\x19\xf5\xa3\x09\x06\x44\xf7\xdc\x67\x3b\xb3\x7a\xa4\x49\xab\x6e\xd5\x99\x92\x8e\x58\xdb\xe5\xb0\x53\x6b\xec\x2b\xe7\x9f\x38\x58\xd5\x5a\xb5\x24\x08\x1b\xf9\xf7\xc2\x86\xc4\x17\x27\x33\x8d\x57\x0b\x6e\xd5\x92\x05\x15\x33\xc5\x75\xb2\x03\x8f\xac\x00\xd1\x5d\x91\x91\x21\x1b\xcc\x03\x6d\xb3\xfe\x98\xea\x72\xa3\xea\xdc\x1c\x57\x97\xe3\x06\x05\x3a\xe1\xc0\x50\x54\xe9\x72\x9d\x0d\x49\x6e\xcb\x8f\x96\xf5\x58\xdd\x29\xeb\x0d\x82\xe3\x94\xa8\x65\x1d\xc5\xde\xcb\x71\x62\x69\x65\x60\x27\x90\x4c\x2f\xa0\xed\xfc\xcd\xe2\x0f\xf6\x92\xf6\x4f\x9f\x57\x9e\xe1\x62\x5d\x20\xde\x51\x6b\x4f\xba\x60\xbb\xe6\x11\x55\xa5\xcf\xf5\xe9\x70\x52\x60\xee\x44\x88\xfc\x54\xf5\x12\x08\x99\x16\x0b\x4e\x79\x9b\xd0\x02\x27\x7e\x39\xb0\x26\x56\x3f\xf7\x76\x79\xe9\x7b\xcf\x75\x0d\xdd\xb8\x0e\x5b\x88\x82\x43\x62\x20\x77\x70\xf7\x82\x84\x61\xd9\x92\xe1\xb8\x60\x6a\x58\x52\xc8\xa8\x4d\x56\x06\xd6\xb5\x43\xe0\x47\x84\x38\x6a\xbe\x7e\x3f\xf0\x61\x0e\xdb\x59\x6c\xa4\x59\x5c\x85\x5b\x7f\xa9\xe8\x56\xf1\x4c\xd7\x23\xbb\x65\xb5\x68\xfc\x0f\x31\x66\x55\xb2\x93\x81\x66\x62\x10\x8b\x0b\x38\xd1\xa1\x74\xd4\xf2\x50\xc6\x96\x34\x8b\xed\x4f\xda\x51\xfa\x13\x7d\x1c\x7d\x79\x5f\xd8\x33\x17\xbe\xd9\xce\xdd\xfe\xcc\xcb\xa6\xce\x92\x61\x77\xe7\x67\xa9\xac\xb9\xcf\x64\xaf\x19\x2a\x91\xc6\xea\xfa\xa9\x7a\x8b\x3b\xdd\x79\x0f\x2d\xdd\x56\xc4\xc2\x71\x3a\xdb\x37\x9a\xaa\x99\xa5\x54\xd2\x08\x1e\x23\x13\x3a\x5c\x13\x38\x31\x57\x6d\xe0\x1e\x05\x30\x7c\xfb\x32\x2b\xe6\x0b\xc1\x83\x97\xb3\x30\x29\x37\x54\xd6\xa3\x70\x94\xd3\xd0\x16\x98\xf3\x98\x2b\xc2\x89\x2f\x74\x30\x80\xc0\xea\x69\x96\x2d\xdd\xae\xa8\xa6\xa9\xa4\xbf\xbd\xb6\x29\x55\xaf\xa0\x63\x13\xd2\xad\x4c\x9b\x66\x8a\x39\xd4\xe4\x78\xb3\xd9\x7a\xa6\x3a\x96\xbc\x7d\xdc\x68\x17\xa1\x0c\x7c\xfb\x7b\x97\x31\x32\x29\x30\x61\x85\x8e\x54\xa6\x9d\x0c\xf7\x79\x97\x53\x62\xf3\x09\x93\xd0\x35\xd9\xe0\x83\x06\x78\x32\x88\xa8\x51\x1c\x81\x87\x1e\xbd\xa0\x9b\x98\x1e\xf8\x39\x5a\x37\x82\xe9\x22\x41\x7a\x98\x79\xf3\xe8\x31\x56\x72\x04\x58\x94\x72\xb3\x9b\x46\x42\xf8\xc6\x29\x9f\x29\xba\xda\xe8\x57\x70\xf0\x5b\x5c\x11\x33\xb7\x80\x09\x5f\x5d\x58\x63\x7d\x0d\xda\x6e\x01\x35\xad\xc0\x0a\xe7\x85\xed\x82\x3b\x01\x4f\x8f\xff\xed\x5a\x2c\xfe\xfb\x07\xf3\x20\xca\xc0\xf9\x7a\xcc\x42\xb4\xfb\x66\xa9\x2b\x57\xe1\xc0\xc1\x46\xda\x94\xef\xf4\x29\xf6\x74\xcb\x74\x75\x96\x97\x1e\x7c\x75\x48\x5a\x39\x63\x68\xe1\xfd\x75\xbf\x58\xd8\x6b\xd0\x9f\x15\xd2\x6c\xcf\x41\xf7\x6e\x42\x4f\x76\x31\x7f\xaa\x38\xd9\x64\x1c\xbc\x35\x62\x1b\xcc\xb9\x3d\xf8\x3f\x7c\x2f\xed\xae\xcf\x11\x37\xab\xf9\xb9\x42\xc9\x74\x15\xb5\x23\x42\x76\x31\xc0\xe9\x14\x09\x54\x5a\xe3\x94\xb1\x76\x79\x3d\x22\xac\xdb\xca\xa1\x61\xda\xe9\x97\xc2\x8c\xcc\xbe\xf1\x7a\xd8\x6d\xd0\xbb\x6a\x43\x8e\x1c\xe6\x08\x24\x93\x18\xdf\x5e\x60\x27\xf7\xe7\x96\xe6\x84\x2d\x61\x05\x8d\x9e\x38\x12\xbf\xc5\xcc\xc3\x75\x22\xc3\xe3\xa9\x80\xc2\x2c\xe8\xfb\xd4\x08\xc2\x30\x33\x3f\x33\xe4\x05\x1c\xf2\x5a\xa9\x30\x59\x56\x41\x0b\x92\x5f\xba\xed\xbb\x18\xcd\x05\x5d\x57\x80\x16\x44\x8c\x29\x68\x9e\xa5\xeb\x47\x53\x5f\x17\x49\x49\xa1\x24\xe3\x0f\xe5\x84\x73\xb8\xb9\xb6\xc9\xa7\x38\x50\x70\x88\xd3\x48\xa1\xcb\x25\x82\xd2\x39\xb6\x79\x86\xfb\x4f\xa1\x8a\xcb\x98\x28\x69\xd3\x51\x36\x12\x71\xa8\x39\x85\x7a\xa3\x99\x8e\x43\xb5\x30\xc9\x31\x49\x29\xec\x22\x72\x77\xe5\xbb\x3d\x0d\x6e\x98\xf0\x24\x24\xf8\xc4\xa6\xcd\xf8\xa3\xb5\xda\x7e\xd8\x57\x3e\xd5\xe9\x4c\xd5\x85\x52\x46\xa2\x99\x86\xb5\xf6\x52\x68\x27\x69\x1d\x8d\x1c\xe0\xab\xde\x7e\x21\x1e\xf4\x11\x56\xcf\x4a\xa6\x9b\x20\x73\x0f\x5c\xea\x44\x46\xdc\x31\x1c\x88\x45\xc0\x17\xbb\xd8\x83\x9a\x94\xbe\x62\x86\x50\x4a\x85\x0a\x82\xa6\x0e\x74\xc5\x10\x03\x9d\x2e\x3e\xfc\x62\xfb\xc9\x8a\xc2\x43\x63\x38\xc8\x0b\xa1\xc3\x35\xc2\xd3\x22\x31\xaa\xdc\x07\x47\x87\x14\xd5\x39\xdb\xa0\x73\x37\x9f\xea\x6a\x81\x17\x75\x73\x49\x04\x7e\x50\x24\xb3\xc5\x8e\x06\xf7\x5b\x40\x4c\x03\x83\x6b\xc3\xbc\xdc\xce\x40\x35\xbd\xda\x79\xdb\x64\x45\x41\x22\x68\xd5\x73\xa4\xf2\x42\x03\x1c\xe9\x2f\x87\x56\x2f\xd6\xdf\xcf\x30\x98\xcc\x72\xe6\x57\x22\x59\x7b\xd7\xfc\x50\x5e\x52\x81\xa1\xce\x84\x83\x28\x75\xf5\xfb\xb2\x4f\x06\xef\xbe\x38\x8c\x4c\x97\xd5\x1b\x51\x76\x10\x64\xf0\xdb\x1c\x9a\x6e\xf3\x89\xe1\x25\x37\x21\x89\xdf\xe2\x14\xed\x75\x84\xc7\x0a\x24\xca\xf4\x7d\xdd\xdc\x78\x91\x5b\x25\xee\x07\x86\xba\x7a\xb3\xdd\x84\xef\x1e\xfb\x32\xb4\xf7\xc0\x69\x61\x83\xf5\x67\xfd\x87\x2d\xad\xf1\x93\x04\x0c\x4b\xc8\x16\xc6\xb4\x9e\xfd\x3c\x62\x96\x85\xc6\x68\x78\x6d\xf7\xa3\x65\x61\x51\xf7\x9c\x6f\xe0\x7c\x2c\xc8\x64\x57\xec\xd7\x13\xdd\xd7\xa7\xf1\xab\xa3\x4c\x07\x70\x0b\x98\x9a\xaf\x9f\x6e\xde\x2d\xff\x74\xed\x35\x6d\xa8\x80\x22\x1b\x87\xbd\x18\xcc\x7d\xbd\x94\xa3\xd9\x00\x38\x5f\xc7\x82\x3e\x50\x9f\x97\x70\xf7\x2b\x3e\xe0\x13\xac\x33\x48\xc1\xb1\x64\xe2\x23\xda\xe3\x5e\xcb\x47\xbb\x6e\x0e\x6a\x33\x2d\xed\x51\xb8\x37\x2a\x11\xfc\x82\x54\xfb\xfc\x0c\xb6\x49\x37\xa5\x3e\x09\x11\x90\xda\x57\x32\xa7\x70\x34\x8a\xdb\xc8\xf6\x44\xb8\x32\x70\x62\xf2\xae\xf7\xb7\x19\x57\xe2\x44\x8c\x61\xbd\xeb\x61\xe1\xcb\x53\x9e\x55\x4c\xc6\xa1\x94\x61\xec\xcb\xfb\xcf\xc3\x30\xe1\x57\x64\xf2\x23\xbe\xcf\x7a\x11\xe4\xa7\x37\xf7\x40\xdf\x63\x94\x5d\x00\x17\x2b\x73\xc8\x11\x99\x4a\xdc\x4f\x49\x79\x48\x2d\xc2\x09\x41\x81\x2e\x27\x99\x95\xf0\x86\x1f\x92\x0c\x69\xe7\xca\x30\xf4\xf6\x48\x04\xdf\xd6\xc9\x30\xce\x13\xeb\x74\x0c\x23\x19\x63\x78\xfd\x25\x32\xb3\x75\x4e\xc7\x85\x0a\x2d\x7f\x45\xd2\x98\xbe\xde\xd6\x2d\xd2\x1f\xfd\xb1\x2c\x7f\x57\x41\x64\x0d\x2d\x55\x73\x34\xec\x17\x8b\x8f\x83\x9e\x3f\x6a\xf6\x7c\x7d\x0f\xf8\xd1\x07\x36\x80\x22\x4f\xd7\x76\xd8\x4f\x8b\x0b\x1f\xbd\x48\xdb\xcf\xfd\x73\x58\x2f\x11\x83\x42\x84\x2e\x77\xa7\x39\x3f\x8a\x15\x70\x4c\x07\x3b\x27\xa1\xd6\x73\x21\x92\xaa\x7e\xcc\x3b\x41\xc4\xf3\xa0\x2d\x26\xda\x46\xc5\x97\xcb\x83\x0c\x05\x74\x0d\xae\xd1\xfa\xf2\xdb\x34\xc7\x79\x06\xf9\x9b\x4c\xe1\xa4\x07\x49\x86\xeb\xf6\x8b\x0f\x1e\xbc\xee\xe1\x97\x39\x23\x2b\x13\x0b\x3e\x79\x2b\xe1\x53\xaa\xc2\x31\xa8\x07\xef\x7c\x2a\xa6\x8c\x4a\x73\xcc\xa6\x9c\x7a\x09\x93\xdd\x8d\xb9\xee\xe4\x5a\x62\x69\x8c\xd7\x94\xc1\xc7\xe1\xdb\x97\xa1\xe7\xad\x3f\x8d\x95\xfb\xaa\xf9\x5a\xe3\x4f\xda\x62\x87\x34\xaf\xfd\xa7\x26\xb4\x0a\x62\xcf\x2d\x63\x56\x68\x54\x5b\x38\xb9\x5e\xa4\xf7\x48\x61\xdf\xe4\x07\x50\x08\x4c\x83\xc3\x4d\xa1\xe4\xc3\xbe\xdb\xe4\xbd\x41\xd5\xc9\x4e\x2e\x15\xd5\xd9\xb5\xbd\xdb\xc7\x92\x3e\xb7\x95\xb1\xa7\x97\xa1\x68\xcc\xa1\x82\x29\x93\xe6\xd7\xbf\xf2\xda\xb3\xe3\x08\xe9\xfd\x7b\x72\xbf\x5e\x8a\xc6\x31\x7e\xfd\xb1\x4e\x23\x18\x6b\x9f\x88\xfb\xa7\x1a\x69\x2a\x8c\x97\x54\x79\xad\xa1\x26\x16\x03\x9c\x5c\xac\x7c\x68\xad\x57\x62\xb5\xb2\x62\x65\x0e\x5d\xe8\xf8\x8d\xb4\x1a\x9a\xc2\x55\xa0\x8e\x92\xb2\x26\x56\xda\xb5\x61\x40\xa1\xe7\xd7\x09\x9c\xac\xee\x86\x9e\x09\x3a\x25\x15\x06\xee\x29\xba\x79\xe5\xda\xe6\x51\x55\x95\xb6\x9d\xfe\xa6\x9e\x29\x7a\x8b\x95\xe4\x75\x4c\xcf\xe8\xe2\x77\x71\x0f\x48\xca\x88\xe5\x81\x1d\xef\x81\x30\xaf\x71\x20\xa8\xdc\xb4\x7d\xae\xd8\x43\x52\xce\xc5\x94\xe0\x64\xed\xbc\x4f\x58\x7c\x9b\x4c\xb1\x82\x32\x8b\x7a\x52\xa4\xe6\x06\x26\xc1\x81\x94\x0e\x16\x7a\xf2\xe2\x1e\xf8\x6d\xde\x37\x77\x2c\x33\xc4\xba\x9c\x1f\xfb\xf8\xa4\x07\x89\x12\xda\xd4\x4d\xcf\x0c\xaf\x8c\x35\x8c\x7d\xec\xb8\xcc\xde\x5f\xfe\x02\x22\x39\x11\x30\x3b\x46\xff\x2e\xc2\x3e\x09\xf5\xa0\xdf\x19\x82\x4e\xd1\x67\x6f\x6f\x58\x11\x88\x13\x4c\xae\xd3\x0a\xc0\x1b\x36\x1d\x82\x49\x49\xd7\xad\x5e\xd5\x96\xe3\x7a\xbd\x8b\x13\x0a\x20\x38\x35\x95\xc9\x65\xcf\xd3\xc8\x5d\x1f\x97\x77\x90\x37\x4c\x77\xb0\xe6\xb8\x94\x36\xd8\x13\x5c\x0f\xe9\xa2\x9b\x7b\xcf\xcf\xe6\x2e\xec\x7b\x92\x2a\xc2\x98\xb6\xa7\x23\x16\xd0\x95\xe7\x94\x64\x38\x50\x37\x14\x0a\x7a\x6b\x86\x0f\x34\xfe\x35\x1d\xb2\x08\x67\xbb\xa0\x38\x28\xad\x58\x7d\x92\xfe\xc9\xd5\x65\xa9\xef\x21\x07\x05\xe8\xbc\x3b\x21\xd4\x3e\x88\x82\xa7\x9a\xf5\xfd\x23\xa5\xe0\xc3\xe4\x06\x26\xe7\xe2\x00\x82\xe2\x97\xdb\xcb\x2c\x48\x6a\x4d\x13\xec\x8d\xa8\x7b\x60\xf3\x21\x3a\xcf\x13\x7a\x40\xc3\xf3\xb5\xf6\xc0\x8d\x80\xfc\xe6\x1a\x91\xef\x68\x71\xb6\xa9\xa1\x06\x3d\x91\x21\x9f\xf9\x87\x4c\x20\xab\x66\xdf\xc5\x9e\x56\x72\xe2\x03\xaa\xb2\x2a\x4a\x86\x50\x04\x4c\x4f\x7b\x16\x14\xd6\xec\x66\xb3\x3c\x54\xb8\xb9\x12\xb6\xc4\xe6\x46\x43\xb2\x7b\x42\x1c\xd1\x59\xb6\x98\x00\x5d\x10\xb9\x7d\x8c\x62\x55\x5d\xc4\xe2\x79\xf2\xb3\x57\x49\xff\xb9\x85\xd4\x9f\x32\xcc\x6f\xc1\x23\xc5\x15\x57\xba\xa4\xdf\x97\x87\x05\x1d\xf0\xc5\x42\x70\x2b\xff\x49\x0b\x4f\x5e\xf4\x9f\xe9\xe6\xfe\x15\xfc\xc3\xf0\x0d\x98\x6f\x6b\x74\x55\xb0\xb2\xe1\x15\xd6\x2f\xcb\xb8\x3f\xdc\x30\xb4\x0a\x47\x0e\x45\x22\x73\xe2\x24\x59\x76\x52\x11\xdf\xcd\x8f\xf6\x29\xaa\x56\x63\xb1\xfd\x0f\x96\x15\x96\x84\x8b\xe9\xb7\x9c\xf6\xc1\x55\x26\x6a\x3d\x1f\x52\x8c\xac\x45\x69\x46\xe1\x10\x3f\x86\xc7\xb6\x65\x6e\x21\x39\xff\x71\xac\xf4\x21\x30\x3b\x23\x43\x68\xa3\x19\xc9\xc5\x55\xb5\xec\xd8\xd1\xed\xcb\xce\xe6\xb1\x55\x33\x23\x43\x3d\xb5\xb9\xf2\xe0\xd0\x99\x69\x47\xe5\x41\xa4\x03\x8b\xa8\x21\x74\x3e\x4f\x8e\xb2\x4e\x0e\x78\x13\xab\x1e\x41\x09\xd2\x20\xf4\xd5\x4e\x8b\x7e\x7b\x8a\x2d\xf5\xff\x64\x3b\x10\x96\x8e\xdd\x41\x46\xea\x45\x3a\x63\x47\x5d\x45\xee\x87\x56\x53\x1f\x66\x49\x30\x41\xc3\x34\x3f\x3a\x1f\xe4\x19\x18\x00\xa8\x09\x85\x57\xe8\xc8\x8a\x6f\xe3\x16\x6e\x57\x05\x78\x5b\x0f\xaf\x2a\x4e\x5d\xe3\xbb\x36\x2e\x8f\xe3\xae\xf7\x8d\x9d\x83\x25\x1e\xbb\x6f\xe6\x10\x39\x3a\x59\xe9\xb3\xfd\x1e\x48\x18\x38\x4f\x0c\x7a\xbd\x68\x1f\x2c\xbb\x67\x83\x39\x78\x21\xd2\xe4\x6f\x36\xaf\xa4\x65\x69\x8b\xe7\x50\xb2\x5a\x48\x43\x2d\xf9\x3b\xd0\xf3\xe8\x20\x50\xd3\x44\xa1\xe8\xfb\x40\xe0\x33\xbb\xf1\x9d\x94\x1e\x8b\x2f\xa2\x17\xf4\xee\x17\xc3\x9b\x26\x85\xc2\x85\x8e\xb6\x4e\x56\x2d\x9f\x58\xe4\x0e\x26\x7b\x20\x0b\x30\xde\x19\x23\x86\xeb\xc1\x6e\x02\xfd\x2f\x33\x4f\xf6\xb3\x11\x6b\x36\x1a\x9f\x13\x3a\xef\x01\xe2\xaf\xbc\x19\xa8\x97\xfd\xbe\x29\xf9\x0f\x2a\x49\xbd\xbf\x55\x72\x2e\x2b\xdd\xf8\xfa\x4d\x83\x9d\xe5\xe4\x08\x51\xdf\xe5\x3f\xbf\xea\x4d\x8b\x90\x65\x38\xf8\xe7\x1a\x26\xee\x70\x74\x65\xd1\x70\x19\x54\x6c\xeb\x70\x0c\x22\x99\xfb\x28\x91\x20\x9d\xb1\x65\xab\xbd\xa2\xb0\xaa\xcf\x49\xd0\xaf\x25\xed\x4a\xe0\xd5\x37\xc7\xf6\x5a\xd7\xfd\x35\xd8\xb3\x5b\x50\xcd\xa3\xd6\x4d\x3f\xfd\xf9\xf8\x83\x60\x86\x00\x6a\x5d\xad\x7e\x2e\x39\xe8\x49\xef\x13\x95\xed\xaf\x82\x9d\xbf\xd3\x09\x42\xc6\x7c\xad\xd9\xae\x10\x16\x70\x48\x5e\xc7\xdc\x66\x50\x6c\xbc\xb5\xd4\x65\x82\x61\x06\xf4\xf4\x3b\x29\x07\xab\x74\x8e\xdf\xd7\xfa\x5f\x49\xe5\x87\x99\x28\xd3\xb8\xba\x20\x4b\x74\xa9\xe2\xe2\x43\xce\x84\x22\xe7\xf7\x74\xf5\x0d\x37\x16\xd3\x8b\x35\x36\xba\x75\xeb\xfb\xb5\x53\x74\x4e\x0a\x1a\x3d\x48\x0a\xd0\xae\x34\x8d\x84\x40\x10\x34\x5d\xec\x47\x1a\xa9\x5f\x25\x8b\x8a\x83\xf1\x44\xf0\xc8\x30\x63\xeb\xed\x81\x3a\xf6\xad\xce\xec\xd3\x86\xed\xd8\xb7\x6d\x11\x93\x57\xec\x2b\xfc\xca\x5e\x71\x09\x10\x83\x4b\x51\x73\xfd\x42\x4b\x17\xfc\xe4\x11\xa1\x2d\x53\x72\x7f\x9a\xcd\x09\xaa\x31\x55\x35\x22\x49\xb9\xed\xa9\xb3\x2a\xcb\xb2\x4b\x0e\x20\x06\xb8\xa4\x0b\xa2\xb1\x79\xf0\xd0\x3f\xde\x60\x62\xdc\x05\xe3\x4b\x69\xe6\x92\xca\xc7\x22\xa0\x12\xb1\x6b\x42\xb0\x39\x15\xde\x64\x70\x0f\x44\xe4\x77\xae\x3e\xc9\xf9\x3e\xde\xa9\xc7\xf7\x6e\x91\x39\x29\x28\xcd\x02\x1a\xa1\x4e\x75\x2b\xb1\x70\xb1\x93\x68\x90\xa5\x11\x4b\xf7\x45\x94\x63\x87\x1a\xcc\xbc\x0b\x4c\x83\xe7\xc4\x83\x6b\x20\x5b\x3f\xe7\x36\xb8\x6b\xf8\xef\x2c\xfd\xe4\x5d\x53\x3b\x82\x2e\x0f\xb3\x6a\xd1\xbb\x85\x21\x2c\x9d\xf5\x9d\xcd\x49\x8f\x25\x86\x70\xd9\xbc\x36\x16\x45\xb7\x12\xa9\x4c\xfd\x95\xf8\xf4\x6d\x75\xdc\x1f\xe5\xd1\x45\xb0\x87\xbe\x7f\xcf\xd0\xb2\x1f\x37\x0d\x86\xdf\x0a\xc7\x8e\xcd\x98\xe9\x3a\x9e\x25\x9f\xd3\x87\x4e\x6d\x1a\x07\x36\xbe\x63\xb8\xcb\xe1\x79\x9a\x4d\x22\xdb\x3b\x68\x85\x7e\xae\x9c\xf5\x7a\xc6\x2c\x64\xf3\xc5\x48\xec\xa4\xe8\x9d\xe7\x5c\x1a\x96\xbb\x0c\x23\xc7\xc6\xea\x7b\x53\x5c\xf4\x67\x53\xe2\x03\x02\x96\x5e\x89\xb8\x85\xcf\x63\x4b\x53\x4d\x7e\x8b\x8d\x0a\x2c\x6d\x21\xb8\xfb\x46\x1c\x09\x1d\x8f\x84\xfc\x54\x4f\xdb\xd9\x07\xac\xfd\x9d\x4a\xe9\x13\x96\x2e\x6b\x74\xfb\xba\x49\x9f\x5e\xe8\x9b\xaa\xa1\x64\x98\xe5\xce\x8a\xb6\x04\xce\x3d\x36\x7e\x4f\x83\x1b\x34\xb5\x05\xff\xc8\xaf\x68\x35\xaa\xc4\xda\xea\x28\x7e\xb7\xe4\xcf\x0e\xd5\xd9\x03\x0a\x92\xe2\x66\xa7\x41\x72\x14\x61\x5b\x30\x8a\x6c\xfc\xb3\xc4\x38\x46\xee\xbb\xa9\x59\xcb\xba\x10\xad\xcf\xcf\x7a\x87\xc4\x13\xab\x3d\xef\xf8\x50\x82\xbe\x94\xc1\x4b\xcf\x0c\x43\xf0\x30\x9d\xa0\x0c\x37\x8b\x13\x19\x8f\x7d\x50\xe0\x21\x8d\x15\xfd\x48\x4b\xaf\x81\x7a\x4e\x91\x61\xf7\x29\x35\x71\x0d\x70\x89\x3f\xf1\x8c\xbe\xc7\x78\x8e\x52\x44\xbf\xc7\x2f\x80\x18\xa6\xdb\x04\x07\xc9\x30\x60\xbf\x83\xea\xca\x26\xca\xcc\x3e\xac\x8f\xf2\x8f\xca\x97\xb7\x0f\xfc\x8f\x77\xc7\x56\x20\xe7\x9e\x4a\x35\x5a\x78\x47\x07\x2b\xc5\xc6\x95\xcd\x2a\x8b\xce\x75\x7e\x77\xdf\xb8\xf1\xed\xfc\xf4\x68\xc9\xf7\x82\x4b\x9b\x6f\x84\x35\x3f\xd7\x72\xf6\x30\x3f\xa1\x5d\xcb\x03\xba\xfb\xbc\x2c\xd3\x9e\xd0\xfe\x72\x6c\x4e\x4e\x1e\xc6\x69\xa7\x3d\x63\x0a\xbd\xc9\xfa\x74\x69\xcc\xb7\x72\x27\xf9\x53\xaf\xe2\x78\x05\xa6\x5e\x2a\x6b\xd2\x21\xf6\x3f\x35\x07\xe8\x05\x27\x16\x18\xf2\x6e\xba\xd2\x39\x0f\x80\x37\xcd\x91\xd3\x83\x72\x81\x1a\xdd\x4d\xe1\xcc\xc4\x77\xec\xeb\xe9\x6f\x95\xf8\x2c\xa7\x4c\x3a\xf7\xf3\xa8\x3c\xbd\xc2\xe8\xf8\x5c\x6b\xc7\x9e\x55\x30\x61\x77\xca\x83\x0d\xf6\xa5\xa8\x97\xa3\x24\x04\x9c\x7a\x77\x02\x90\x5e\x56\x46\xcf\xa5\xe6\x41\xab\xc1\xc1\x31\x06\x9c\x7f\xa7\x1a\xfc\x17\x90\xdc\xb5\x5f\x5c\xf6\x63\x44\x9e\x79\x03\x70\x97\x61\x12\x39\x08\xe4\x9a\x27\xdf\x92\xfa\x9c\x89\xc5\x37\x21\x98\xe2\x78\xce\x3f\x4c\x8d\xa4\x96\xf0\x64\xe8\xb4\x77\x53\x07\x41\x2b\x07\x66\x7a\x79\xcb\xcb\x33\xa6\xbe\x68\x9f\x87\x8b\xee\x81\x9d\xb8\xae\xfb\x57\xc4\x55\xa6\xa8\x0e\xae\x67\x72\x10\x6c\x55\x34\x34\xa1\xbb\xa9\x23\x42\x47\xae\x03\x31\x15\x32\x7b\x9c\x98\x93\x17\xeb\xe1\x5e\xc2\x47\x44\x13\x03\xe7\x8f\x81\xe4\x96\x04\x9f\xa9\x97\x06\xb4\xdd\xfd\x39\x64\x57\xbd\x05\x09\x4b\x8e\x25\xda\x52\x46\x28\xa2\x62\x88\xd1\x9d\x79\xbb\xdb\x8b\x3b\xca\xdd\x7b\x80\x54\x22\xe0\xdd\xe6\x9f\x47\x3f\x66\x09\xaa\x0e\xdc\xf2\x15\x93\x75\xbd\xf0\x7e\x06\x70\x62\x3e\xdf\x7c\x1e\xf5\xf4\x84\xb5\x7d\xd6\xf9\x91\xc0\x9f\xe8\x2f\xe6\x2f\x00\x8e\x14\xbe\xe0\x6f\x16\xd5\xbe\xf0\x6d\xdd\x74\x7f\x86\xe9\x1f\x75\xd3\xaa\xf3\x7b\xb1\x3c\x3f\x8d\x8e\x8d\x98\x06\x7e\x74\xaa\xc1\xf0\xf9\x26\x6d\x0a\x60\xf8\x96\x9f\xab\x9e\x75\xd4\xb8\x94\x15\x47\x5f\x60\xe4\x69\x0b\xa9\x04\x35\xee\x7b\xeb\xec\xb2\xa9\x10\x3c\xc4\xa4\x11\xa5\x3e\x91\x61\xf4\x71\xae\x82\x26\x0e\x0a\xa8\xfa\x95\xd8\xe1\x59\x39\xa4\x52\x90\x7c\x00\xbb\x85\xf6\x8a\x6e\x93\x41\x0e\x24\xb9\xd5\x7b\x72\xb9\xdb\xe6\xad\x5b\x67\x85\x74\x21\xe5\xcb\xed\x78\xf8\x35\x20\x1a\x64\x72\x2f\x82\x29\xd5\x18\xc5\x14\x79\xb1\xb2\xca\xa0\xf9\x24\x4e\xeb\x87\x7e\xdf\xe6\x07\x2a\x06\x88\x9a\x98\xab\xc9\xc4\x86\x29\xe4\x51\x86\x33\x3b\x72\x6c\xce\x68\x35\x99\x27\x85\xcc\x47\xe4\x82\x23\x6e\x1a\x6c\x2f\x47\x41\x9a\xfc\x37\x71\xd8\x67\xde\xbd\xb1\x9b\x18\x4f\x0a\xd0\xc6\xb2\xbb\xd2\xa6\x7a\xdc\xb9\x81\xb8\x98\xa1\xd1\x06\x33\x2b\xa8\x7e\x6e\x31\x38\xce\x0b\xe1\x2d\xff\x1d\x96\x70\xb9\x25\x4d\xe7\xf0\xbe\xf6\xab\xc7\xaa\xef\x1a\x15\x36\x03\xe5\xce\x24\xce\x4b\x17\x69\xe5\xcb\x55\x0c\xb4\x1d\xed\x93\xea\x69\xd1\x73\x56\x9d\xdb\x41\xc0\x35\x8f\x5a\xf0\x6b\xcb\xe9\xbc\x37\xfc\xd1\xa1\xcf\x33\xfd\x0c\x11\x9d\x8d\x7b\x40\x39\x76\x53\xbe\xad\x79\x59\x5c\x2f\x39\xfa\x89\xda\xac\xc2\xcb\x5c\xe4\x5c\x36\xca\x18\x11\x5d\xf5\x40\xeb\xf4\xf2\xb8\x4e\x63\xb0\x80\x5d\x76\x6a\x8d\x3e\x21\x77\x43\x37\xd6\x9f\xbb\x8d\xca\x84\xbf\xb5\xbe\x87\x40\xe2\xe1\x99\x5e\x8a\x1e\x3d\x13\x62\x01\x26\x79\xd3\xf1\x66\x2b\x5b\x7a\xf9\x4e\x70\xae\x61\x98\x59\x7e\x8c\xfc\x07\xd6\x46\x6a\x4a\x8f\x8b\x74\x8e\x9f\x41\x76\xb0\x51\x64\xa2\x04\xd3\x3d\x80\x27\xf5\x61\xdc\xe1\x5d\xc8\x1f\xd1\x84\x9d\x54\x9e\xae\x9e\x44\x87\x69\x9c\x84\x68\x47\xa2\x84\x0c\xec\x0e\x3d\x02\xda\xf0\x1e\x86\x70\x1f\xa6\x81\xf6\xd2\xac\x2d\xa9\x0c\x67\x0a\x98\xcf\x3b\x6a\x07\xa3\x16\x87\xec\x38\x88\xa6\x5e\xdb\x55\x3d\x0a\xbc\x39\x40\x6a\x68\x64\x3c\xe8\xee\x70\xa4\x23\xfa\xdd\x89\x27\x40\x54\xb4\xb0\xd7\x20\x28\x5a\x42\x15\x49\xdd\x98\x23\xcf\xd1\x93\x24\x9a\xa2\x08\x20\xb1\xcc\x5c\x07\x01\xbf\xf8\xdc\x50\x0b\x6f\x87\x92\xad\x59\x1a\x02\x5e\x62\x74\xef\xc8\x75\xb5\x8a\x24\xed\x50\x1f\x7f\x7a\xd3\xcc\xab\xa2\x5d\x3b\x66\xcd\x1b\xed\x2c\xbd\x38\x97\x8a\x5c\xf8\xdb\x0b\x00\x06\x00\xf4\xe6\xe9\x31\x9c\xa0\x9a\x58\x96\xe3\x77\xc9\x46\x4c\x71\xfe\x54\x99\x31\x59\x95\x7a\x0f\x8e\xf1\x7b\xb6\x5d\x93\x93\x17\x4f\x29\xd7\xb5\x48\x70\x7b\x29\x40\x1b\x99\x26\x95\x5b\x10\x4c\x9f\x3e\xea\x85\x9f\x3d\x75\xef\x9c\x53\x18\xa5\x35\x8f\x0f\x4d\xa2\x37\x4f\xa2\xdb\x18\x1b\xb7\x07\x9c\xa8\x08\x22\x99\x0e\xb6\xcd\x70\x9d\xd5\xab\x3d\xda\x72\x83\x4b\xed\x16\x10\xce\xde\xf6\xf4\x51\x7f\xdc\x44\x6f\x0f\x23\xba\xd1\xa2\x05\xdf\x87\xb6\x1e\xe5\xf2\xeb\xd5\x0e\x94\x86\xc8\x0b\xdc\x76\x73\x01\x17\x36\x35\xe6\x69\xde\xac\x21\x92\x15\xc6\xfd\x92\xf6\xa3\x4f\x02\x19\xa1\x08\xc5\xb6\xf7\x73\xb7\x32\x6b\x4a\x1a\x05\xa2\x9f\xb2\x30\x13\x72\xef\xee\x81\xbb\x36\x04\x6f\x28\x8a\x77\x35\xcd\x7c\x5e\xb3\xdf\xf2\xc1\x39\xbf\xae\xe4\x24\xf4\x0f\x27\xe6\x02\x6f\xa3\xb8\xb8\xd0\xfb\x96\x96\x84\x67\x85\x1c\xee\xa0\x60\x13\xc7\xad\xa9\xf8\x65\xaa\x18\x83\x15\xd5\xc9\x42\x2f\x59\xcc\xd1\x1d\x8a\xab\xd1\x13\xb4\x0e\xdd\x2d\xdd\xd7\x4b\xe7\xac\x37\x0b\x3b\xc4\x27\x6d\xb6\x20\x9e\xa9\xe3\xe3\x85\x76\x08\xd1\x2d\xdb\xe9\x6e\xe4\x82\x28\xd9\x28\x47\x9b\xfa\x2f\xc7\xe7\x5f\xdc\x0f\xf7\xa4\xf1\x81\x33\xdc\x5b\x69\xa4\x7a\xd4\xe2\x49\x40\x39\xc7\xb7\x63\x6b\xb3\x6f\x56\xbd\x2b\x47\x52\xb9\x8d\x3f\xa5\x08\x4e\xb5\x13\xc3\x2f\x46\x36\x42\x48\xa8\xdd\xf4\xce\x94\x6a\xd2\x09\xa8\xe1\xdb\xbc\xea\x0e\x57\x95\x22\x70\x6c\xfa\x7f\x1a\x9b\xd9\xc7\xe5\x33\x16\xe4\xc8\xee\xcb\x30\x3e\xdd\xf8\x8d\xd7\xd0\x1d\x63\x50\x65\x35\x0d\xc6\x0a\x7b\x0d\x8a\x43\xa5\x51\x1e\x1d\x4e\xeb\x7e\x5a\x6b\xfb\x76\x6b\x2e\xcf\x55\xf4\x7d\x39\x38\xe5\x0f\xdf\x71\x22\x0a\xa1\xf2\x32\x8d\x02\x38\xe0\x2c\x80\xfd\xb7\x5f\xa1\x9a\x46\xca\x0f\x83\x73\x12\x00\x06\x3b\x83\x41\x14\x4e\x21\x65\x5a\x5c\xcd\xa4\x94\x1c\x4f\x7f\x97\xd4\x07\xd0\xf9\xc9\x80\xdf\x7e\x63\x1e\x7d\xaf\x23\xf6\x26\x7e\x0d\xc5\x70\x47\x9a\x96\x78\xf2\x49\xe6\x35\x02\x0c\x37\xc6\x58\xcc\x97\xd2\xdb\x26\xc4\x3f\x45\x10\x0d\x32\xc5\xfa\x3b\x4b\xde\x28\x34\x52\x99\xe1\x3d\x0e\x4d\x4e\x79\x26\xaf\x20\xbb\xd6\x15\x57\x1b\x26\xeb\x90\x5c\xb1\x01\x92\xa1\xda\xfb\xb7\xd0\x27\xe1\x5f\xfc\xcf\x07\x4b\x74\xe6\x4e\xb5\xff\xf3\xb2\xd7\x79\x01\x66\x01\xdd\x46\xae\x06\x5f\xbf\xa0\xef\x76\x1c\xfd\xe9\xca\x14\x7b\x89\x59\x37\xa4\xf8\x72\xe7\x41\x3d\x50\x02\xdd\xd9\x0b\x63\x16\xc3\xac\x51\x1d\xaa\x14\x73\xa9\xf7\xa3\x6c\x67\xbe\x99\xfb\x88\xbb\xc7\x7b\x62\x01\x88\xec\xb9\x07\x89\xb0\x70\x5c\xf1\xcf\x02\xdf\x2e\xee\x01\x4c\x13\x7b\x8b\xd3\x15\x6d\xd4\x93\xb6\x09\xc6\x42\xca\xce\xa2\xee\x67\x6f\x79\xbf\x8d\x80\x22\x04\x12\x02\xbb\x95\x7f\x36\x24\x86\xd2\x32\x64\x7c\x98\x03\x7f\x9a\x3e\x61\xaf\x1b\x37\x83\xa8\x81\x69\x30\x60\xcf\x84\x4c\x63\x6e\x86\x1a\x74\x86\xfb\x7d\x55\x78\x66\x6f\xbb\x3c\xbe\xd0\x28\x98\x64\xa9\x5f\x1e\xaa\x6c\x40\x22\x75\xd5\x2b\x6a\x9a\xab\xab\x12\x5d\x14\xcd\x79\x1f\xb8\x3b\xb1\xa6\xa6\x04\x04\xd1\x5e\xc6\x3e\x85\xd8\x2e\x60\x09\x52\x95\xc5\xe1\x3c\x07\x4d\xd8\x56\x70\x5d\x00\x1a\x58\x5e\x57\xa8\x15\xb8\xe2\x3c\x57\x02\xec\xed\xfc\xdf\xe8\xb1\x06\xcc\x5d\x14\x17\x39\xb7\xd9\x60\xee\x42\xa8\x5f\x72\xdb\x4b\xf1\xa7\x88\x2c\x15\x3a\x3f\xd1\x92\xe1\x6b\x09\xe1\x17\x95\x40\x66\x5e\xdd\x03\x38\xf5\xd2\x11\x82\x57\x56\xfd\x74\x1e\x6c\xd6\xdf\x74\xa3\xd1\x35\x78\x0e\x2b\x83\x54\xe7\x43\xac\x64\xab\x2f\x62\x40\xdf\xdb\x09\xb6\x49\x83\x87\x4b\xd1\xba\x1d\xd0\x00\xb2\x27\x8c\xab\xe4\xd8\x3a\x42\xc0\x0d\x4a\x86\xb6\xe1\xef\xf2\x70\xd7\x3c\xf2\x5b\xb1\xb5\x87\xa7\xc6\xdf\x9f\x95\x1c\x46\x45\x7e\x22\xb9\x64\x45\x55\x30\xe1\x36\x36\x7f\x95\xe0\xa0\x20\x1b\xd2\x32\x7c\xb9\xdd\x24\x8f\x37\x5c\x76\x59\x73\x63\x93\x6e\x63\xf2\x5c\x63\x6c\x4c\x16\xdc\xe9\xf3\xa0\x7f\x27\xaf\x7f\x4d\xea\xeb\x85\x5f\xd4\xed\xc7\x52\x77\x36\x4e\x30\x16\xe6\xe2\x32\x4c\x32\x60\x9e\x3f\x4d\x12\x62\xf0\xab\xdf\x44\xc9\x9f\x1b\xc5\x30\xcb\xb9\xcc\x46\xee\x14\x55\xe0\x42\x92\x8d\x64\xc5\xcc\xbe\xb8\x42\x14\xd9\x0f\x77\x09\xda\xfc\x8a\x58\x79\x93\x08\x35\xf7\x2f\x7d\x7c\x38\x49\x0c\x36\xe9\x2e\x06\x7c\xd3\x53\x3d\x78\xab\x0a\x93\xdc\x5b\x65\x2b\x07\x2c\x75\x73\xfc\xf9\x51\xa0\xae\x69\xc7\x85\xf7\x18\x72\xc6\x35\x90\x32\xc4\x4b\xb2\x72\xe3\x95\x08\x49\x1b\xcc\x81\x3b\x49\x99\xd4\x78\x5a\xf2\xe4\xf3\x76\xa7\x29\x86\x48\xe5\x4b\x69\xc2\x65\x05\x9c\x64\x87\xca\x49\x56\xfa\x3b\xca\xed\x7b\xe0\x41\x8e\x53\x87\x67\xc1\x0a\xbf\xc0\x50\x45\xfb\xb0\xb8\xcb\x97\x00\xf0\x25\xc2\x6a\x96\x55\xaf\x8a\xe5\x95\x11\xa7\x06\x00\x27\xb8\xf8\xc7\x8e\x50\x21\x46\x0c\x27\x30\xf8\x97\x9f\x1d\x9c\xfc\x0f\x19\x16\xe9\xff\xb6\x02\x45\x1b\x56\x41\x0d\x70\xca\xad\x2c\xbf\xde\xad\xdc\xe9\x9f\x7b\xe0\x83\x7f\x93\x94\x9e\x83\x6b\x8a\xcf\xee\x19\x42\xbb\xc9\x71\xfa\xf1\x15\x42\x18\x5d\x4b\xd4\x39\x14\x1a\x38\x93\x1e\x43\x57\x4b\x1f\xbe\x8d\x99\x80\xde\xea\x24\x57\xf7\x4c\x1f\xe3\x30\x09\x97\xa5\x00\x39\xfd\xaf\xa8\x80\x02\xd0\xcc\x7c\x2c\x20\x43\x20\xc7\xbc\xaf\xf2\xdf\xa3\xdb\xf3\xa5\x45\xad\xc7\xb6\xe5\x2c\xe4\x14\x09\x55\x77\xd4\xfa\x64\x38\x37\xdc\x6e\x3c\x63\x5c\x42\xbc\x4b\x0e\xc9\x67\xdb\x30\xef\x20\x1f\xd4\x42\xc4\x4a\x71\x18\xea\x1b\x2c\x37\xe4\x59\x62\x3f\x72\x2b\x02\x24\xcf\x38\x31\x6b\xd1\x86\x9b\x4b\x82\x13\x38\x54\x2d\x6f\xcf\xa9\x71\x7e\xc9\x0c\x6f\xc6\x5c\x34\x52\x53\x57\x88\x69\x57\x2c\x2f\x0d\xd3\x26\x50\xca\x50\xfa\xff\x2f\x21\xd9\x7f\x48\x3c\x15\x94\xff\xf3\xc2\x25\x42\x1c\x5d\xe7\x12\x5f\x64\x60\x7b\x4c\x2e\xd2\x96\x85\x1d\x09\x72\x11\xcf\x26\x9d\x52\xbe\x50\x3e\x53\x8f\xaa\xef\xf7\xdb\x6a\x17\x57\x5a\x53\xe7\xc2\x22\x6a\x54\x47\xa5\x0e\x2f\x36\x17\x03\xde\xb9\x54\xb5\x11\xe3\x0a\x21\x9c\x19\x76\x16\xcc\x94\xc3\x06\xeb\x15\xb4\xaf\x1d\x19\xc2\x94\xb7\xd3\x97\x05\x32\xbb\xff\x3d\x5d\x21\xf4\x9b\x8b\x62\x36\x7c\x84\x8f\x3b\x43\x63\x51\xbd\x28\x48\x93\x80\xfc\x82\x02\x74\xb6\x9e\x78\x52\xaa\x4e\x67\xbf\xec\x2e\x36\x4e\x39\x50\xbe\x23\xcc\xaf\x51\x89\x99\x20\x7e\x89\xc8\xef\x00\x73\x4f\x6c\x4a\x4a\x16\x99\x4d\x3e\xd4\x18\xa6\xde\x26\xd4\x9d\x62\xe4\xaf\xcb\x34\x16\xf8\xed\xfb\x16\x43\xe9\x52\xca\x2b\x84\x1f\x7f\xdb\xec\x8e\xf2\x24\x8f\x78\xf1\xe8\x8e\xe2\xb3\x7c\xea\x97\x27\xd4\x66\xeb\x26\x36\x98\x9f\x0b\x92\x9e\x39\x45\xfc\x9d\xd4\x10\x95\x48\xfb\x19\x6a\xbf\xd5\x95\x55\x51\x55\x4d\xb6\xf6\x88\xad\x0f\x46\x2c\xb2\xbd\x58\xbf\x98\xe3\x6f\x30\x83\x6c\x9d\x61\x9d\x3f\x6f\x52\x91\xc8\x8e\x6a\x4e\x07\x83\x69\x8e\x47\xe0\xc4\x37\x93\x9e\xad\x0d\x31\x56\xa2\xc4\xf0\x98\x1f\xb7\x01\x25\x52\xe5\x9b\xc6\xf2\xd4\xab\xc9\x0b\x64\x63\x6f\x2d\x4f\x45\x91\xdf\x2d\xdf\xde\x61\xb5\xff\x76\x0e\x73\x78\xb4\x46\xe7\x21\xb3\x4b\xd9\xee\x4e\x92\xfe\xe0\xe5\xcc\x87\x50\x19\x26\x1e\x34\xb7\x4c\x86\x7e\x47\x47\xc2\x9c\x4e\xfb\xdc\xcf\x82\xd4\x1d\x1b\x4b\x87\x00\xd7\x21\x39\x6f\x57\x7b\x46\x91\x53\xec\x3e\x06\xc7\x84\xc6\x02\x48\x5a\x69\xb4\x3b\xcb\xd3\x72\x86\xc0\xd6\xa9\x85\xda\x0b\x43\xed\xd3\xee\x41\xef\x3a\x7d\xcc\xe1\xc7\x56\x23\xc8\x27\x8b\xe7\x08\x9f\x68\xd6\xd6\xe0\x97\x9c\xcc\xd7\x83\x00\x14\x1c\xe5\xff\xae\x08\xdd\x3f\x44\x2b\xf9\x35\x3f\x69\x98\x5a\x3b\xc3\xcd\x6c\xc8\xdb\x35\xfb\x14\x8c\x34\x7d\x65\x1b\x16\x10\x23\x41\x1f\x87\x7f\xea\x1c\x6d\xc2\xd4\x38\x27\xe1\x58\x38\x85\xa5\x21\x47\xd4\x0f\x62\xd6\xbb\x3a\xe9\xdd\xce\x76\xb1\x5f\xbd\xa8\x22\xa0\xae\x8b\x73\xa4\x1e\x04\x4c\xfe\xdf\x68\xc6\xc7\xef\x84\xc2\xef\x81\x30\xdf\x89\xb1\x3a\x02\xb7\x56\x2e\x01\xe3\xee\x08\x06\xab\xe9\x6a\x36\xa3\x8d\x81\x4e\xdf\x8b\x1a\x05\x24\x51\x8a\x31\xd4\x98\xe1\x87\xde\x6d\xf9\xd7\x2e\x9b\xd8\x44\x35\xd7\xb9\x43\xc3\x3b\xdc\x4f\x1c\xa7\x8d\xc9\x11\xda\xef\x76\x82\x5b\x30\x43\x7f\x9d\xcb\x30\xc8\xfd\x0f\x88\x5e\xa9\xa5\x9e\x7d\xd5\x55\x38\x5d\xdd\x59\x32\xc3\x97\x57\xfc\x75\x95\x7a\x21\x22\xb1\x88\x77\x3a\xa7\x72\xfe\xf3\xa9\x90\x9b\xe9\x73\x07\x3a\x7b\x95\x1f\xa4\xeb\x79\x2f\x27\xac\x6f\x75\x50\xf4\x8b\xcb\x8d\x88\xc8\x86\x5f\xc9\x9f\xf2\x04\x1c\x68\xb8\xc0\x0e\x57\xa3\xc7\x26\x19\x9b\x7e\xe4\xb6\x45\x3d\x35\x52\x01\xa1\xae\xd7\x83\x80\x13\xd7\xa6\x4c\xe9\xbf\xda\x91\xd6\xa2\x02\x2c\xb3\xf1\x31\x31\x44\x04\x01\xef\xe2\xbf\x79\x41\xcb\x1a\xd6\xf8\x9c\x04\x80\xe6\x51\xc7\x2b\x13\xde\x56\xa4\xdf\xf8\xa5\xd7\x19\x56\xae\x2e\x3e\x35\x69\x92\x74\x87\x8b\xeb\x77\x5f\xdd\x52\x28\x52\xfb\x6e\xe4\xb4\xf8\x78\xac\x45\xc9\x8b\x32\x2e\x39\xef\xe3\x6f\x6f\x84\xf0\x29\x51\xdc\x9c\x9d\xed\x18\xff\x8e\x55\x5a\x53\x99\x24\x2a\x38\x2e\xa1\x7b\xf7\x11\x4c\x32\x73\xc9\xab\x27\x74\xb9\xe4\xff\x47\xdd\x5f\x7f\xc5\xf9\xef\x59\xa2\xf8\x03\x05\x14\x6e\x81\xe0\x16\x20\x78\xf0\xe0\x50\x24\xc1\x42\x08\x84\xe0\x16\x08\x0e\xc1\xad\x70\x0b\xee\x10\x20\xb8\x5b\xb0\x40\x70\x77\x87\xc2\x49\x70\x28\x9c\x40\xaa\xd0\xc2\xbf\xab\xcf\xe9\xd3\x73\xa6\xbf\x33\xdd\xd3\xd3\x9f\x7b\xd7\xba\x3f\xec\x3f\xe0\x59\xcf\x7b\xbd\x7c\xef\x5d\x9c\xdb\x13\xf8\xf6\x1f\x7a\x27\x15\x07\x91\xba\xe1\x80\xb3\x52\x2e\xf8\x51\xe4\xb6\x8f\x26\x5c\x59\x86\x48\x8f\xae\x9a\x2c\x95\x27\x90\x5a\xd0\xc4\x25\xd3\xd9\x7f\xc2\x36\x07\xb9\x1b\x57\x54\x7b\x72\x56\x49\xca\xd2\xda\xd2\x82\x1f\xb9\x77\xcb\x44\x17\xc7\x60\x24\x55\x4e\x24\x8b\xf2\x70\xab\x7a\xcd\xdb\xa6\xae\xa5\x90\xe0\xd9\x18\xc7\x89\x76\xc9\x4c\x86\xa6\x7e\xb9\x59\x7f\x3e\x37\x23\xfb\x88\x1d\xd2\x0d\xfe\x75\xda\x76\x13\x38\x1b\xed\xd2\x6f\x06\x0d\xee\xa3\x17\x9d\xcf\x6f\xa9\x99\xe1\xf9\x63\x84\x9e\xa7\x3b\x26\xe1\xd3\xcf\xa9\x30\x0a\x03\xb2\x7d\x6d\x17\xb9\x7d\x98\x0b\x7e\xbd\x8a\x20\xcc\xb1\xcf\xe3\x6f\xbc\x34\xce\x99\x68\xd0\x9a\x66\xdd\x0b\x0a\x90\x36\xb5\xe3\xea\x5f\x2c\x09\x9b\x08\x5f\x24\x98\x2e\xde\x4e\xc0\x0f\x60\x97\x1f\x16\x1b\x06\xc5\x39\x78\xcd\x3d\x00\x9f\x33\x36\x89\x42\x2a\x19\xeb\x5a\xa6\x25\x9b\x10\xe8\x42\x4a\x4d\x84\x6b\xbd\x39\x23\x1d\xe1\x37\x42\x90\xbb\xee\x97\x8b\x7d\xf0\x1d\x35\xbf\x3a\xb4\x75\x3f\x1a\x54\x63\xa5\x82\xfb\xf7\x83\x1a\xfe\x5f\x8c\x4a\x22\x03\xa6\x18\xde\x66\xa6\x1e\x3e\xb4\x6e\xd5\x8e\xd3\x6e\x19\x2a\x46\x53\xf6\x3c\xc5\x0a\xea\x68\x12\x3a\xb4\x66\x96\xf5\x5a\x73\xb7\xfc\xc5\xb6\xe2\x3e\x29\x1e\xee\x43\xfb\x6c\x6c\x20\x0c\x06\x35\x5f\xdb\x91\xaa\x33\x18\xf1\x2d\x6f\x4b\xca\xf5\x84\x42\xc7\x64\xe0\x07\x01\xee\x14\x57\xaa\x6e\xd1\x6b\xef\x40\x08\xfd\x86\x9c\x09\xd4\xb2\x6f\x9e\x9e\x75\x26\xe5\x78\x44\xed\xc0\x2b\xfa\xa4\x64\x72\xfe\xe8\xef\x97\x3f\x39\x95\x3a\x0d\x05\xf9\x2b\x8b\x2c\xc5\x22\x29\x02\xdf\xd6\xd1\x35\x2e\x44\x85\xf3\xfe\xa5\x9e\xd3\x46\xc4\xa9\xb7\xc4\x4a\xdc\x51\x23\x1a\x6e\x94\x22\x8b\xb5\x41\xf4\x41\xed\xef\x4b\xab\x99\x90\x1f\x47\x37\x54\xc3\xc5\x2d\xca\x1f\xe9\x2e\xe9\x2e\x77\x26\x33\x51\x69\xf9\xae\x38\x83\xc1\xe0\xce\xe9\xf6\x8f\x38\x9f\x27\x43\xdf\x67\x46\x02\x57\x7f\xe0\x3c\x59\xf3\x09\x9b\x37\x2a\x2f\x06\xde\xd3\x4e\xf3\x41\x63\x05\x83\x27\x2f\xce\x2b\x79\x89\x7c\xd4\xe7\xce\xc2\xdf\xf9\x68\x16\x2b\x11\x94\x51\xc6\x9e\x60\x47\xc8\x4b\x3f\x00\x21\x0e\xb7\x8e\x75\x1f\x7e\xdb\x49\xbc\xb3\x75\x10\x5d\x5a\xa6\xad\x52\x70\xca\x86\x6e\x39\x1d\xe9\xd3\x13\xd4\x36\xcc\xdd\xb2\x9a\xd9\xe7\x86\x42\xd4\x48\x43\x64\xd5\x9c\xf6\x5c\x20\xf4\x0e\x70\x5e\x32\x5d\x68\xa3\xc6\x94\xbd\xeb\x68\x8a\x95\xcf\x8e\xc2\x5a\x97\x3a\x7f\x70\x5d\xe4\x65\x25\x23\x49\x49\x0f\x9e\x3d\x13\x04\x56\x09\x2d\xe9\x1b\x27\xed\x55\x59\x10\x1a\xfa\xcd\xc3\x53\x79\x7a\x9a\x15\xa8\x4d\x29\x36\x21\x40\xe4\xe0\x97\x7c\x24\xce\x31\x91\x86\x06\xd3\xc0\x0a\x10\xfa\xf7\x42\x3a\x7f\xcf\xac\xff\x11\x18\x5e\xb3\xe7\x12\x49\xa2\xfa\x8e\x18\x82\x96\xbf\x39\x8c\x0d\x51\xda\x77\x0d\x96\x09\x5b\x6e\xf8\x44\xdf\x3f\xaa\xc7\x3f\x18\xcb\x2d\x5b\xf4\x9f\xb0\xe5\x82\xbf\xb2\xb0\xc3\x9a\x60\x0a\x6c\xf1\x49\xd4\xa7\x03\xcf\x17\xa2\xa4\x63\x18\x42\x47\x28\x88\x1a\xb4\xb6\x68\x2f\x73\x89\x94\xff\x16\x6d\x92\x32\x91\x7f\x4d\x52\xfd\xfb\xae\x6c\xd6\x3e\x65\xa2\xc7\x7a\x79\xe3\x1d\xde\xa3\x78\x99\x2c\xbd\x2a\xff\x01\xed\xe1\x12\xd4\xc7\x0b\x0f\xfe\x10\x6c\xd9\x53\x42\x34\x98\x0d\x70\xa2\x8a\xb9\xc4\x16\xd9\xe6\x56\x66\xa3\x4d\x53\xa4\xf3\xf4\x6e\xf5\x12\xa3\x7a\x1d\x8b\x68\xbe\x7d\x7e\x05\xfd\x55\x2e\xbe\x93\xd1\x4b\x84\x11\x95\xd9\xcc\xf1\xb3\x55\xec\xcd\x58\x85\x9e\xdf\x94\x04\xb1\xa8\x7e\x6f\xd2\x2a\xe0\x7f\xa5\x47\xc5\x4c\xfc\x4d\x29\x17\x33\xff\x9b\x5c\xe9\x92\xb2\xeb\xc5\x28\x27\x55\xbc\x79\x92\x07\xa3\x46\xaa\xf6\xbb\x45\x7d\x25\xc9\xcf\xd8\x70\xf5\x31\xa5\x01\x4c\x40\x55\xce\xa5\x45\x24\xba\xae\xdd\xf1\xb5\x1d\x2b\x86\x02\x53\x74\xe6\x39\xf3\xcc\xac\xd6\x7a\xb6\x54\x1a\x37\x3f\x04\xe3\x92\x6f\xe9\xe9\x55\xa1\xc6\xbb\xd9\x9a\x2e\xf2\x09\x9b\x6c\x99\x49\xa1\x56\x8f\x74\x7d\x54\x26\xaf\x2c\x8d\x3d\xb7\x2f\xb8\xd2\x73\xad\x2f\x87\x84\x1d\x89\x6b\x3d\x63\xa3\x42\xd0\x8c\xf6\xeb\xd5\x6b\x88\x81\x69\xf5\xfb\x2b\x6d\x89\x8b\x4e\x1c\x3c\x72\x13\x09\x83\x72\x52\x9f\xce\x1f\x1b\x11\x5b\x5e\x8e\xd2\x5f\xd0\x16\x1f\x80\x9e\x83\x1f\x29\xe7\x8f\xb9\xb4\xf8\x86\x6e\xc8\x6a\xba\x07\xcb\xe0\x80\x76\x81\xee\xe1\xf3\x4b\xad\x08\xc7\x5a\x26\x79\x2a\x0c\x7a\xae\x9d\xea\x86\x8e\xa2\x82\xe5\xa5\xfd\x55\x86\x06\xad\x80\x94\xf4\x8f\xad\xe4\x10\x49\x7a\xa2\x92\x76\xd7\x0e\x10\x62\x7b\x37\xdc\xf5\x4c\xe4\x72\xda\x37\x9d\x4d\xc2\x24\xf6\xc3\x97\x7b\xd0\x9a\xd4\x1e\x68\xe9\x99\xa4\x4a\xe1\x12\xd6\xa9\x43\x2e\x7e\x01\x77\x87\xf1\xd0\xf5\x02\x83\x1b\x52\x40\xd7\x7e\x4c\xdc\xe2\xeb\x82\x52\x13\x1a\xe3\x47\x67\xec\xc3\x00\x71\xf7\xf2\x79\x69\xf4\x99\xa3\x2a\x7a\x6b\x96\x74\x43\x14\x2b\xd5\xfd\xfb\x09\x6f\x37\xfa\x81\xc6\xe9\xe9\x89\x01\x12\x5a\xe2\x81\x00\x47\xf4\x52\x40\x0d\x0c\x6e\x1d\xb8\x67\xfc\x91\xe8\x1d\x55\x3f\xc3\x33\x9b\x82\x43\x4a\x9e\x04\x78\x3f\x00\x7a\xb3\x28\xbb\x4d\xfd\x2c\x6d\x15\x2b\xde\x62\x6b\xfb\x27\xf6\xba\x3f\x52\xd4\xa1\x47\xfa\xd4\xbb\xe1\xae\xbe\x58\xfd\xd9\xd7\x17\xec\xbd\x8e\x65\x59\x63\x7d\xd7\x68\xc3\x55\xa0\x0d\x97\xbe\x96\xbb\x5b\x3e\x8a\x9f\x3a\x39\x59\x10\x16\xcb\xe0\x23\xd4\x24\xb8\x2e\x56\x8e\xe7\xc9\xdd\xd4\xbf\xbc\x29\x75\xfe\xc5\xc2\xec\x59\xb4\x6d\x7f\x4a\x87\xaf\xdd\x96\x25\x79\x06\xcd\xdc\x2f\xcb\xba\x61\x74\x5e\x96\x49\xdd\x95\xbc\x61\xe2\xda\x3f\x8f\xc6\xd2\xa2\xff\xa8\xfd\x7c\x43\xd7\x0e\x65\x63\xd8\x5d\x6c\xba\xf3\x73\x5f\x68\x73\x91\x9a\x8d\x1f\x40\xf4\xbc\x22\xae\x5e\xd4\x54\x8e\x7d\xeb\xb5\xe5\x8b\xbd\x2b\x65\xbb\xe0\x8a\xa7\xd9\x30\xbd\xae\x19\xfd\x94\x18\xdf\x52\xa6\x12\xb0\xfd\x97\xff\xff\x39\x40\xc0\x86\xb5\x29\xa2\x45\x54\x26\x46\x6b\xde\xf5\x01\x38\x52\x79\xba\x39\xf6\x7a\x8a\x4a\xad\xd4\x8d\x8d\xd3\x1f\x17\x71\x24\xd1\x7b\xa9\x75\xbd\x32\x1f\x23\x5d\xe3\x6d\x5a\xfa\xca\xa3\x9f\x45\x90\xb8\xaa\x19\xce\x4c\xf9\x34\x40\x6a\x6f\x22\x10\x2f\x11\x3d\xd6\x76\xd8\x47\x15\x6e\xa7\xda\x27\x5e\xb7\x4a\x8f\x18\x93\x85\xbf\xdc\x5e\x31\x48\x94\x07\x33\x06\x28\xbc\xcd\x72\x31\xd8\x8d\xaa\xe7\x25\xd9\x0b\x4f\x37\xec\xf8\x7e\x9d\x38\x91\xa7\xc7\xc1\xc7\xf2\xfe\xfe\x64\x7d\x1d\xde\xee\xf1\x00\x10\x9d\x51\x9e\xdd\x11\xe2\x2f\xb1\x08\x8a\x87\xa5\x52\x89\x99\x0e\x6f\x9d\x42\x88\xa1\xca\x5d\xc4\xd6\x2e\x51\xa3\xbd\xbb\x46\x22\x12\x71\x72\x2c\x2e\x81\x77\xb6\x53\x4c\x21\xa6\x6a\x00\x7d\xdd\x50\x82\x46\x36\x9f\xcd\x08\x9c\x0c\xc8\x35\x36\xfe\xc7\x1b\xd6\x78\xaf\x3f\x28\x69\x47\x1b\x49\xa5\x63\x1c\xbc\xac\x51\xa7\x06\x4e\xb4\xd5\x33\x5f\xe8\xed\x24\x26\xf0\x78\xc3\x7b\x17\xe1\xc2\x4e\x31\x5f\x1e\xfd\x4a\x71\x63\x41\xea\x47\x60\xe4\x59\xbb\xc4\xfb\xa0\xfb\xf1\x67\xa6\x09\xba\x74\x2f\xd1\x09\x94\x4b\x7f\x76\x97\xea\x2a\xdb\x39\x91\x2a\xd1\x46\x6a\x26\x87\xca\x92\x9f\x9e\xa5\xa6\x5f\x7e\xae\x8f\x8a\xc3\xdb\x5f\x88\xa0\xa6\xe2\x47\x4b\xcd\x49\x6e\x31\x36\x95\xd9\x9a\x04\x4f\x52\x88\x27\x57\xa6\x87\x35\x65\x8b\x26\x31\xda\xbb\xe3\x8a\xed\xcf\xe7\xd8\xfa\xdb\x79\x51\x2e\x8d\x25\x62\x8a\x4a\xbc\x75\xb4\xed\xad\xb7\xc3\xba\x56\xe1\x39\x27\x22\xb1\xd5\x7e\xd4\x8b\x1b\x84\xc8\xc3\xa5\x6a\x45\xbb\x9a\x5f\xe8\x2e\xa7\xaa\xac\x74\x78\xb6\xac\x98\xb0\x3c\xfa\x45\xeb\xa3\xbc\x94\xbc\x1c\xe0\x8d\x49\x46\xf8\x45\x0d\x9c\x73\xab\x87\xb8\xa5\x86\x85\xe8\xb9\x47\xba\x67\x4f\xb5\x0d\xa5\x13\xea\xfa\x42\x8f\x45\xcb\xd7\x88\x84\x7f\x9e\x77\xe2\x2d\xbd\xc1\x59\xfd\x46\x7e\xda\x3d\x74\x68\xa8\x79\x9e\x29\x72\xe1\xbc\xb8\x2c\x5f\x2b\xf7\xe4\xc8\xcc\xa4\x9b\x7c\x2b\x1b\x57\x01\x11\x17\xe3\x26\x43\xa4\x8c\x91\xd0\xcf\x95\x66\xb7\xc5\x13\xc2\xb5\x87\x26\x63\xf4\x05\xad\x13\x19\xab\x19\xd7\x75\x22\xdd\x63\x76\xfa\x22\x17\xc4\x16\x2f\xa7\x8b\x32\xc7\x53\x58\x3f\x24\x33\xce\xfd\xbd\x87\x46\x29\x13\xe3\xcc\x40\x29\x6c\x52\x66\x68\x7d\x8d\xd9\x92\x96\xe3\x91\x79\x48\xb9\xfc\xd2\x9f\x88\x0a\xf6\xe6\xde\x6d\xdf\xef\x71\xed\xf3\x16\x9e\xda\xaf\x6d\x0d\xec\x78\x4c\x92\xc1\x10\xfa\x0f\xc8\xda\xb9\xfe\xfb\x04\x3e\xdc\xd1\x14\x06\x3e\x30\xed\xe9\xd2\xb2\xf6\x37\xa8\x9e\xce\xf6\x64\xa5\xde\x93\x8a\x0e\xbd\xe8\x32\x78\xa0\x01\xd1\x20\x06\xc3\x4f\xf7\xb7\x23\xb8\xdc\x25\x92\x66\x67\x43\x47\xf7\xe4\x0b\x3e\x32\xaf\x54\x71\x75\xb9\x3f\x85\xf8\xd4\x5c\x7a\xa9\x81\xb5\xff\xeb\xa3\x80\xaf\xb9\x44\x42\xa8\xb1\x1a\x99\xd0\xa3\x4b\xcb\x31\xdd\x60\x46\x5c\x55\xe6\x65\xd7\x62\x1f\x06\x05\x15\xb4\xd9\xaa\xb9\xd3\x0c\x0c\x7f\xe2\x52\x3f\x61\x18\xb5\xd5\x05\x53\x63\x39\x4e\x04\x61\x7b\x53\x79\x27\x36\xf3\xd2\x86\xe8\x30\xd8\xfd\x82\x5b\xd9\x92\x4d\xca\x0a\x34\xb5\x6f\xcd\xff\xaf\xf1\x19\x2b\x92\xfd\x2f\x39\xe8\x23\xdf\x79\x00\x1e\x27\x67\xbc\x74\x4e\xb8\x8a\x2e\x5d\xe3\xe0\x89\xab\xa6\xd5\x2e\xc8\xae\xdf\xf9\x40\x49\xef\xf0\xdb\x5c\x51\x4b\xcb\x74\x4e\x4b\xa5\x54\xe1\x46\x67\x6b\x12\xb3\xf3\xf3\x41\xd4\xfa\x21\x4f\xab\xdf\xfe\xbd\xdb\xde\x8b\xb6\x99\x0d\x42\xff\x0d\x92\xc6\x6e\xd0\x8e\x24\x00\xdd\x2d\x11\xde\x37\x76\x82\xe0\xfd\x4f\x1f\x4d\x55\x9a\xbe\xc9\xb2\xd2\xdc\xb5\x34\x3c\x9c\x8b\x63\x23\xf6\x15\x1b\x26\x1c\xe8\x0f\x57\x79\x02\xf3\x62\xb9\xf7\xf9\xd6\x1a\xf9\x0a\xa7\xeb\x9c\xed\x7b\xd5\xeb\xd3\x4d\x82\xfb\x46\x13\x62\xc4\x45\x86\x64\xed\x44\xbf\x72\x32\x93\x29\xa8\x99\x1b\x60\x7c\x00\xf4\x00\xd8\x94\x7d\x61\x14\xfc\x59\x09\xc5\xd7\x37\x16\xc4\x8e\x6f\x7d\xc5\xaa\x55\xe6\xde\xc3\xa6\x8e\xe3\xf3\xa5\x4d\x99\x6d\xe1\xe0\xd8\xf3\xf5\x74\xd6\xbb\xcb\xb0\x0e\xee\x36\xf1\xb6\x61\x96\x54\xdf\xb9\x08\x90\x94\xf8\x29\x4a\xbb\xd3\x41\xb7\xe2\xeb\xa3\x5e\x5e\x99\xd7\xc0\x55\x86\x0a\xd2\xa0\xe3\xf1\xdc\x1f\x1e\xf5\x6e\x8b\xcc\xd1\x76\x2d\xac\x2b\x7f\x88\xaf\x84\xb6\xad\xc5\xaa\x08\x32\x53\xf1\xe9\x44\x96\xd9\x68\x3c\xe9\x8b\x98\x9c\xde\x44\xa9\x18\x97\x74\xac\x08\x73\x70\xdf\xcd\xa1\x77\xb8\xf9\xc9\xdc\xd7\xde\x5d\x2f\xcb\x4a\x6f\xf3\x94\xca\x42\xbd\x17\xcc\x22\x0d\x43\xef\xa3\xa9\x80\xc1\x43\x08\xfd\x23\xb8\x03\xc6\x78\xfe\x4a\x2f\xf7\xe9\xb0\x73\x2c\x48\x50\xc2\x2c\x48\xf0\x30\xc9\x50\xa1\x97\x86\x4e\xea\x7e\xce\x5a\x38\x13\x6b\x07\xcc\x6a\xc1\x95\x38\xa2\xb4\x9b\xde\x88\xe4\x35\x9c\xae\x1f\xa5\xb2\x73\xfd\x22\x92\x3a\x45\x94\xad\xf3\x71\x99\xd9\xe8\x01\x10\x79\xbd\xe9\x43\xe3\x5d\x91\x25\x5b\x30\x43\xa5\xae\x5c\xf8\x62\xe2\x37\x18\xaf\x7b\x40\x76\x37\x12\x38\x3b\x12\x18\x99\x5f\xe8\xf7\x9a\x4f\x67\x86\x34\x72\xfe\x78\x46\x01\xc2\xb0\x93\x29\xad\xf0\xa5\xd1\x9f\x6e\x63\xaa\x32\x7a\xe9\x5f\xfa\x55\xf5\x16\x99\x1c\x41\xe7\x55\xca\xdc\x59\x6f\x41\x23\xf3\xc8\xfa\x9e\x7f\x46\x58\x4a\xeb\xe2\x69\xa8\xf6\x8d\xb4\xa9\x41\x3c\xa1\x22\xc6\xba\xa5\xcc\xeb\xc9\x79\xd7\x15\xce\x0f\xf4\xb2\x3c\xbf\xf1\x58\x62\xbb\x65\x93\x58\x4c\x41\x94\x68\x4e\x0b\xb3\xe9\xc0\xaa\x7f\xf8\xa5\x5e\x61\x10\x2f\xa1\xd5\x82\x5e\x50\xce\x17\x03\x53\x33\x89\x8e\x8e\x64\xa9\xce\xe0\x5b\x85\x8a\xa1\x69\xdb\x96\xdb\x72\x8c\xcf\x3f\xf4\xf4\x88\xb8\xd1\xee\x56\x56\x9c\xee\x85\xa7\xa2\x2a\x05\x5f\xce\xdc\x0e\xef\x04\x2d\x92\x4f\x08\x86\xd0\xb7\x73\x3d\x55\x8d\xec\xa0\xfe\x4c\x42\x37\x36\xc3\x67\x10\x12\x89\x25\xd1\x91\xa9\x86\x15\x9a\xb3\x4e\x44\xb4\xff\xec\x69\xfd\xcc\x86\x2e\x45\xfc\x6f\x3c\x92\x33\x36\xd1\x2a\x05\x59\x8d\x19\x3f\x4e\x9b\xf9\x02\x6f\xcf\x9f\x09\xca\x0c\x2d\xfc\xd9\x52\xb5\x36\xb7\x39\x8f\x84\x69\xb6\xd9\x14\x10\x1d\x45\xce\xcd\x1b\xcb\x18\xea\x52\x9e\x55\x46\x37\xef\x9a\xc3\x06\x17\xed\xf3\x4a\xf5\x47\x09\xfa\x4a\x8b\x72\x0d\xf8\x8d\x14\xcf\xce\x06\x5f\x2e\x06\x48\x4d\x11\x6a\xbc\xff\x46\x63\x79\xca\xf8\xfe\xe8\xbd\x1a\x9a\x6e\xcb\x71\x1e\x7d\x6a\xfe\xca\xca\x90\x1a\x36\x9c\xc5\xc1\x31\x20\xbb\x97\x2d\x50\x4f\x73\x47\x86\x5c\xf8\x01\x60\xb2\x73\x2d\x55\x74\xf7\xd0\x4a\x13\x21\x67\xf2\x76\x65\x0e\x0e\x4e\x07\xb6\x24\xc9\x89\x67\x25\x65\xf1\x02\x6e\xf0\xd2\xb4\x09\x29\x4b\xec\x9b\xa4\x22\xcf\xfa\xbd\xc7\xb0\x49\x59\xdf\x4d\xe2\xae\xdf\x62\x16\xbf\x24\x93\x37\x56\x1d\x71\x7f\xf2\x7d\x03\xf8\x8d\x43\xbe\x16\x9b\xf9\xf7\xce\x5d\x9b\x1c\x5e\x8d\xff\x00\xd8\xfc\xa2\x39\x7c\x31\x65\xf3\x7c\x44\x8f\x42\x7e\x40\xd5\x80\xe1\x5d\x3c\x57\x7d\xc5\x8a\xbb\x2c\x56\x94\x27\x87\xc4\x8b\x17\xe3\x39\x6f\x70\x01\xa4\x0c\xb6\xee\x70\x05\x34\xd2\x5a\x58\xdf\x33\x66\x5e\xc6\x77\x67\x7d\x30\x5b\x14\x84\xa8\x36\x68\x6f\x8f\x7b\x31\x65\xcf\x4b\x25\xf0\xfd\x15\xac\xce\x69\xd2\xa2\xed\x66\x23\x24\xa6\x75\x31\xeb\x35\x16\xef\x6e\x83\x60\xd7\x80\x84\x1d\x28\x6e\x6c\xc1\x14\xae\x1f\x12\xdc\x9d\xfe\x25\xd1\x01\xfb\x3b\xed\x6f\x46\x86\xb1\x49\x30\x8d\x25\xb2\xa5\xc7\x35\x51\xbf\x9d\xf3\x9e\x32\x51\x25\x86\xc5\x7a\xe7\xa9\xff\x2a\xf9\xa4\xf5\x1a\x85\x24\xaf\x9b\x60\xd7\xc2\xbd\xac\x91\x87\x01\x53\x8c\xea\x64\xfa\x86\x1f\x19\x25\xb7\x24\x6b\xe9\x87\x03\x34\xad\x9f\x6f\x26\x74\x43\xdf\x62\x89\x5f\x2f\xc8\x3d\x00\x38\x0f\x40\xa0\xc3\x32\x4b\xaa\xfb\x78\x26\xbe\x32\xa1\x8c\x64\x24\x70\x00\xee\x27\xc2\x31\xe3\x58\xe0\xee\xf5\x72\xb8\x1c\xd4\xab\x95\x7e\x82\xd2\xa9\x88\x16\x6e\xe5\x29\x85\xb0\x4d\x50\x0e\x53\xad\x5f\xee\xf9\x73\xf6\x37\xd4\x21\x0c\xc7\x1b\x3e\x36\x4e\xeb\x71\x48\x3d\x16\x20\xf2\x47\x94\xf8\x7f\x84\x3e\x9d\x17\x63\xbb\xa1\x4f\xa6\x4e\x19\x4d\x0c\xc7\x52\x60\xd8\x3d\x84\x3c\xde\x45\xd5\xac\xdf\x78\x4a\x36\xcc\x57\xae\x3c\x00\xfb\x5f\x9f\xc9\xf0\x61\x97\xd5\x39\x44\x88\x3f\x6e\x2d\x8f\x11\x1f\xd0\x35\x92\x67\xe0\xba\xe2\x26\xbb\x1c\x70\x1a\x84\xbf\xd3\xdd\xcf\x66\x58\xd5\xea\xc1\x23\x77\x3b\xa8\x79\xb2\x8b\xec\x77\x6c\x71\x1d\xeb\x7c\x5c\x55\x69\x6c\x4a\xf8\x4b\x96\xf5\xad\xe6\x40\xf7\x80\x84\xc7\xed\x1e\x68\x59\x76\x28\x3f\x8d\x64\x04\x7f\x66\x0f\x60\x8e\x44\xaa\xc6\x50\x2b\x2f\xc1\x2c\x2b\xf4\xab\x3e\x38\xaa\xa3\x9b\x05\x95\x30\x83\x67\x4f\xb8\x16\x0f\x43\x50\x45\x56\x0b\x46\x64\x4e\x24\xe8\xe6\x09\xaf\x9f\x3b\xc5\x0e\x66\x2f\x3f\x82\xd0\x3b\x5e\xff\xb9\x65\x73\xd1\xd9\x7f\xae\x3f\x8f\xa9\x72\xf9\x2a\x70\x98\x31\x40\x86\x48\xcd\xf6\xa7\xa4\x54\xb1\x5c\x89\x4e\x3f\x86\x31\xe7\x40\x9e\x36\x7d\xf2\xc6\x03\x40\x50\x52\x57\x87\x0c\x19\xaf\x1d\x11\x94\xf4\x9e\x04\xb5\x76\x8e\xe1\x9c\x0f\x4b\xb5\x6a\x4f\xba\x53\x9e\xdc\x29\xe6\xe2\xf5\x16\xfd\x4b\x90\x75\x5a\x15\x42\x48\x1a\x71\x3c\xbf\xc4\x73\x62\xad\x9f\xab\x79\x2a\x46\x7c\x7a\x7b\x58\x93\x1f\x20\xb9\xd6\xc3\x80\xb7\x31\xcd\x2a\xb2\xd8\x36\xf0\x00\xbc\x63\x55\x4c\x7f\xd9\x6a\x65\x14\x60\x79\xb5\x50\xc0\x89\x61\xc0\xbe\x99\x25\x07\x78\xfe\xe9\x8f\x52\xad\x87\x3a\x3f\x5e\x69\x1c\xcd\x72\xfa\x82\x41\x0a\xdd\x95\x02\xa3\xe6\x3e\x7c\x16\x99\x1e\x2f\x50\x01\xd9\x59\x6d\x7c\xf9\x46\xde\x05\x78\x01\x12\xda\xca\xf0\x1b\x7e\xcf\xf5\x9b\x6d\xfe\xab\x0c\x6d\xe8\x87\x92\x92\xbc\xcb\xaa\x47\xeb\xb3\xcd\xde\x43\x9b\x16\x7c\x55\x93\x68\x74\x52\xed\x32\x9c\xc0\x05\xe7\xbf\x0d\xb9\x4b\xed\xed\xf3\x7e\x34\x7a\xee\x3a\xd1\x2a\x0a\x8c\x79\xab\x61\xcc\x6a\xea\xf3\xbc\x58\x52\xfb\xac\x6c\xc7\x39\x14\x96\x07\x16\x3a\x5c\x1a\x12\xba\x51\xb2\x3f\x2e\xd2\xc9\x8d\x50\x96\x68\x84\x60\x02\x3a\xf9\x65\xd6\x8b\x95\x29\x95\x40\xfa\xc0\x8e\x18\x5c\x6a\x72\xa7\x6a\xf2\x3f\xdd\xfb\x11\x51\xa0\xb6\xa1\x93\x4a\x45\x03\x55\x5f\x59\xd3\x92\x82\xfc\x9a\x84\x97\x7c\x44\xea\x6c\x1d\x70\x74\xc3\x0c\x24\x18\x3f\xf2\xcf\x08\x77\xf9\x98\x6b\xc5\xf5\x3d\x17\x79\x36\x75\x65\xa4\xf4\x86\x24\x29\xc7\x48\x6c\xf0\x49\xbb\x60\xd7\x54\x9b\xdf\xe3\x1a\x6d\x31\x13\xd2\x13\xc1\xfd\x3f\xe3\x80\x6b\xdd\x3b\x39\x80\x09\x3d\x25\xda\x22\x12\x78\x7b\x56\xf7\x17\xf5\x16\x8e\xfe\x8f\x78\x9e\x36\x4f\xa3\x69\xfa\xb3\xba\xec\x88\x8b\xaa\x17\x1c\x28\xde\xcb\xb7\xd6\x3a\x72\x65\x23\x7d\x2b\xdb\xef\x83\x25\xdf\x1f\xb3\x63\xfd\xe6\x3c\xde\x3f\x0a\x86\xd0\x8a\x74\x97\x07\x3e\xcd\x70\x23\xcd\x94\x4f\x22\x8e\x6a\xab\x61\x88\xa8\xd6\x03\x33\x57\x42\x15\x7a\x08\xde\xe8\xdb\x52\x87\xa6\xb1\x7c\xfe\xf8\x42\x53\x8a\xcf\x29\x7a\xa1\x65\xc0\x39\xe0\x7a\x12\xb4\x97\x9f\x44\x99\x8b\x99\x1f\x19\xeb\x6e\x16\xf2\x8b\xb8\x15\x2d\xbe\xa0\x1d\xd0\x9e\x15\x96\x50\x11\x58\x29\x6e\x49\x63\x96\xa3\x62\x49\x5f\xaf\xee\xe0\xb3\x4e\x98\xe0\xa9\x3b\xc4\x6b\x3d\x0c\x5a\x7a\x21\x0f\x96\x59\x38\xab\x16\x9f\xc3\x58\x65\x41\x56\x9e\xd1\x33\xcd\x9a\xd5\xd4\xcb\x3f\x15\x76\x7f\x77\xb2\x9b\x90\x9d\x55\x5e\xf3\x03\xc9\x10\xec\x23\xf4\x78\x95\x81\x77\x0c\xc6\x8b\xef\x1d\x31\xe8\xdc\xa5\x86\xd1\x68\xc4\x8a\xdc\xa9\xd8\xae\x6b\xa7\xaa\x80\xcb\xb8\x2e\x93\x1b\xf8\xca\x0e\xcb\x94\xc0\xdf\xc4\xf5\xf8\xb1\xb4\xa7\x15\x2e\x48\x2a\xbe\xe6\x63\xca\x8f\x64\xa5\xa2\x6b\x66\xbe\xd6\x80\x6f\x32\x1b\xa5\x52\x6b\x25\xf8\x3b\x7e\x43\x53\xc2\x60\xe0\x62\x80\xb8\xfc\xd1\xdd\xcf\x85\xc2\xfa\x6a\xeb\xd2\x63\x36\x66\x78\x0a\x65\x0e\x36\x98\xc7\x96\xf6\x07\xfc\xb3\x00\x03\x71\x85\x20\x1f\x56\xfa\x9b\xc6\xa8\x31\x82\xa6\xab\x69\x8a\x8f\x6b\xc7\xd7\xf7\xe4\xe6\x92\x16\x0b\x66\xb2\x1b\x77\x84\xc7\x48\x72\x05\xd8\xf6\x95\x62\xf3\xd1\xa9\xe9\x59\xa5\x14\xf3\x46\x55\x94\x29\x8b\xc7\xa3\xbe\xcb\x54\xc8\xee\x44\xf3\xc7\x5d\x99\x97\x5d\x55\x23\x12\x3a\xf9\x06\x9c\x68\x67\x64\x68\xa7\x97\x31\xb7\xc2\xe5\xc3\xf6\xd9\x4f\x5a\x6a\x62\x09\xde\x3e\x27\xfc\x18\x9e\xaa\x2e\x7a\x68\x68\x19\xd2\xc1\x61\x75\x49\xad\x14\x79\x8d\x34\x69\x8a\x78\x91\x6c\x9a\x38\x48\xd7\xb4\x3b\x43\x59\xfd\x6a\x9e\x27\x3f\xfd\x57\xaf\x29\xe5\x2d\xd7\x58\xbd\x03\x16\x54\xdd\x9d\x42\x64\x7a\xa9\xfb\x99\xcb\x67\x26\x65\xe4\xfe\x7c\x80\xa8\x04\xcf\xb3\x0f\x74\x3e\xb2\xb3\x0e\x4f\xda\x5b\x23\x47\x9d\x70\x18\x59\x9e\x4b\x61\x79\xe1\x9e\x1f\x51\x6c\x14\x07\x5a\xdb\x44\x09\x27\x2e\x37\xaa\x2f\x50\x39\xab\x56\x0b\x07\x16\xd8\x64\x53\x20\x56\x87\x2a\x8c\xb4\x78\x53\x00\x7c\x7b\x99\x58\xa9\x72\x7b\x78\xbf\x1f\x63\x13\x5a\x9d\x2f\xce\x56\x48\xa8\xe6\x8e\x84\xb3\x74\x1a\x19\x9a\xed\x80\x97\x4a\x7b\x75\x30\xaf\xdd\x6f\x46\x45\xac\x31\x22\x1e\xcd\x17\xb1\xbb\xf5\xd0\xb5\xe0\x7a\x51\xed\xbe\xe7\xe8\x62\x06\xd8\x3f\x07\xd4\xb2\x73\x63\x0b\x63\xc5\x77\xa7\xdb\xe9\x2f\x15\x91\x39\xe1\x76\xba\xc2\x34\x87\xde\x94\x13\xe0\x64\xd2\x44\x4a\xe3\x5d\xc9\x9b\x85\x98\x35\x2b\x8e\x7c\x54\xba\xbe\x28\x6f\x92\x5b\xd3\x29\x96\xb2\xa3\x02\x0b\x2d\xd1\x36\x84\x3e\x15\xde\x49\x65\xfd\x6c\xbe\xc5\xb7\x6e\x9f\xe5\x62\x01\xfb\x18\xc0\x70\x1b\x40\x93\xba\x4f\x36\x1d\x7c\xbe\x40\x44\xd0\x90\xf7\x49\x93\x36\xbf\x33\x8d\x8d\xf3\x33\xc9\x9e\x80\x8c\xf8\xae\x64\x27\x8e\x21\xea\x99\x77\xca\x0d\xe9\x01\x77\x0c\xe3\x1a\xe3\x5a\xe7\x12\x1b\xf3\x62\xd1\xac\x34\xa3\xb5\xb6\x34\xf6\x8f\x20\xe5\x66\xbf\xd9\x56\xad\x57\x6f\x89\x18\xd4\x64\xf7\x21\x74\x25\xa1\x7e\x0c\x8b\x07\x24\x4b\x07\xe9\xe3\xdb\x13\x45\x2e\x4f\xca\x37\x2d\xa5\xf5\xb2\xdb\x78\x51\x0b\x79\x8b\x7b\xf3\xcf\xad\x1e\xd3\x58\x15\x30\xfc\x66\x24\xdf\xbe\x66\xe8\x97\x22\xed\x55\x6e\xf8\x11\x7c\xd4\x98\x8a\x47\x1d\x50\x46\xaf\xdb\x3c\xf8\x3e\x50\x7d\xc5\xc7\xa0\x2d\xd1\x35\xee\xed\xe4\x33\xd6\x65\x08\x4d\x06\x5b\x89\x24\x3b\x73\x5c\x25\xe0\x55\x92\x40\xca\x86\x17\x18\xed\x5a\xfd\x14\x95\x6b\x57\x71\x7e\x47\xea\xea\x78\x29\x40\x1a\xf4\x88\xfe\xae\x97\x39\xe1\x14\xdf\x2d\xcf\x47\x0e\x89\xa7\x97\xb2\x8a\x2d\x84\x34\x66\x65\xf3\x19\xa0\x0d\x68\xa2\x3d\x79\x4b\x24\x9d\x39\xd7\xfe\x68\xe3\x4d\xad\xcd\xda\x62\x07\xcb\x2c\xeb\xac\xbd\xec\x98\x2d\x33\x29\xf1\x1d\xf4\x0e\xc8\x25\x52\x99\xfe\x95\xde\x43\xba\xf2\x1a\x7f\xdd\xb4\xde\xb0\x74\x23\xc2\x24\xc2\xd4\x08\x3d\x1a\x37\x31\x80\xa9\xa5\x29\x76\x7e\x5e\x77\xdb\x38\x61\xa0\x28\x2d\xce\x98\x6b\x77\x29\x6a\x66\x33\x8e\x02\x56\xfa\xe3\xd1\xcd\x34\x63\x74\xd5\xa4\x06\x3e\xa1\xe2\xee\x02\x72\xb3\x9d\x68\x33\x27\x92\x75\xaa\xae\xa9\x92\x87\x15\x4f\xaa\x97\x78\x34\xc0\xf9\xab\x18\xed\x19\xec\x35\x0c\x65\x6d\x8c\x3b\xf2\x87\x34\x7c\x08\x3f\x87\x7d\xcf\x9f\xc8\x14\x42\x57\x1d\x7a\x36\x30\xf3\xfb\x49\xcc\xaf\x8c\x6d\x8c\xe3\x8f\x7d\x0c\x03\x2d\x68\x6f\xe4\x70\x73\x09\xbf\x5c\x03\xec\xf9\x69\xcc\x5f\x0c\x02\x73\x8a\x00\xe9\x66\x18\x2d\x8c\x4c\x9a\x68\xb6\x6d\xd7\x4c\xe1\x73\x9e\xb9\x4a\x9f\x65\x6c\xd6\xf5\xfc\x03\x90\xde\x24\x79\x56\xf5\x68\xb3\x72\x59\x79\x7d\x5f\x73\x87\x7f\xc0\x4c\xed\xb8\x1d\x02\x73\xf0\x1f\x09\x78\x82\x72\x33\xbb\x58\xa5\xae\x27\x95\x8c\xde\x7a\x94\x26\xca\x62\x39\xd3\x48\x3e\x89\x4a\x92\xbb\x5f\x9b\xac\x72\x9d\xde\x14\x14\x3f\xc2\x97\x95\x50\xad\xb6\x81\x21\xfa\x22\xb0\xe2\x6c\x19\x32\x9a\x2a\x6c\x87\xa5\xa0\x55\xd1\x06\xaf\x0e\xa4\xfd\x87\x26\xc1\xd1\xbb\x7a\x28\x17\xa6\x99\xdd\x99\xdd\x39\xd7\x30\xcc\xf1\x3e\x76\x65\xc6\xc1\x15\xe6\xdb\xf3\x6f\x46\xd4\x51\x6f\x90\x39\xb1\xac\xad\x37\xf8\x5c\xe6\xb4\xd2\x7a\xcc\x4b\x70\x3f\xcf\xdd\x68\x33\xff\x10\xf7\x07\x80\xd4\x07\xc2\xed\xfa\xf5\x88\x67\xcc\xce\xcd\xef\xfe\x05\x97\x88\xa8\x94\x2a\xed\x8d\xfb\xe1\xac\xd6\x60\x80\x10\xbb\x50\x0c\x35\xfb\x9c\x46\xa7\x7a\x17\x7e\xe6\x29\x84\x64\x10\x01\xeb\x2d\x7d\x95\xf3\x6b\x32\xa6\xd3\x4d\x1e\x42\xbe\xeb\x4f\x5c\x57\x8d\xb5\x27\x80\x63\x3e\xb3\xe9\xb9\xc5\xda\xf6\x7d\xfc\x34\x07\x82\xf6\xc7\xe8\xd0\x45\xe0\x25\x48\x90\x18\xa0\x5d\x88\x8c\xd2\x77\xa0\x40\xfd\x5e\x1b\x22\xf9\x5d\xa1\x53\x68\x33\x3a\x77\x3a\x2c\x79\x3a\x74\x08\xa1\x65\x0b\x73\xc3\x33\x14\x31\x8c\xd3\x4c\xb2\x48\xdd\x0e\x6e\x98\x9e\xc7\xf2\x70\x3b\xa6\x8a\x9b\x6e\xed\x04\xba\xdd\xca\x51\x27\x0f\x80\x61\xfa\xbc\xce\xf4\x8b\xd5\x77\xd0\x86\x0d\x67\x3e\x31\x3a\xa7\x3f\x46\x09\x8f\xd3\x8a\x1e\x2f\xdb\xe5\xb2\x51\xb2\xe4\x56\xd2\x58\xd4\x87\x7d\xc6\x6e\x5a\x37\x25\x43\xab\xc8\x71\x7d\xff\x2d\x7d\xf5\x15\xf8\x99\xf8\x66\xe1\x8d\x01\xa3\x25\x74\x70\x3e\x80\x5b\xcb\xa8\xf1\x53\x63\x8a\x00\x44\xc9\xb0\x97\x29\x70\x8b\x64\x48\x58\xa8\xa5\xa8\xc5\xcc\x33\xaa\xc9\x1d\xf6\xba\x67\xee\x7c\x08\x1e\xd3\x61\xd2\x09\x94\xc2\x5e\x03\x57\x8d\x4a\x09\xae\x0e\x14\x5c\xe8\x65\x2e\x76\x65\x75\x66\xc8\x91\x9a\x41\x87\xc1\xe6\xea\x72\xa1\x32\x8c\x94\xd2\xf5\x5d\x4e\x02\x9f\x0c\xc9\x1c\x2b\x54\x32\x47\x72\xe8\x2f\x5e\x49\x58\x32\x94\xad\x94\xfc\x5c\x26\xcc\xec\x01\x80\xc4\xc9\xac\x90\xa1\x35\xff\x53\xa6\xc2\xf4\xfe\x29\xd7\x5f\xf8\x3d\x1e\xdb\x8d\x2b\xf8\x98\x6b\xc0\x8f\xfe\x00\x24\x8f\x0c\xcd\x2b\x5c\xfe\x7a\x62\xb6\x58\x28\x0d\x4f\xd8\xdf\x93\x49\xf6\xb6\x06\x55\x42\x79\xc3\xc9\xf6\x1f\x00\x92\x6a\xf3\xf4\x4d\xda\xc1\x27\x92\x1f\x5f\xf5\xf2\x49\x86\x60\x70\xc0\x9c\xae\xd4\xc0\xed\x1c\x23\xc1\xca\x9a\xae\x87\xc9\x6d\x33\xeb\x59\xd2\x87\xb9\x26\x5a\x7f\xe3\x98\x01\x55\x0e\x83\x22\xbc\x76\x1b\xde\xc1\xb4\xf2\xef\x99\xb0\xd5\xf8\xf1\x65\xcf\x06\xbd\xf6\xb9\x12\x50\x61\x34\x9d\xa1\xba\x41\x03\x2f\x5e\x57\xf8\x0c\x74\x1d\xc6\x36\xd3\xd7\xa1\xbd\xdc\x58\x69\xfc\x75\x36\xbf\x24\xde\xfc\x21\x3e\x57\x2d\xd7\x74\x7f\x0d\x29\xac\xbd\x79\x5c\x3a\xdf\x81\xe7\xad\x5e\x32\xd6\x96\x60\x0a\x00\x0a\x60\xc9\xdd\x92\xd7\xb3\x08\x82\xef\x2a\x4c\x16\xbf\xa8\x85\xc2\x76\x74\x26\x34\x9d\x06\xd0\x86\xe1\x91\xf0\x7b\x7e\x43\x65\xa7\x32\x6b\x2f\x8d\x77\xc7\xef\xd3\x44\x3f\xd1\xee\x82\x0e\xa7\x03\x84\xef\x49\xf6\x2f\xb5\xae\x5f\x1a\xac\xbc\x65\xf1\xfc\xce\x47\x86\x8f\x36\xf8\x6e\xbe\x5d\xa0\x39\x0e\x04\x31\x41\x6c\x7f\xfb\x82\xfb\x82\x10\x7c\x25\x3c\x33\x89\x26\xfb\x1f\xa6\x4b\x75\x06\x3d\x00\x29\x13\xfd\x2d\xaa\xda\xba\x62\xf8\x93\x46\x1e\xfe\x07\xd6\xeb\x1b\x17\xd4\x42\x39\x14\x9a\x37\x75\x94\x26\x58\x37\xd0\xee\x97\xbc\xc3\x40\xfd\x24\xc1\xa1\xae\x79\x9a\x7d\x45\xb7\x81\xf4\x00\xba\x7b\x52\xfd\x06\x31\xaf\xff\xb2\x61\xa8\xfb\x64\x50\xb5\x08\xb0\x7b\xb7\x56\x24\x44\xd0\x0e\xd6\x73\x03\xc8\xde\x29\xfd\x4b\xa3\x67\x19\x6b\xf5\xdf\xd6\xc4\x2d\x7d\x56\x95\x57\x17\xb8\x93\xad\x19\x2b\x4c\x65\xf1\x11\x20\x17\xab\xc6\x46\x75\x57\xaf\x18\x1e\xbc\xdb\xbb\x38\x69\x0a\xf6\x2a\x1f\x88\x94\x35\x5d\xde\x65\x8e\xeb\x9a\xc4\x1a\x8c\x96\xe6\xf9\x94\x71\x23\xd3\xcb\x43\xde\xb7\x9e\xc0\x8d\xe2\x66\xde\x9f\xf4\x98\xf0\x3a\xab\xa2\xb5\xa5\xe7\x9f\x55\x97\xf7\xfd\x78\xfb\x23\xae\xc9\x44\xed\xab\xf4\x16\x1a\x0a\xf7\xf0\x96\x07\x81\x50\xb6\xc3\x33\xec\x49\x78\xc1\xd7\x8d\x1e\xb0\x75\xf3\xfd\x01\x38\x5f\x28\xd1\xd9\x6b\xd0\xf3\x2d\x8d\xa4\x4c\x56\xd8\x9d\x60\x07\xed\xca\x60\x45\x8d\x33\x6f\x12\xd4\xae\x18\xd8\xf3\xb2\x8d\x8d\x85\x28\x27\x4a\x0d\xaa\x7a\x5d\xfb\xcd\x35\x42\x4a\x66\xb5\x63\x6f\xb5\xa6\xe1\x33\xd5\x75\xed\x5e\xab\x94\xdd\x41\xe6\xa4\xcd\x26\x5d\x30\x63\xdb\xd9\x33\x89\x9f\xc7\x67\x3f\x59\xe5\xb5\x08\x03\x10\xbe\xa5\x20\xbd\x48\xf6\x5c\xe0\xac\x70\x90\xb2\x28\x3f\x40\x52\x79\x13\x16\xfa\x24\xee\x7d\xfd\x1c\x9a\x61\x31\xc4\x40\x71\x90\xce\xf3\x70\x52\x5b\x77\xc3\x01\x7f\x8f\x5f\xfe\x99\xdd\xa7\x5c\x82\x27\xbb\x63\x03\x9b\xb2\x5b\xd1\xe9\x7b\xb7\x9a\x79\xfa\x87\x2d\xaf\x1a\x4e\x8d\x69\xcd\x44\xf2\xaa\xe9\x11\xc9\xf7\x75\xa9\x1e\x2d\xcf\xd3\x7c\xed\xb5\xa8\xb0\xaf\x9a\xcc\xa9\xba\xb9\x66\xd5\xc0\x8d\xbd\x76\xb6\x18\xde\x9a\xc4\x44\xb2\x8b\x79\x6d\x73\x9f\x84\x50\xaf\x52\x29\xf8\x5e\x75\x54\xad\x6b\xa3\x4b\x0a\x97\x8f\x33\x2b\x78\x56\x2e\x4b\x92\x1a\x53\x76\xb3\x90\x0f\xb1\x58\xd4\x99\x20\xb4\x22\x6c\x77\x94\xdc\x5f\x0d\xfd\x14\x4d\x0b\xa5\x58\xbb\xb5\x42\xdf\x5e\xe8\xc3\xf3\x67\x69\x48\x33\x75\xf1\xff\x59\xcb\xa1\x09\x2b\x56\xfc\xd6\xf3\x00\x0c\xe8\xd5\x0f\xf4\x85\xae\xa9\xd4\x33\xa7\x3a\x75\xa8\x76\x59\x44\xdc\xea\x6e\xf8\xa2\x63\x05\x71\x98\x3e\x15\x8c\x7b\xba\x22\xe0\xf2\xd3\xd8\x69\xdc\xc5\xa3\x93\xbc\xca\x72\xae\xa3\x3b\xcf\xaa\x76\x45\x7a\x1d\x94\xb9\x11\x56\x0d\x0a\xcc\xde\x09\x10\x61\x41\xf8\xe5\xb9\x57\xb4\x84\x36\xbb\x3c\x69\x54\xab\x18\x1d\x2c\x31\x78\xcf\x88\x90\x0e\xb6\xa6\x7c\x24\x31\x42\x86\x16\x51\xc2\xea\xd7\xc4\x46\x67\xfb\x58\x42\x35\xdc\x8f\xb1\xf9\x8b\x61\x65\x7d\x48\x79\xb4\x1d\xb7\x12\x3d\xdc\x7a\xc2\xaf\x38\xc7\x1c\x11\x79\x5e\x99\x4d\x73\xe4\xbc\x3d\xf9\x7d\xe8\x4d\x80\xa3\xcb\x84\x52\x2e\x41\x99\x70\x1c\xb6\x15\x71\xc2\x45\x94\xc1\x60\x4e\x32\xe1\x05\x9c\xd6\xe9\x9c\x21\xeb\xe3\xca\xad\x7a\x43\xb3\x7c\x18\xe4\xbb\x77\x79\x56\x89\x4d\x6d\xa3\xd1\x32\xe0\x72\xb5\x20\x6b\x82\x48\xea\x6d\x08\x15\x64\x6d\x5d\x26\xdb\xdf\x1d\xd2\xcf\x6e\x17\xd7\xd6\x2e\x41\x79\xa8\xcc\x68\xe0\xe9\x8b\x9a\x80\x6e\xc2\x31\x01\xe8\xef\xd4\x0f\x64\x6e\xb9\x18\x8f\x6b\x7e\xf5\x37\x26\x3c\x23\xae\xf9\x73\xcc\x15\x84\xa4\x08\x74\xb3\x25\xd0\xb4\x9c\xff\x63\xea\xfb\xd3\xfa\x29\xf7\x98\xd8\x1e\xd6\xc6\x07\x5d\x4f\x8e\xbb\x29\x5d\xf1\xc1\xb0\x4f\xe7\x6e\xe8\x56\x49\x8c\x76\x2b\x75\xa4\x0a\x25\xd3\x01\xd2\x86\x0d\x53\x92\x62\x0e\x9f\xa4\x7f\xf9\x59\x36\xa3\x5d\x5c\x71\x3e\xa7\x25\x14\xbf\x89\x1b\xf8\x66\xad\x6c\x82\x99\xbc\xec\xa1\xa7\x31\x2d\x2a\x16\xa4\xa9\xee\x4c\x04\x38\x45\xc7\x0d\xb6\xfb\x72\x58\x23\x76\x5f\x04\x89\xa9\x2b\x8b\x6e\x9d\xa6\x7e\x4a\x53\x13\x21\xca\xdd\xcc\x94\xa6\x41\x79\x71\xe4\x26\xe2\x91\x45\x0d\x33\x06\x7c\x0e\x50\xc8\xa3\x1b\x44\xa9\x81\xe9\x10\xb0\x9e\x86\xcb\xe7\xaa\x1e\xfe\xc5\x10\x83\x9c\x15\xc1\x01\x11\x4c\x49\x78\xc9\xeb\x73\x65\x3b\xce\xe9\xb9\x17\xfd\x0e\xd4\x68\x93\x9c\x01\x9c\xb6\xde\x3a\x95\x5f\x58\xf8\xbf\x31\x52\xa2\x29\xa0\x57\xa8\x61\x7c\xa4\x9c\xdd\x7a\xc6\xb1\x8c\x0e\xf6\x72\xca\x0f\xc0\xad\x2c\x35\x52\x28\xf9\x39\xea\xc6\xff\x44\xf4\xcb\x0f\x63\xb3\x75\xcd\xf4\x93\xb8\xc8\x55\xb6\x61\x15\xf4\xa9\xc0\xe4\xf0\x44\x47\x9d\x52\xae\x09\x2c\x85\x26\xd8\x06\x84\x56\x6a\xe5\x1a\x3a\x3a\xe0\x7c\xe0\x8c\x13\xed\x54\x5b\x81\x8b\x7d\x05\x81\x61\x58\x9e\x8f\x7b\x37\x84\x99\xd0\xb5\xa7\x8b\x0f\x90\xa7\xc9\xc3\x97\xef\x54\x1c\x3b\xb0\x10\x7d\xcf\x4f\x8b\x46\xf4\xda\x9c\xec\x86\x96\xe1\x65\x67\x80\x23\xd7\x2c\x33\xa4\x3c\x76\x16\xd8\xe8\x2a\xca\x8f\x04\x5e\x38\x0a\x1a\x79\xc3\x89\xc2\x47\x37\xee\x5e\x4b\x50\x56\xe2\x4f\x2b\x62\x0f\xfb\xe6\x3a\xe5\xec\x1b\x7d\x5e\x73\x5d\x88\x38\x48\xe9\x5c\x92\x21\xc3\x87\x12\xd1\x35\xf1\x26\x3a\x83\x5c\x1f\x00\xb1\x5c\x7c\xae\x23\xef\xc1\x1e\xeb\x2a\x73\xdd\x90\xb6\x60\xfe\x6f\x58\xd2\xed\x5f\x90\xb3\x1e\x47\x06\x1d\x65\xde\xf0\x18\x8b\x01\x5b\x79\x8b\x74\x0a\x87\x2c\x05\xa4\xd3\x4c\xb6\x82\x1f\xd7\x7e\x94\xdd\x13\x70\xe8\xf3\x14\x61\x36\xda\x60\x75\x82\xc7\xb3\x32\xa3\xf8\xa6\xd2\x41\x01\xd2\x56\x3f\xfc\x19\x7e\x2e\x15\xbe\xab\x80\x93\xe0\xdb\x1b\x78\xfa\xad\xde\xfa\xda\x7e\xe4\xf1\x18\x9c\x32\x60\xc6\x66\x83\x6e\x19\x56\x55\x15\xb0\x3b\x7a\xc2\xfc\x6d\xae\x89\xf7\x53\x76\xef\x75\x9f\x61\x1f\x46\xca\x16\x77\x37\xd2\x50\xc4\x66\xaa\x81\x47\x28\xbc\xe2\x22\x84\x65\xc8\xf5\x7b\xfd\x2c\xbc\xbf\x46\xf0\x07\x7d\x1d\x6c\x22\x3f\x1b\x0c\x35\x69\x09\x7b\x1d\xf0\x1a\xdb\x38\x20\x5e\x55\xb8\x6b\xdc\x9c\xe8\xf6\x59\x6d\x62\x5c\x32\x0f\x9a\x6c\x63\x90\x5f\xf3\x35\xd2\xa8\x15\xc3\x58\x3e\x0f\x02\xa8\x81\x99\xe1\x47\xaf\x77\x06\x7b\x29\x6a\xbb\x36\x58\x74\x60\xc2\x9b\x2d\xcf\xc3\xe0\x0a\x53\x3c\x85\x33\x6f\x9c\x98\xfc\x05\xa5\x70\x0e\xe7\xdb\x95\xe1\xdc\x89\x4b\x50\x71\xad\xcf\x96\xcf\xf2\xbe\x3b\x7a\x5d\xdc\x71\x3e\x00\xbd\xed\x8d\x46\x64\x3f\x12\xe2\x83\xb4\x59\x44\x0c\x26\xc1\x59\x0f\x80\xa9\x8f\xb2\xb7\xf1\x89\xa1\x5c\x2a\x68\x1b\x94\x70\xce\xbc\x7f\x3d\x27\xf0\x00\x90\x70\xef\xe8\x4c\xa4\xba\x71\x17\xc4\x1c\x74\xe5\xd1\x81\xfd\x07\x3a\xc2\x15\x99\x07\xd0\xa3\xdf\xdf\x8f\xd3\x03\x8b\xa2\xb9\x44\x38\x3f\x3a\x51\x5f\xa6\x28\xb7\x11\x67\xac\x69\x50\x9e\xa7\x2b\x9d\x46\x36\x5b\x22\x39\x24\x1f\xa3\x59\x16\x5f\x29\x34\x68\x41\x00\xf8\x8c\xcc\x7c\x7b\x8d\xb1\xdc\x3d\xc9\xdb\x93\x99\x9b\x82\x93\x5c\x22\x9c\xe6\xb9\x36\x17\x9b\x1b\x7d\x88\xb5\xec\xe1\xf6\xf0\x80\x8b\xc1\x7d\xfb\xe6\xb8\xf9\x66\x22\xcd\x38\xd6\x09\x07\x2e\x9f\xbc\x95\x3e\x9d\xd8\x30\x2d\xf5\xf5\xbb\xdc\x98\x30\xf6\xce\x64\x73\x1b\x2f\x1f\x22\xd0\x9f\x70\x81\x23\x96\x38\x1b\xe0\x8a\x73\x72\x4d\x61\x93\x46\xe5\xf5\x2a\x69\xec\x10\x0b\x6b\xed\x68\xf6\x57\xb1\xfd\xe9\xf6\x9c\xde\x9c\x47\x89\xab\xfc\x58\xe5\x56\xf3\x13\xed\x86\x6f\xcf\xa5\xe1\xe4\xca\xdd\x35\xfb\x8b\x73\xab\x25\x18\x8e\x71\x8c\x2a\x21\x4a\x64\x8f\x86\xb6\xb4\xb5\x3d\x10\x70\xb9\xa6\xb8\x31\x7d\x21\x6d\x8c\x78\xb5\xe4\xdd\x85\x48\xe0\xb0\x0e\x46\xfc\xeb\xe0\xf1\xa8\x90\x08\xf6\xde\x5b\x01\xa2\xab\xfe\x4f\x05\x61\x06\xc1\xe9\x27\xba\x3e\x4c\x9e\x05\x4b\x75\xe9\x76\xb3\x85\x89\x84\xbd\xb1\x7e\xc5\xad\x39\x38\x07\x02\x2b\xfb\x43\x8d\x78\x11\x5f\x4c\x4a\x41\x05\xff\xc8\x16\xcc\xc2\xdb\x0c\x8f\xcf\xc2\xf8\x17\x6d\xe2\x5f\x54\x0a\xd9\xd5\x14\x32\x45\x80\x82\xc4\xdd\xc7\xbd\xda\x9d\x65\x48\x2a\xd3\x77\x7b\x44\x2c\x44\x2f\xdb\x20\x8a\x14\x8c\xae\xd2\x70\xf0\x3e\xe4\xb1\x24\x4e\xa9\xbf\x15\x4a\x6f\xc2\x48\xf0\x3b\xa1\x54\x79\x71\x35\x0f\x4a\xee\x5b\xe8\x8c\xd9\x4c\x66\xce\xf3\xa7\xc3\x98\x4e\x75\xf4\x7d\xee\xd2\x73\x07\x7f\x57\x05\xd3\x96\x82\x2b\x6e\xa7\xf6\x52\x7c\x94\x80\xee\x5e\x39\xbf\x1b\xa6\x25\x84\xd3\x26\xa1\x22\xf7\x6c\xea\x8f\xf2\x8d\x16\x95\xec\xd7\xc9\x1d\x65\x87\x26\xd8\x41\x89\x28\xff\xd2\xa8\x6a\xc2\x9e\xcd\xe5\x9e\x66\x46\xc6\x8f\x10\x60\xdd\x54\x72\xb3\xa9\x33\x7c\xd5\xa2\x06\x1e\x45\xa3\xc3\xec\x71\xc3\x08\x79\x8d\x25\xa1\x4c\x9b\xb4\x27\x5a\x49\x59\x29\xf9\x61\x83\xa6\xac\xf2\x77\x05\x56\x81\x05\xec\x4b\xfc\x98\x73\x6e\xce\x1b\x27\x15\xc4\x42\x70\xbd\x44\xbb\x9f\xdd\x7b\xfd\x46\x7f\xb1\xac\xda\x55\x4f\x5c\x4f\x18\x5e\x34\x3c\xd3\x38\x7b\x16\x6d\x9f\x9a\x3c\xbe\x66\x3a\x37\xc0\x55\x03\xd0\xca\x12\x10\xfa\x19\xa8\x00\xe1\x38\xfb\x0f\xb5\xc8\xd4\xbc\xde\xc9\x01\xd0\x3f\x83\x18\xc4\xbd\xc5\x86\x64\xc9\x43\xf1\x01\xe4\xf7\x46\x62\x5b\xda\xde\xeb\x19\xf5\xad\x88\xb9\xcc\x91\x26\x02\x4a\x51\xe1\xe1\x5b\xc7\x99\x9d\x66\xc4\x17\x6d\x35\xae\x24\x87\x67\x3a\x25\xe6\xcc\x49\xf7\xbe\x36\x97\x3d\x76\x4a\xbc\x6d\xcc\x9f\xb0\xd6\x3f\xd2\x10\xc2\x93\x06\x2b\x01\x2f\xba\xa7\x9e\xfd\x7f\x53\x89\x2e\x1c\x14\x02\x4a\x16\xe3\x03\x14\x24\xa7\xa7\xfe\x51\x4e\xa4\xff\x5f\x0b\xa4\x70\x8d\xb7\xd9\xad\xdb\xae\x68\xab\xc7\x69\xcc\x8c\xd1\xfb\xbc\xa1\xa4\xa2\x60\x41\x9b\x45\x33\x4a\x92\x03\xa0\xbf\xfd\xa4\xe7\x7f\x17\x47\x4e\x18\x92\xf7\x85\xcb\x78\x69\x98\xf9\x85\xc5\x0d\x7c\x1b\x86\xfb\x93\xd9\xbc\xdd\x5c\xe5\xb7\x69\x6d\x58\x87\x4c\xf4\x66\xb7\x13\x9d\x54\x9b\xa4\xbe\xa9\x4d\x51\xe5\x3f\x2a\x10\x20\xda\x5c\x14\x7c\x61\x3d\x3f\x65\x3a\x1a\x42\xb1\x97\xab\x06\x0e\x39\xb8\xa7\x59\xb8\xb5\xa3\x2d\xbd\x14\x0c\x4f\x80\xda\xc6\xcb\xc3\x0f\xc8\x1d\x05\xa4\x0e\x4d\x37\x44\xc2\x2d\x82\x36\x1d\x08\xd7\x9c\x9c\x6c\x4f\xaa\xcc\xd7\xe2\x45\xcf\xab\x3f\xde\x48\x1a\x3b\xe6\x6a\x87\xa3\xe0\x2f\xdb\x11\x1e\xd1\x4c\x48\xac\x38\xba\xd1\x97\xce\x4a\x4d\x24\xf2\x54\xda\x87\x91\xc0\x25\x99\x5d\x17\xc9\xdb\x2a\xdb\x1e\x69\x96\xb0\x3e\xf1\x37\x1e\xfc\xdb\xfa\xc7\x2d\x22\x98\xfa\xd3\x2d\x7f\x67\x1c\xd8\xb2\x1b\xcb\x52\x81\x4b\xab\x69\x91\x58\xc1\x65\x56\xd2\xbc\xa9\x9a\x53\xae\xeb\x93\x09\xa9\x06\x26\x7c\x9e\x12\xf2\x5e\x3b\xed\x29\xe9\xef\x54\xd5\x08\x00\xa8\x4a\x1f\x03\x49\xfd\xcd\x57\xb3\x10\xcc\x42\x82\xcb\xf8\x1a\x39\x10\xa2\xd7\xfd\xce\x56\xed\x96\x63\x5e\x58\x43\xf5\x48\xca\xa9\xcb\xc0\xa7\x86\x2b\x61\xe9\x66\xcc\x97\xeb\xe7\x67\x9b\xa6\x9e\xc0\x48\x03\x34\x08\x2d\x66\x58\x8f\x2a\x81\x5e\xc3\xfe\xa7\x90\x5e\xa7\x24\x8e\x21\xd1\x8b\x7d\x43\xb7\xd8\xb0\x92\xfd\xa9\x0a\xf7\x86\xf8\x9e\x48\x3e\x0c\x2b\x4c\xeb\x77\x91\x80\x71\x0c\xd0\x45\x59\xb2\x19\xc9\x0e\x1c\xfd\x6b\x41\x8c\x4e\x2d\xfe\x6f\xff\x4a\xd3\xbb\xb5\xa9\xe2\x68\xd5\x3a\xf3\x09\xe3\xf0\xd3\x00\x0e\x68\xb0\x6e\xd8\xcb\xa9\x63\x87\xed\xad\x57\x69\x78\xd9\x25\xdf\x6f\x0f\x07\x84\xa4\xe8\xff\x0c\xd0\xf3\x66\x68\x74\x28\x51\x72\x9c\x3e\x96\x13\x55\xf3\xc6\x64\x16\x03\x2d\x2c\x66\x6c\x12\x58\xec\x0e\x2e\x2e\x27\xe8\x2b\xd7\x4e\xff\x0a\xfa\x44\xc5\x96\x34\x08\x2a\x93\xf4\xe5\x9a\x6b\x63\xdd\x40\x16\xea\x06\x9d\x0c\xb3\xc4\xa2\xb1\x22\x07\x1b\x55\x2b\x01\x7b\x5d\x3d\x6e\xe2\x27\x21\xdd\x20\x72\xe7\x48\x76\xa0\x80\xec\x1d\x04\x3f\xad\xe1\xc5\x98\x17\x5a\xfa\x09\x11\xf6\x95\x87\x3f\xb1\x1b\xc7\xdc\x87\xe8\xcc\xc7\x43\x06\xd9\xf0\x85\xc8\xb3\x07\x80\xf8\x43\x7f\xf1\x5e\xa3\xf6\x23\xc5\xd2\x6f\x61\x29\xfb\x39\xaf\x4f\x88\x3e\xbf\xbf\x2b\xd1\x99\x33\x37\x5e\xca\x36\xec\x6f\xea\xde\xcd\xce\xc4\x05\x2e\x31\x40\x0e\x64\x75\x11\x97\x72\x1c\xc6\x05\x49\x10\x2c\x0e\x9a\x40\x15\xc1\xa7\x7e\x88\x12\x33\x62\x02\x00\xfa\x00\xf4\xf1\x3f\x0f\x81\xdf\x3d\x32\x78\xf1\x46\x90\xe8\x87\xb4\x4b\xbd\xe7\x9f\x73\x82\xc1\xb7\xc9\x07\x17\xaa\x1d\x98\xd2\xb9\xd4\xf0\x0e\xce\x9f\x77\x25\xdd\x2e\x13\x21\x29\xfa\x0a\xba\x53\xb3\xe8\xf2\xe2\xd9\xbe\xe5\x2e\x3d\x2d\xe9\x36\xe2\x04\xc9\x7d\x9f\x0c\xcd\x42\xde\x6e\xf2\x67\x8b\x4f\x82\x65\x90\x16\xbf\x8a\x11\x86\x5b\x01\x74\x35\x9f\x4c\xbf\x6f\x84\x4d\x08\xc8\x96\xcb\x10\xf2\x90\xae\xf5\x34\xbc\xfb\x46\x86\x1b\x70\xc4\xd3\x4a\xb5\x5b\xed\x35\x8f\x8c\x89\x3a\x90\x26\x9d\xb3\x83\x7f\xac\x95\x6a\x3d\x62\x2e\x65\xb4\xbc\xd6\xf2\xe8\xb5\x50\x40\xf8\x06\x57\xc8\xf3\x99\x76\x83\x9b\x69\x2d\x91\x87\x10\xba\xc8\x68\xdc\xbf\x9d\xb9\xbf\x89\xd4\x03\x38\x53\x4a\x48\x52\x7a\xcc\xd4\x41\x02\x7c\x54\xd7\x9a\x8b\xe5\x7e\x4b\x9f\xb6\x1d\x5e\xb1\x9d\xe5\x12\x61\xa0\xde\x54\xd2\xb7\x96\x32\xa3\xe3\x8a\xa9\x53\x2e\xb4\xc9\x07\xbc\x6c\xa4\x2b\xef\xed\x20\xf4\x2f\x3c\x10\x2f\xea\x8e\xc3\x3d\xa5\xa5\xf5\x5e\x68\xcd\xed\x83\xe6\x12\x3a\xf4\xfb\x37\x21\xe6\x7e\xf7\xa8\x72\x14\xc4\x39\x3a\xfd\x8c\x0c\xeb\xf2\x40\xff\xf3\x32\xe8\x63\xf7\x30\x6d\x7a\x01\x52\xfa\xae\xa2\x8d\xbc\x94\xdc\x18\xef\xa9\xd8\x9f\x9c\xd7\x96\x3d\x4d\xb7\x39\x38\x8b\xc9\x16\x4c\xa1\x47\x95\x99\xd1\x17\x3b\x01\x52\xb8\x91\xe0\x7f\xbd\x36\xfb\x76\x39\x3f\xec\x61\x29\x44\x98\x5b\x11\xae\x11\xbc\xf6\xa4\x42\xcd\x4b\x0d\x0c\xeb\xa0\xcc\x6a\xe3\x87\x47\xf0\x3c\x4d\xd4\x09\xcb\xfe\x68\xee\xf8\x22\x1b\x0a\x4a\x1a\xf7\xbe\x55\xed\xe0\xfb\x75\x68\xc4\x8c\xfc\xa0\x14\xac\x30\x9f\x37\xaf\xf5\x0e\x5d\x79\x88\xbb\x2f\x4e\xf0\x97\x42\x15\x58\x26\xc6\x8b\x2d\x40\x78\xaf\x1e\x86\xbf\x68\xc0\xd2\x61\xf2\x93\x3c\xee\xe6\x65\x25\xe0\xf6\x8f\xc3\x48\x26\xb5\x15\x39\x34\xc8\xfe\xff\xa1\xe2\x84\x4b\xb6\xf8\x77\x5f\x85\xee\xeb\xe4\xb6\x4f\x9a\xd1\x72\xb5\x44\x25\xa2\x77\x5c\x63\xd2\x78\x36\xaf\x96\x8d\x74\x49\x97\xb4\xf1\x41\x58\xd7\x4e\x89\xb6\x8b\xc7\xf0\xd3\x4a\xf3\x38\x51\xee\x22\x67\x09\x6d\x58\x36\x86\xb5\xab\x7f\x84\xc8\xe3\x19\x03\x74\x18\x73\x01\x3b\x40\xea\x12\xaf\x02\xf8\x92\xb6\x73\x58\x27\x64\x96\x9e\xf5\x4b\xff\x7d\x50\xfa\x42\x50\x59\xfe\xef\x1d\xca\xfe\x5f\x22\x88\x2c\xcd\x3c\x95\xbb\xe0\x2a\x91\x81\xf7\x79\x35\x31\x8f\x72\x42\xec\x48\x6f\xd6\x34\x12\xb8\x82\x75\xfb\x31\xa5\x76\x19\x31\xb5\x4d\x9d\xcb\x37\x9f\xa8\x05\xa6\xa8\xb6\xf8\x95\xd4\xfb\x82\x4c\xbd\xc9\x8f\xea\x5c\x5e\x75\x27\xcc\x12\x2b\x38\x19\xc4\xc5\xde\x62\xda\x6d\xea\x6b\x67\xcf\x3d\x09\x53\x07\x6d\x65\x15\x10\x64\x3a\xa3\x5d\x54\x29\x74\x77\x70\xb7\x4f\xd5\x9f\x21\x8e\x6b\x04\xd3\x3a\x0e\xc2\x5e\x88\x5d\xb0\x9c\x3d\x00\x92\x6a\xe0\x1f\x53\xef\xfa\x39\x87\xd2\xb0\x0a\xff\x13\x9a\x04\x67\xfd\xd1\xef\xc7\x8f\xa7\x0d\x0c\x5e\xd7\xf4\x53\xa7\x58\x98\x06\x60\x02\x4a\x4e\x4e\x74\x75\xbc\xdc\x15\xe4\xc4\xe6\x11\x52\x98\x50\x86\x18\x1f\xc3\x52\x54\x6b\xdf\xf3\x45\xa3\xaf\x27\x0a\x1f\x2b\x46\xf6\x70\xb4\x78\x32\x7d\x7a\x83\xf7\xfb\x79\x63\xfd\x18\x97\xa1\x89\xf7\x04\x82\x8a\xb1\x3b\x2a\xa2\xcd\xba\xe9\x8c\x7b\x4a\xb0\x52\x3a\x51\x99\x2c\xb7\x35\x82\x5b\xce\x8b\x20\xef\xf2\xf0\x31\x5b\x66\x13\x63\xb1\x1e\x78\xa7\xe4\x24\x56\x6a\xef\x03\x80\xa5\x90\xa7\x13\x96\x4c\x03\xfb\x72\xec\x3b\x28\x36\xa8\xda\xd3\x8a\xc8\xc5\xc7\x7d\xa5\xf6\x0d\xa0\xec\x17\xff\xb7\x83\x3f\xbe\x5b\x03\x16\x69\xea\xb6\x93\x42\x92\x06\x58\x9b\xb7\x76\xaa\x0f\x4d\x1d\x1f\xac\x54\xd1\x9c\x34\xe5\x6b\xa2\xbc\x23\xe1\x5b\x27\xa3\x18\x78\x84\x99\x34\x75\x47\x10\x7b\xba\x12\xfd\x63\x4e\xb0\x33\x98\xbc\xc7\x87\x26\x56\xb5\xd6\xb0\xad\x6d\xc8\x82\x75\x60\x92\x6f\x05\x45\x86\x76\x98\xf4\x26\x65\x1e\xc6\x1d\x86\x1d\xa9\x93\x79\x41\x0e\x5f\x8c\x6d\xae\x86\x36\x0e\x50\x88\xdb\x27\x94\xd6\x57\x7e\x71\xc2\xaf\x7b\x25\xba\x3b\x1b\x1b\x96\x19\x4d\x3f\x77\xb8\x10\x5f\x77\xf1\xfe\x55\x09\xfe\x90\x06\xad\x65\x3d\x34\xe7\xb3\x9b\xad\x03\x36\x2a\xe3\x7d\xed\xfc\x2f\x3b\xf3\xa6\x2f\x94\x5b\x6e\x3d\xd9\x6d\x8f\xee\x9d\x50\x6a\x20\xe1\x76\xa2\x7e\x23\x92\x7a\x95\xd7\xaa\x8f\x0c\x0d\xf4\xe4\x0f\x70\x5d\x60\x92\x96\xd9\x69\x87\x87\x46\x8d\x1b\x95\x6f\x0e\xd2\xe9\x2a\x47\x5f\x27\x0a\x85\xe3\x98\x89\x61\xdc\x68\xaa\xd8\x3c\x00\xaa\xfe\x84\x2b\xca\x2c\x23\x26\x24\x82\xf6\xea\x44\x80\x65\x6c\xfd\x88\x0f\x9d\xf5\x44\x98\xa0\xfd\x7b\xab\x99\x9a\x00\xf6\x75\xa2\x99\x2b\x35\x70\xbe\xcd\x7c\xb9\x77\xd1\xf2\x92\xa8\x96\x2e\xb3\x39\x53\xa8\x02\x33\x79\xd7\x2d\x5b\x0b\xc3\xcf\xa4\x9f\xe0\xe5\x86\x24\x21\x08\x3c\xda\xfd\xb7\xe8\x2d\xd7\xb4\x8e\xb9\x8a\xe7\x87\x90\x22\x65\xa2\x08\xf1\xfb\x34\x8a\xd4\xad\x56\xb0\x66\x34\xa2\xd0\x51\x9e\xbf\x7b\xcb\xf5\x69\x80\x94\xfc\x0e\x6b\x53\x03\x34\x23\xd9\x8d\x31\x4e\xcd\x36\x1a\x65\x5f\x6d\x5e\xbc\x62\xed\x32\xc6\xe2\xad\x9c\x46\xe2\xa8\x80\xd7\x04\x0f\x9c\x6e\xd5\xec\x8e\x66\xb0\x39\x0d\x3f\x2d\xf0\xd1\x4b\x11\x5e\xda\xfe\xd0\xbd\x63\xd7\x05\x76\x3c\x80\x1e\x42\xe8\xd3\x74\x17\x27\xea\xcd\xf3\x7e\xd6\xaf\xfc\xce\x60\xfe\xd0\x97\xde\x11\xd3\x2c\x5b\x05\xda\xcc\x6d\xbb\xef\x25\xc2\x7f\xf7\x95\x22\xcd\x5c\x74\x04\xff\x62\x98\xce\xbf\xc4\x0b\xc8\xb3\x83\xdf\x59\xea\x34\x37\xd9\x09\xaa\x9c\xda\x99\x12\x6c\xb7\x0c\x8c\x37\xc5\x06\xb3\x04\xc2\xf6\x23\x3b\x0b\x6f\xe5\xd7\x3c\xed\x4c\x2a\xac\x2f\xb5\xb4\xdf\x0f\x99\x1a\x22\xf9\x5e\x78\x05\xe6\xf8\x0f\x34\xb4\x71\x11\xa4\xef\x69\x05\x4d\x69\xc8\x6d\x47\xa3\x2d\x36\xaf\x45\xf2\x7e\x6a\xe1\xe6\x14\x6d\x51\x7a\xf5\xfd\x0b\x50\x5b\x7b\x9a\xed\xed\x75\x67\x05\x9a\x52\x97\x7d\xb2\xe5\x5a\x11\x47\x0e\xbb\xf8\x80\x7b\xf0\xe3\x01\x80\x49\x28\xe9\x17\x7b\x71\x94\xa0\xdc\x77\x94\x57\x08\xa7\x37\x35\x17\x4f\x5e\x55\xf4\x4e\x26\x68\xb4\xb9\x30\xcb\xad\xaf\x98\x7c\x59\x8f\x52\xe2\xf3\x95\x7e\x0f\xa1\xff\x80\x10\x00\x5c\x6f\xd2\x70\x89\x8f\x9e\xb9\x0c\xc1\xe8\x93\x8f\xd9\xb6\x0d\x16\xe2\x6f\x29\x42\xe4\x3f\x4f\x3c\x59\xd4\x1d\x5a\x76\x49\x41\x6f\x77\xfa\xb1\xb5\xdb\x0e\x78\x96\xf4\x5f\xbd\xf2\x23\x6e\x7a\x81\x1a\xa6\x53\x30\xb2\x55\xdd\x08\x7e\x8c\xc8\x0a\xdf\x22\xa1\xc4\xa0\x9f\x83\xdd\x9a\x7e\xad\x0e\xc3\xf8\xd4\xe7\xe0\x88\x7d\xec\x97\x49\xbd\x7f\x4f\xc7\x14\xd5\xdb\x50\x8a\x4b\x86\xfd\x3c\x19\x1e\xad\x06\xb6\x8b\xe5\xf8\x27\xe5\x71\xd1\x07\x20\xdc\x0b\x67\xde\x47\x72\x1c\xff\x85\x72\xc6\xa7\x36\x45\x08\x63\xf6\x2d\xf5\x69\xce\x67\xaf\xbe\x94\xf4\xb9\x8b\x38\x2e\x8c\xab\xe8\xc8\x0c\xf7\x1b\x5a\xc2\xe5\x3b\xdb\xe5\x9d\x68\xe5\x47\x4c\xf7\x4c\x91\x57\x0f\x40\x7f\x8b\xe6\x60\x90\x8f\x8d\x70\x86\x71\xbf\x32\x23\x4f\xa3\xc4\xec\xdd\xa6\x2a\xa0\x06\x9e\x64\xef\xfe\x42\x6c\x3d\x97\x9a\x67\xa3\x76\x90\x6e\x26\xa2\x26\x6a\xb5\xa5\xd6\x15\xe7\x35\xfb\x5f\x62\x40\x61\x30\x33\x93\x6f\x2c\xe6\x3e\xf7\xa7\xda\x50\x68\xe5\xfe\xed\xc1\xf9\x1b\xe0\x4c\x98\x11\x3e\xd6\x3c\x6d\xec\x3f\x6b\x55\x0d\xbf\xf6\xbf\xd0\xc7\x6c\x4d\xd3\xd4\x58\xdf\x7a\xee\x74\x5b\x0a\x5a\xd3\xba\xc0\xce\xc7\x3f\xe1\x8c\xf6\x10\x2d\xb3\x3b\x5e\x6f\xa1\xc9\x4b\xa6\xf5\xaf\x75\x31\x12\x2e\xb9\xe5\x9b\x13\x2e\x3c\xbd\x55\xaa\x5e\x9d\x50\x7d\x42\xb9\xc5\x19\x29\xc5\xa1\xaf\xe4\x1f\x2a\xcd\x3c\x93\xf1\xb6\x23\xdb\x50\xfa\x5a\x95\x53\xdf\x33\x47\x42\xb5\x54\xf4\x32\x97\xc8\x36\xbf\x20\xa4\xb1\xaf\xfa\x40\x50\x5d\x0d\x80\x16\x1e\x2a\xcb\x8b\xfd\xd7\x78\x5b\xff\x31\x8e\xfa\x01\xf0\x6a\x13\x2f\x03\x0a\x1f\x1a\xbd\x64\xa3\x25\xc0\xd3\x51\x64\xb5\x94\xf8\xc6\xd2\xf9\xbc\xbb\x0a\xe1\xd4\x4f\x99\x4b\xc4\x84\xf0\x8f\xad\x57\x91\xd1\x12\x97\x89\xa4\xc7\x5e\x92\x30\xcd\x39\xc6\x92\x74\x74\x31\xaa\xb1\xf3\x20\x18\x7b\x8d\x54\xac\x2a\xc9\x7b\x9f\x60\xb0\x16\xd5\x46\x52\x02\x4d\x19\x81\x5c\x4c\xde\x95\x7f\x6b\xe5\xf5\xf7\x3a\x59\xaa\x34\xed\xcb\xc1\xcb\xd6\xf7\x4e\x22\xbb\xb6\xbe\xaa\x1c\x32\xe0\x3c\xbd\x54\xb8\xfa\x03\xa1\xbf\x91\x73\xe9\x20\x41\x92\x42\xe3\x5e\x36\x76\xbe\x89\xe3\x97\x97\xa5\xec\xae\x8a\xfc\x77\xdc\x91\x23\xa5\x26\x8f\x5c\xcc\xfc\xbc\x94\x03\x76\x79\xc3\x00\xfa\xc2\x79\xf3\xcb\x88\xb3\x18\x31\xaa\xe3\x73\x3c\xab\x17\xd1\xf1\x27\x80\x15\xc8\xe2\xeb\x49\xa1\x29\x77\x17\xee\xc9\xca\x7b\xf8\xdb\xaf\x2c\xe9\x74\xd4\x13\xbb\xea\xd0\x6e\x6e\x64\xd5\x2c\x43\xc4\x2e\x43\x88\x93\xde\xdc\x5a\xb4\x8f\x09\xe6\xd2\xca\x87\x86\x0c\x07\x42\x27\x5b\x7a\xb5\xa4\x68\xb8\xa4\x3d\x7c\x8d\x0c\xed\xe0\x9e\x1d\x95\x94\x8b\x32\xc7\x85\x39\x3f\x6d\xbe\xa7\x64\xba\xca\xbc\xf3\x95\xa1\x46\x8e\x7b\xf4\x7b\x95\xc4\x3a\xac\xff\x68\x9d\xfd\x38\xf3\xbb\x24\x9e\xa8\xa6\xa2\xc9\x2e\xec\xe6\xe7\x2e\xdb\x6a\xbd\x34\x8d\x95\xb8\xef\xee\xd7\xa4\x9e\x7b\x77\xd0\xe3\x64\x59\x01\xd0\x9a\x3b\x4e\x55\xdc\xa0\x1f\xba\xa7\x1d\xf3\xac\xab\x99\x46\x4b\x40\xd9\x09\x9c\x72\x15\x8c\x02\x41\x68\xfc\x48\x10\xae\xd4\x1a\x8e\x5f\xdc\x48\x72\x45\xe5\x18\xbc\xa5\x4b\xda\x3d\x10\x7d\x35\xb9\xb8\x58\x52\xe5\x63\x7e\xd4\xa8\x06\x43\x4d\xfa\xc5\x0b\x7d\x13\x81\x4c\x6e\x2b\xb8\x23\xa8\x81\x6b\x56\x6d\x0b\x9d\x1f\x42\xf8\xcf\x77\xc6\x31\xa8\x84\x27\xfd\x1b\x04\xb2\x1d\x86\xe3\x38\xb2\x29\xb8\x02\xbe\xe3\x2e\x32\x60\xe6\x93\x33\x75\x50\x61\x8e\xc8\x9a\x9a\xe7\xf5\xfc\x60\x7f\xc6\x6c\x2d\x22\xa4\xb7\xcd\x96\xd1\xb4\xd1\x96\x54\xf0\x4a\x93\xe1\x73\x59\x0c\x6b\x5c\xf2\xf6\x80\xc1\x17\x35\xe8\xbb\x3d\x76\xd0\x0c\xda\xd0\x66\xed\x79\x1c\xa1\xb5\xde\x51\x67\x52\xe9\xaf\x97\x8e\x19\xc1\x26\x0b\x92\x91\xb3\x7a\x6e\x80\xa7\xf0\x65\xb7\xbe\x7e\x46\x03\xce\xb7\xe5\x41\x53\xe6\x54\x5b\xa7\x49\x97\x4c\x5e\x63\x09\xd7\x7d\xa3\x88\xbc\x3d\xf7\x96\xc7\x69\x04\x31\xf9\x76\x91\xac\xb8\x60\xaf\xb9\x7e\xca\x5c\xac\x84\xee\x6a\xe6\x48\x7e\x4b\x64\x0f\x2a\x57\xf3\x46\xae\x25\x65\x59\x89\x65\xdd\x59\x74\xd0\xc1\x68\xee\xb0\x72\xba\x2d\xe5\x7a\xa5\xaa\x43\x88\xe2\xe3\xb7\xef\xfa\x55\x7c\x5d\xfc\x43\xb7\x43\x3b\x01\x52\x7a\xcc\x5f\xbb\x44\xab\x39\x91\x37\xfe\x96\x3e\xaf\x11\x95\xeb\x3d\x9e\xc5\x8a\xba\xa3\xa6\xcc\xcc\x71\xb7\xd0\x85\x6f\x2f\xef\x2b\x88\x6c\x90\x6b\xd1\xd3\xec\x48\x8a\x90\x1a\x6e\x13\x78\xd6\x4f\x74\x45\xb1\x11\x53\xc4\x66\x80\x54\xe8\x5c\x63\x4f\xc9\x62\x5a\xa9\x8e\x6c\x99\xce\xa8\xb5\x73\x24\xf2\x75\xab\xae\x22\x86\x5f\xfd\xe3\xc4\xed\x8a\x8f\xcb\xce\x4b\xf2\x2a\x1f\x72\x89\x78\x67\x7c\x04\x37\x3b\x71\x0c\x57\x9e\x65\xce\x5f\x2e\xfa\x54\xb6\x88\x16\xfa\x66\x6b\xd3\xae\xbb\xc3\x64\x62\xd4\x32\xe4\x91\xfe\x91\x6e\x56\x39\x9a\x3f\x62\x47\x86\x12\xab\xa9\x9b\xd8\xec\x55\xc5\x06\x5c\xd6\x4a\xbc\xce\x4f\xd0\x0e\x38\x9e\x07\xb8\x44\x02\xd5\xe6\x36\x0d\xee\x35\x5d\x91\xe8\xf2\x79\x10\xba\x10\x97\x0f\x24\x0e\xd2\xfd\xeb\xbe\xea\xda\xa0\xaf\x0d\x84\x22\x96\x2c\x84\x59\xd7\x0b\x86\x06\x44\xfd\xf5\xd6\x92\x04\x2e\xd4\x94\xbd\x9e\x11\x41\x77\xe2\xf7\x9d\xaf\x81\x22\x44\xfa\xb8\x5d\x1b\xcf\x27\x6d\x07\xd8\x29\x5d\xc7\xed\x3d\xf9\xde\x6f\x81\x30\x49\x6d\x86\x75\x4a\x2d\x5e\xc2\x5f\xdf\x02\xc8\x18\x45\x07\x24\xb4\x3f\xde\x96\x48\x49\xed\x81\x06\xfc\x04\x85\x8c\x75\x0a\xa3\x73\x1f\x6f\xeb\x7e\x27\xca\xbb\x1d\xaa\x5a\xeb\xaa\xa9\xdd\x73\xe4\xfa\xc4\xfd\x0d\x4b\x2d\x7d\x5d\x5a\xa8\x76\xb4\x74\xef\x02\x6e\x6d\xe1\xdf\x9a\x00\x63\xd4\x2e\x86\xbe\xe0\x49\x97\x04\x8d\x62\xbb\xe3\x07\x42\xe8\x18\xf7\x95\x15\xc5\xd5\x27\xd1\xe4\x98\x60\x36\x46\x2e\x47\x7f\x6f\x25\x9c\xb3\xa5\xa7\xfc\xeb\x6f\x45\x9c\x13\xf2\xd3\xdc\xd7\x49\x0b\x1f\x80\x67\xbe\x87\xe5\x85\x9c\xd8\xdd\xc0\x24\x38\xda\x47\x68\xe1\x99\x2b\x81\x1a\xca\x54\xd3\xec\x8d\xe5\xc8\x68\x90\xcb\xb2\x5b\xb5\xa5\x16\xbe\x00\x81\x67\x63\x5f\x0e\xbe\x9c\x53\x71\xd6\xdb\xe1\xbc\xba\x96\x06\x69\xe3\xf8\xa3\x37\x09\x43\x62\x92\x84\xb6\xbc\x5d\x9d\xe4\x95\x0e\xf8\x5e\x5a\x95\xa2\x86\x72\x6f\xe7\x39\x05\x62\x62\xaf\x68\xd5\xc0\xd5\xef\xde\xbd\x14\x7f\x93\x97\x10\x48\x79\xf0\x5f\x70\xa7\x0c\x3d\x70\x6d\x68\x48\xb4\x14\xd5\x50\x57\x1a\xf7\xd9\x2e\x36\xea\xdf\x84\x45\x4f\x1b\x91\xd3\xbf\x61\x69\xc1\xcf\x8c\x76\x9a\xb0\x6d\x47\x8d\xc2\xa3\xa4\x68\x5e\x64\x28\xc4\xaa\x2f\x2c\x30\x5a\xf0\xc9\x04\x4b\x6e\x5d\x54\x93\x21\x0c\x8c\x58\x9b\x67\x9f\xb1\x20\xfa\xab\x16\x92\x03\xac\x73\x08\xb6\xe3\xde\xa4\x03\xd7\xa6\x06\x48\xfa\x8c\x8d\x2c\xca\xe5\xd5\x11\x2c\x51\xc5\xd9\xed\xcc\x6b\xb4\xd5\xa6\x2c\xd0\x8b\xb9\x5b\xbb\x4a\xb9\x4d\x29\x9f\xaf\x76\x70\x99\xbd\x06\x9b\xa6\x9e\x5d\xc6\xc6\x4e\xbf\xba\x74\x85\x1e\xdb\x8c\x9b\xfa\x59\x49\xcd\xb2\x71\x7f\x51\xe3\x61\xfa\x13\x72\xa9\x10\xaf\xf6\xac\x0a\xf7\x94\x43\x32\x53\xdc\x02\xd0\x3e\xe4\x91\x7c\x2b\xb3\xe6\x00\x1f\xc7\xd9\x57\x3a\xeb\xff\xfe\xcc\xfc\x7f\xc9\x1a\xe1\x41\x2d\x70\x3b\xa1\x8c\xd8\x0d\x41\x9e\x33\x98\x8c\xd7\x6e\xd5\xea\xd5\x4c\x28\x98\x50\xd9\xf3\xd8\x80\x23\xf9\x2f\xd1\x7f\xcc\xef\x14\x50\x6a\x58\x97\xbd\x34\x8a\x95\xb7\x3c\x0e\xb4\x0e\x4d\xf4\xaa\x63\x44\x1f\x9c\xf4\xe9\xd9\xe6\x84\xed\x48\x99\x3c\xcc\x3f\x3d\x5b\xdf\xdb\xef\xe2\x8f\x33\xb8\x24\x8f\x42\x0c\x4b\x56\x3e\xfb\xf4\x7c\xfb\xf4\x2d\x76\xea\x18\x0c\xae\x97\x43\x52\xcf\x5c\x8c\xe2\x7d\x97\x45\xe1\xf2\xf5\x02\x2d\x51\x1c\xb9\x18\x20\x79\xf3\x0a\x75\x68\xc7\xe2\x52\x55\x69\x8f\x7c\x53\x02\x1a\x36\xec\xbd\x9a\xff\x22\x43\x23\xb4\xa3\x06\xa3\x32\x40\x94\x3a\xea\xc0\xab\x1c\xa1\x47\x03\x5c\x5c\x1b\x0a\x61\xb9\xad\xb5\x29\xca\xe5\x1a\x16\x0e\x1d\x2c\x54\xc3\x92\x97\x55\xf7\xaa\xa1\xd2\xe4\xe9\x2e\x12\xfb\xc4\x54\x38\xc3\x5d\x8c\x7e\xba\xfd\x80\xb1\x7f\xcf\xce\x0c\x7e\xb8\x3a\x29\x22\xd3\xde\xcd\x5e\x9b\x59\x32\xb2\xd9\x16\x69\xab\x98\x7d\xd6\xd7\x3d\x2f\xf9\x68\xc7\x9d\xe1\xc3\xeb\xc9\xa4\x0d\xcb\xcf\x85\x2a\x95\x05\xb2\xb0\x4b\x67\x19\x35\x9b\x8c\x5b\x5a\x44\xd2\xba\xf0\xe7\x10\x05\xd9\x8b\x34\xd1\x07\x60\xb0\x14\xa4\x29\xcd\xb4\x47\xfa\x3a\x21\xea\xe7\xc0\x36\x37\x1e\x1f\x28\xce\x45\x97\xc2\x9f\x4a\x92\xc3\x66\x09\x73\x49\x71\x85\x28\x25\x23\x40\xaa\x99\x56\xbd\xa4\x7b\x0d\xe7\x18\xb3\x82\x32\x84\x06\x22\xd8\xf9\xb6\xed\x74\xdc\x4a\x01\x31\xd8\x53\x86\x2b\x77\x97\x84\x83\xeb\x92\xa8\x24\x76\xbd\x13\x20\xc6\x15\x17\x63\x0d\x7d\x23\xfe\x34\xc1\xc5\x8d\x5f\xf4\xe5\x53\x12\xdf\xd3\x33\xf2\xc8\x0e\x6e\x54\xf2\x37\x0e\x6f\x9d\x8a\x7c\x05\x8c\xd2\xa5\x3f\x5d\xbb\x88\xea\x8f\x8d\x88\xf9\xd4\x4f\x64\x72\x96\xa4\x47\x62\x94\xef\xf4\xf0\x2c\x71\x4d\x3f\x19\x7f\x0c\x90\x86\x66\xa8\x20\x07\xc3\x9f\x91\xd2\xe9\x5d\x5f\x2b\x52\x06\xed\x63\x78\x6b\x3a\xcb\xe0\x5f\xdc\x1e\xcc\x95\xf4\x88\x2d\x9a\xb0\x7c\xbf\xea\xf6\xa2\xb0\xc0\xb8\x93\xc5\xd0\x9e\xc4\xb3\x23\x3d\x93\x55\x25\xf9\xb6\x0b\xb8\x40\xe8\x3d\x37\x3a\x43\xe7\xf5\xdc\x52\x93\x5d\x83\x8c\x7b\x77\xe4\x69\x3d\xe0\x74\xfc\xc3\x55\xdf\xfe\xf4\x5e\xfc\xd8\x4f\xd2\xc5\x56\x53\x78\x62\x37\xb0\x2a\xae\xb5\xca\x9e\x4b\x94\x73\x54\x51\x7d\x4f\x0f\x1d\xb4\x9b\xe9\xb9\x68\x64\x7c\x6c\x1e\x9f\x5f\xa5\x48\x85\xeb\xa5\x5d\xaf\x67\x20\xe7\x89\x5e\x2b\xde\xf2\x1d\x83\xd8\x99\xc0\xc4\x07\x82\x88\x36\x62\x99\xa6\x83\x37\x28\xf1\xe6\xbd\xdc\x4a\xba\x6d\x79\x00\xc4\x4f\x54\xf1\x51\x4b\xef\x10\x21\x73\xfd\xc5\x0d\x0e\x90\x98\x70\xd7\x04\x90\x65\xa6\x23\x74\x70\x47\x81\x0c\x6d\x06\xda\x2a\xef\x80\x8d\xca\xe6\x25\xfe\xd9\x35\x30\xaf\x84\x96\xf3\xa9\x84\x29\xd6\x25\x64\x80\x0f\xba\x2b\x7c\x20\xcd\x30\x3b\xa3\x39\xbd\xde\x12\x4d\x5c\x9b\x6b\x4c\x53\x09\x5d\x88\xee\x60\xd5\x41\x85\xbd\x35\x64\x53\x52\x6e\x7e\x9a\x3c\x2b\x88\xd1\x05\x92\x8c\xb6\x64\xdb\x3f\x32\xaa\x5c\x1f\x97\xb4\xce\xa6\xaf\x6f\x54\xeb\xc2\xa0\x25\x96\x27\xf2\x93\xf0\x65\x07\x15\xe7\xc7\xd3\xfe\x8d\x84\x0f\x4a\x07\xd8\xf3\x83\x21\xf4\x86\xc8\xd8\x07\x60\x18\x71\xc6\x5e\xb8\xa9\xe4\x7e\x5b\xc0\x82\xf0\x72\xe6\x52\xd8\x48\x2e\xd0\x47\x79\x3d\xf5\xfd\xe5\x94\x2d\xcf\x05\x82\x4b\xf6\x48\x89\xcf\x61\x77\x59\x37\x3b\x6f\xd9\x51\x1e\x70\x95\xa1\xdc\x7e\xdc\x93\x2c\xf9\x46\xeb\x3a\x65\x4e\x82\x6d\xb0\x30\x79\xe8\x4a\xff\x56\x5c\x60\x29\x6e\xbc\x8b\xd8\xc3\xf4\x54\x0d\xbd\x3c\x94\x21\xae\xaf\x54\xbb\xb2\x23\x73\xa6\x71\x35\x13\xbb\x29\x34\xbd\xa2\x9e\x46\x15\xc0\xb1\xcf\x62\x84\xac\xb5\x62\x69\xd4\xdb\x7a\x58\x4c\xbf\xb3\x51\xed\x6b\x75\x30\x40\x3d\x5d\xe9\xa8\x59\x38\xee\x13\xd8\x89\x04\xdd\x96\xb7\x9c\x5d\x20\x74\xb5\x26\xa6\x6c\x45\x3e\x77\xc8\xc4\xb3\x35\xe8\xe2\x3c\xe5\x9b\xaa\x94\xe7\xeb\x43\x8f\xf2\x7f\xf0\x0d\xfa\x79\xc5\xce\x1d\xeb\x75\x94\x10\x26\x14\x2d\xaf\x2d\x77\xfc\x34\x8e\x1e\x1a\xfc\xa9\x3d\x3a\xa8\x93\xa4\xb3\x30\xbe\x55\x7a\x6f\x91\xe7\x6e\x69\x1c\x76\x9c\x9f\x93\x2a\xfd\xeb\xf2\x9e\x1a\xb8\x0e\xee\xad\x6c\x55\x6a\x94\x7c\x00\xca\x69\x49\xa2\x9d\xf4\xce\x13\x36\x26\x0f\x0b\x97\x22\xb0\x9f\x11\x5b\x82\x99\x8b\x6c\xff\x76\x88\x83\xfe\x28\x30\xc9\xc8\x12\x59\x65\xa1\x0a\x8c\xd7\x44\x36\x66\xd1\x53\xba\x8b\x55\xbf\x71\x68\x71\x31\xfa\x80\x0c\x7a\x2f\x12\xba\x55\xdf\xf5\xf3\xad\xd3\x31\x26\x60\x7f\x2b\x61\xca\x1b\x52\x77\xe9\xec\x21\x84\xd7\x44\x72\x64\x18\x75\x37\xb2\xdd\x86\xc3\x90\xbc\x51\x4e\x8e\xf3\xe3\x92\x6b\x70\xc3\x50\xb2\x04\x5b\xb5\x1e\x80\xa6\xf6\x75\x3b\xb0\xc5\xba\x16\x25\x72\x50\x96\x02\x26\xdf\x09\x55\x85\x0f\xd3\xf1\x95\xe9\x3e\xdb\xe4\x96\x82\xa2\x17\x22\xa0\xf3\x07\xd6\xf7\x3c\x7a\x4b\x11\x64\xf2\xa5\xad\xb5\x8e\xde\x09\xd7\x9b\xed\xa3\x4a\xb0\x9f\xf9\x6c\x32\xae\x6a\x58\x31\x7f\x1b\x1f\x79\xfc\x6b\x61\xf4\xc2\x49\xd9\x20\xac\x8f\x88\xf2\xe5\x86\x0a\x4e\x31\xf7\xab\x13\xba\x9a\x0d\x0f\xd3\x03\x01\x76\xd0\x84\x1f\x2f\x34\x5b\xbf\x35\x74\xda\xc4\x5a\x7a\x2c\x93\xec\x65\xcc\x6f\xc1\xb5\xa4\x59\x5f\xd1\x2a\x07\x25\x94\xaa\xbb\xcf\xf3\xf4\x8a\x61\x66\x43\xd1\x53\x7c\x9c\x5e\xcc\x41\x7b\x22\x29\x64\xe4\x2a\xca\x73\x23\xc2\xc7\xb0\x62\x74\xd3\xd7\x1c\x8f\xb3\x83\xa7\x80\xd9\xca\xde\x2b\x79\xf8\xe2\x8f\xd1\xe2\x2b\xad\x86\xdf\x3a\xdf\x06\x29\x77\x25\x3f\x06\x48\x82\x20\xc8\xd4\x70\x49\x0a\x1a\xd6\x3e\xe7\x03\xea\x8f\x4a\xf5\xb5\x83\x3e\xd2\xcb\x0f\xc0\x75\x47\xf2\x31\x3d\x1d\xf2\x6d\xce\x26\x17\x46\xcb\x8f\xaf\x7c\x92\xe4\x92\xe4\xd2\x9f\xb5\xe3\xa0\x43\x0c\x8f\x6d\x5d\x06\x4d\xa8\x1a\x3e\xfb\xe4\xbf\x92\x11\x2a\xf4\x58\x5a\xd6\xa4\x81\x81\xa0\x61\xdd\x03\xd3\x37\x4a\x1d\x69\x4a\x34\xc5\x50\xb8\x3b\x06\xbc\x9c\x7d\x48\x26\x06\xf0\x7d\x8c\x2d\x45\xc0\x03\x85\x05\xdf\xf3\x34\x66\xb7\x78\x44\xe0\xf6\x3a\xc5\xb2\x75\xe1\xae\xa9\x89\xd3\x6a\x57\xe8\x1c\x34\xa4\x47\x73\xf0\xd4\x0d\x73\x8a\x0e\x99\x7d\x0a\x86\x50\x94\x16\xe2\x13\xbd\xfc\x4f\x38\x11\xc2\x3f\x39\x49\x55\x5f\xab\x3b\x72\x8d\x76\x70\xdc\x2a\x34\x4c\x72\x67\x28\x7c\x7f\x02\x7f\xdf\xac\x9e\x41\xd2\x1c\x4d\xbf\x4b\x77\xc7\x0e\x1a\xe9\x60\x59\x7b\x00\x7a\xf4\x91\x74\x9f\x3e\x35\x74\x2c\x10\xc3\x47\x41\xd2\xcd\x8c\xa7\xd7\xda\x93\xf4\x44\x88\xed\x86\x90\xfc\xa5\x25\x05\xd2\xe2\x59\xaa\xae\x03\x5b\x98\x34\x21\x8a\xb5\xb2\x92\x41\x6f\xd6\xd8\xc4\x4d\x6c\x24\x82\x02\x53\xce\xfb\x05\xa3\x26\xe0\x9a\x8b\x39\xf0\xcf\x0d\xcb\x5f\x0e\x78\xc7\x13\xa8\x49\x9b\x5c\x9e\x7f\x41\x1f\xfd\xc9\xca\xe7\x04\x63\x82\x41\x3a\x08\x5b\xb1\x6d\x4d\x7e\x80\x34\x74\xf2\xd6\xd3\x65\x43\x22\xa5\xb6\x79\xc6\x3c\x54\x50\x50\x68\x6a\xc8\xf3\x85\xd7\xfa\x25\x88\xfe\x4b\x07\x3f\xf2\x07\x74\x63\x63\xc6\x15\x95\xf1\x9b\x7d\x7d\x94\x39\x48\x84\x1e\x5e\x3a\x20\x75\xbd\xd0\xae\x5a\xf4\xcb\xe0\x87\xd0\xfc\x94\xa2\x8e\x71\x0a\xc4\x99\x4b\x9a\x08\xd7\xda\x3d\x95\xde\xad\xbe\xa5\x4b\xf9\x8f\x5b\xb8\x9d\xb6\xf4\x66\x80\x40\x1b\x78\x63\x76\x4a\xe8\x33\xc8\x6f\xf7\x2a\x76\x67\x42\x8a\xff\xc8\x30\x46\x58\x83\xb1\x27\x1a\xd7\xed\x9f\x86\x44\xff\xc3\x6b\x1a\x38\x35\xd8\x69\x5d\xaf\xc4\xfb\x90\xc6\x36\xcb\x4d\x6a\xfd\x3e\x40\x89\x39\xee\x2d\x81\xab\xab\x1a\x18\xcd\x1c\x31\x28\x5b\xd7\xa6\x5c\x63\x59\x2b\xe7\x7c\x90\xff\x32\x30\x5b\xdc\x97\xeb\xa5\x3e\x32\x25\x79\xa3\x2e\x82\xd5\x79\x3b\xc3\x9e\xe2\xfb\xb1\x8d\x03\x15\x2a\x7d\x41\x76\xda\x42\xc0\x80\xd2\xd2\x4c\xda\x88\xb8\x51\x38\x78\x23\x0e\x47\x01\x9a\x70\xd0\x52\x2a\xf2\x48\x31\xb7\xd0\x99\x97\x84\xd7\x00\xed\x30\xdb\x0a\xdd\xb3\x83\x73\x0f\x39\x64\x4a\xb2\xfc\xa8\x5e\x57\xa7\x78\x4e\xa2\xc5\xd9\xcb\x4f\x58\x38\xb5\xaf\xfd\xd9\xc6\xd7\xb7\x7e\xe3\xd4\x0d\x30\xfe\x65\xe3\x9c\xd3\x43\x3d\xf1\x81\xb4\x22\xdd\xfd\x6a\x96\x8b\x9a\x3a\xc7\x98\x2e\xf2\x5d\x46\x63\x53\x86\x64\xcf\x17\x50\xa6\x36\xfb\x23\x1f\x26\x6a\x57\x20\x8e\xbd\x74\xa5\xc9\xeb\x68\x4f\xe2\x63\x80\x14\xa1\x6a\x94\xf4\xe3\xc8\xf7\x14\x17\x41\x35\xf8\xda\x8e\x60\x2a\xfa\x4c\x97\x73\x5a\x4d\x5d\x3f\xee\x7d\x65\x73\xf2\x59\x47\x83\x51\xfc\x68\xf9\xad\x77\x81\x71\x2e\x06\x21\x97\x3d\x2a\xcf\x07\x55\xac\x63\x6e\x22\xfc\xd4\xcd\x9b\xc4\xba\x41\xb4\x68\xb1\x4e\x9a\x92\x62\x79\x7b\x8f\x1b\x9d\xae\x5a\x32\x1b\xb9\x2b\xc6\x86\xf6\xeb\xa9\x86\x0f\xd0\xa8\x6e\x31\x01\xaf\x9d\x04\xb8\x14\xb3\x1e\xde\x85\x7e\xbc\xce\xd9\xcb\xee\xaa\x70\x3e\x27\x23\xa9\x0a\xa8\x18\x31\xcf\x7d\x98\xf3\x64\x1b\x83\x58\xb4\xe0\x73\x55\x23\x2c\xa8\xf0\x02\x8a\xad\x8f\xf7\xdb\x4f\xc5\xa7\xc9\x2c\x89\x14\xec\xba\xb2\xc0\xbd\xef\x1e\x28\x1e\xb5\x99\xf8\x00\x98\xeb\xff\x56\x19\x65\x26\xde\x82\x5b\x51\xde\xbb\xb5\x23\x8a\x02\x10\x95\x99\x26\xc3\x4b\x94\x92\xd7\xd4\xd2\x9c\xf2\xa9\xf4\x54\x69\xce\xa0\x10\x56\x47\x01\x97\x23\x1d\x3f\x30\xd2\x3d\xd9\xa4\xe0\x97\xfe\xb0\x73\x14\x67\xdf\xb7\x2e\x8e\xfb\xa0\x00\xa9\xcf\xea\x0b\x22\x76\x70\x1e\x7a\x6d\xab\xfb\xc5\xc8\xd1\x59\x69\xed\xab\x3b\xdb\x17\x32\xc4\xd6\x3f\x18\x56\x56\xbb\xd6\x14\xc8\xd0\xca\xd4\x0c\xc7\x1a\x2e\x60\x5c\x0d\x73\x72\xdc\x4a\xbf\x39\x93\x57\x5b\x4d\xad\x49\x12\xf5\xbf\xce\x81\x9d\x7b\xda\xca\xfb\xfc\x78\xdb\x91\x3e\x71\xc5\xfb\x68\x1d\x23\x3a\xe8\xeb\x31\x15\xed\xa3\xfe\xb2\x10\xf2\x4f\x4f\x54\x29\xa1\xf7\xa7\x3a\x6e\x09\x95\x3c\x23\xe1\x20\xa2\xf8\x8b\x95\xcc\x1b\xed\xf2\x5f\xad\x94\x5f\x4a\x99\x20\xeb\xb1\xe7\x11\x1b\x31\x24\x9f\xea\x9a\x8e\x56\x62\x35\x80\xb7\x6f\x95\x2a\x79\x5c\x74\x6a\x11\x17\x09\xc2\x47\xcb\x41\xa2\x3c\x70\x6e\x55\x97\x3d\x76\x50\x28\xaa\x7f\x33\xbc\xa2\x8e\xf7\xb7\xe2\x92\xdb\x4e\xfe\x48\x90\xb0\xe4\xe7\x95\x61\x19\xa3\x9c\x18\x4f\xcb\xc0\xb3\x1a\xb7\x8a\xb7\x3e\x29\x89\x72\xf4\x1a\xe8\xda\x06\xb1\xbf\x64\xde\xe0\x6b\x6a\xce\xc5\x45\xb4\x59\xba\x54\xac\x52\x60\x74\x1c\x42\x1b\xed\x17\x15\x56\x28\x0f\x20\xf0\x22\xf7\x55\x50\x9d\xdb\xc2\xf1\xef\x55\x59\x96\xd2\x83\xed\x91\xc4\xde\x62\x2f\x84\xb8\xf7\x24\xb8\x69\x4f\xab\xd3\x74\x86\xe7\xe8\x44\x35\x95\xd2\x20\xe9\x48\x2f\x59\x7d\xf6\xdb\xab\x02\x66\xd1\x72\x48\xd0\xdf\xdd\xd1\xe5\xf7\x8d\x94\x90\x91\x76\xe9\x06\x7c\x47\x26\xbb\xaf\xc9\xf8\x44\xbb\x61\x7a\xe7\xf9\xbd\x39\x36\x27\x32\x91\x97\x24\xcb\x87\xe2\x84\xd9\x39\x12\x69\x63\xb1\x60\x48\xf0\x02\xf2\x5e\x03\x6d\x05\xaa\xff\xc9\x4b\x83\xa4\xca\xef\x15\xe8\xac\xd2\xfb\x57\xb2\x5d\xda\xd7\x75\x3f\xcd\x81\xfd\x96\xdb\xe7\xf3\x98\xf3\x3a\x83\x2c\x98\x30\xc6\xd8\xfa\x31\xd4\xe0\xa6\x54\x7b\x72\x99\x62\xd5\x47\x6b\x7d\xc6\x57\x02\xfd\x9d\xcf\xbe\xa0\x8d\x42\x83\x14\xff\x74\x08\x75\x05\x99\xd6\xbf\x20\x26\x57\xda\xf2\xcf\x99\xef\x08\x9c\xe9\xd2\x37\x1b\xda\xe9\x70\x43\x3c\x4f\x28\xb3\xf5\xe3\xf1\xb5\xdb\x80\x26\x7f\x95\xde\x9e\xa0\x49\x58\xbe\x13\xd7\x9e\x6a\x48\xa8\x5d\x2a\x3e\x26\x14\xcb\xc5\xd3\xf8\xa7\xe1\x2c\x93\x68\x35\x80\x8a\x2a\x83\xb9\xc0\x4d\x8b\x55\x9c\x7d\xca\x2c\x14\x7f\x19\xa1\x85\xbc\x75\x8a\xde\x95\xcc\x6e\xba\xe3\xda\xc3\x3d\x8d\x0b\xa7\xc7\xb2\x53\x3f\x96\xb2\x9f\x74\x68\xfd\x1c\x33\xb2\x8b\x52\x30\x87\xbd\x06\x0e\xce\xf4\x6d\xed\x44\x5e\x47\xb2\x93\x68\x92\xfb\xa9\xe5\x12\x8d\x34\xc5\xd1\xa3\x7a\xa8\xd8\x92\x14\x82\x90\x4f\x3e\x33\x9d\x6e\x45\xe3\x50\x36\xba\x82\x1a\xaf\x2e\x2b\xda\x55\x37\xe9\x8b\x4a\xf6\x45\x1e\x0f\x17\xd7\x69\x2b\x51\x2e\x4e\xfc\xa2\x45\xc6\x83\xa5\xb3\xe7\xa2\xd6\x3f\x60\xd8\xb4\xfc\x52\x6e\x37\x56\xe4\xa1\x8b\xfa\xfa\x33\x5a\x46\x6c\x02\x9b\xed\x4a\x0d\xec\x84\xf8\xa3\x12\x6c\x0a\xc3\xd0\x67\x62\x73\x1c\x6f\x8e\xce\x3c\x5d\xbb\xd6\x2e\xf0\x54\xd4\xb6\x56\x53\x68\x7f\x69\x6a\x4e\x10\x53\x2b\x8b\x8b\x29\x47\x09\x10\x26\x5b\x04\x88\xa9\x92\xf8\xc8\x4c\x49\x2a\x10\xa5\xba\x7d\x22\x3e\x5e\xe9\xe0\xfd\xb2\xdb\xe1\x6b\x3b\x56\xdd\x46\xb1\x09\x43\x53\x65\xfd\x13\x56\xe2\x5d\xee\xfe\xc9\xd3\xdc\x23\xbe\x60\x89\xd6\x8f\xfc\x0f\x59\x88\xec\x21\x84\x5e\x2c\xd7\xc7\x04\x0a\x34\x20\x9f\xe6\x08\x27\x77\xd9\xe5\x35\x20\xfa\xdc\xd6\xcf\xaa\xe5\xa6\x6e\xf5\x0b\x6d\x39\x8b\x27\x2e\xc4\xf0\x08\xba\x5f\x3a\x83\x9b\x8e\xd4\x6d\xfd\xc8\xa6\x85\x0f\x2d\x82\xae\x47\x38\x40\xf8\x96\x56\x43\xd7\xd4\x27\x6b\xc4\xb7\xf4\x29\x03\x9e\xbc\x6d\x12\xce\x48\xf1\x00\xd3\x48\x46\xf2\xee\x3f\x30\xff\x12\x32\xb4\xa3\xc0\x40\x2a\xb0\x50\xfd\x69\x65\x49\x4c\x9b\xc3\x86\xfe\x1a\xaf\x36\xaf\x9b\x3d\x91\xc4\xe6\x55\xe0\xd9\x3a\xee\x99\x0a\xd1\xe6\x45\x60\x99\x7c\xd0\xce\xba\xde\x68\xac\x96\x11\x78\x17\x42\x1f\x23\x67\xbe\x7f\x7d\x9f\x56\x66\xff\xd8\xe3\xbb\x6a\x23\xd5\xc9\x32\xad\xd6\x57\x73\xa9\x7f\x93\x76\xc6\xe9\x07\xc8\xd4\xcd\xbc\xa6\x12\x0e\x21\x78\x72\x4f\xe5\xf8\x77\x63\xb0\x74\x67\x89\x2a\x01\x25\x45\x45\x3a\xdb\xe4\x79\xe9\x27\x50\x53\xf9\x58\xf9\x96\xb9\x23\x0f\xc6\x89\xbe\x78\x41\x91\xef\xa0\x76\x4f\xbf\x3c\x24\x5e\x3f\xfd\xf3\x79\x0a\x39\xc4\x32\xe8\x6d\x43\x3c\xe9\x0c\x3f\xe1\x8d\x94\xea\xa5\x5f\x96\x15\xc8\x61\x33\xb5\x8f\xa6\x15\x2f\xbc\x4e\x95\x70\x15\xad\x54\xf1\x67\xea\x47\x7b\xab\x7e\xc1\xae\x0f\xf8\xac\x91\x0f\xc0\x8d\x77\x1f\xa9\xef\xb7\xbb\x7b\x73\x18\x67\xf3\xc5\x79\xa5\x3f\xc8\x87\x3f\xea\x65\xfc\x9a\x8d\xfd\xb3\x73\x2c\xbb\x81\xf7\x49\xb7\x87\xd3\x09\xe8\x8c\x6a\x7c\x98\x80\x00\x25\x29\x39\x6e\x24\x7a\xec\x1c\xcf\x5f\x21\xa1\x41\xbb\xf3\x7f\xb1\x6d\x2c\x64\x23\xfb\x9b\x4d\x12\xf0\xde\xb0\x21\xcf\x41\x36\xdd\x4d\xd6\x93\x66\xd4\x52\xc8\xa9\x59\xc1\x8c\x91\xef\x80\x00\xf0\x4c\xc9\xc1\x1c\x8c\xf4\xf9\xe0\xeb\xe9\xe2\x24\xfe\x6b\x51\x65\xbb\xa8\x2d\x2a\xa0\xef\xd1\xb5\xcb\x74\xbb\xc0\x2a\x6b\x04\x5f\x2e\xbe\x6b\x35\x33\xa2\xe3\x87\xc7\x86\x9d\xd6\xee\xdb\xf9\x00\xb9\x94\x8f\x87\x12\xa2\xa2\x2c\x70\x70\x87\x14\xd7\x3c\x63\x7b\xa4\x06\x7e\x55\x21\xb1\x18\x19\x5a\x3f\x74\x67\x7d\xed\x20\x85\x9a\xcc\xf4\x89\xe5\x9a\x0c\x37\x5f\xf0\xfe\xd9\x1f\x43\xf3\xe4\x42\xf7\x8b\xd2\xf0\xc8\xd2\x6f\x7c\xc0\x00\x50\x25\x32\x20\xc2\x51\x84\x2a\x50\x99\x63\x70\x48\x71\xa1\x8d\x0b\x8c\xc7\x01\x3c\xe8\x3b\xce\x17\x17\x0d\x06\xa5\x6a\xc9\x8d\x65\x19\xb2\x00\xcf\xd4\xc8\x2a\xb6\x85\x67\xbc\x3e\xe5\xa1\xca\xb6\x58\x9c\x08\x0e\x46\x45\x8d\x20\x25\x16\xa7\x73\xf2\x2e\x25\xa7\xd2\x95\x2b\x8a\xe7\x4e\xfe\x7d\x1d\xfc\xdf\xc5\x9b\x92\x53\x17\x12\xb9\x26\x25\xdf\x30\x40\x90\x2c\xe3\x2e\x0e\x76\x77\x59\xdf\x44\x92\x6f\xaa\xdb\x33\x1d\x5f\x5f\xfe\x49\x9a\x89\x83\xc5\xae\x94\xa2\xac\x2d\xea\x82\x66\x97\x7f\x19\x88\x1c\xef\xa8\x1b\x6a\xd0\x62\xa2\x79\xb8\x5f\x48\x7f\x41\x9b\xb9\x95\x98\xdb\xe9\x6c\x6d\xfd\x91\xd6\x17\x9d\x2b\x7d\x5b\x3d\x46\xf4\x16\x80\x47\xfe\x9c\xaa\xdc\x9e\xbe\x75\xf2\x34\xfb\xc1\x18\x64\x2e\x58\xa8\x0b\xaa\x36\xc0\xdf\xad\xf2\x1c\xf4\x0a\xde\xd8\x89\xf0\x28\xee\x15\x1e\x47\x44\xf9\xe4\xb8\x72\x9b\x28\x7e\x78\xe1\x3d\x9b\x72\xb9\x5f\xea\xa3\x98\x33\x9a\xec\x93\xa1\xa3\x61\x8f\x4b\x08\x9f\x90\xf7\x15\xcb\x25\xcc\xf8\x80\x38\x39\x4c\xd7\xec\xcf\x3c\xa8\xa8\x2d\xdb\xba\xa8\x66\x68\x45\xc9\x38\xa7\xe2\x9b\xb4\x5a\xc9\xca\xb0\x53\x31\x32\x14\xbb\x18\xa1\x78\x4d\x34\x76\xe4\x6e\x0f\x93\x90\x0c\xb1\x92\x32\xf9\x81\x17\x19\x71\xcf\xed\xa7\xfa\x32\x22\x76\x17\x4a\x1c\x8c\x66\xd1\x76\x5e\x6e\x2c\x44\x12\x3f\x1f\x2d\x57\x62\xde\x7b\xfc\x6a\xc2\xe9\x30\xbb\x9d\x33\xb4\xa6\xc4\x56\x8f\x3c\x03\x56\x2a\x6b\x13\xd5\x28\xc3\x92\xe1\x12\xeb\x08\xf6\xcb\xe2\xaa\xc8\x18\xd4\x5b\x6d\xf6\xb8\xa0\x23\x9d\x17\x55\x6e\x58\x13\x8d\xdf\xf6\x3c\x8c\xc5\xe2\x4f\xf7\x4b\x5d\xe7\xb1\xd4\x98\x57\x39\x6e\x16\x34\xe6\x50\x8b\xe2\x70\x5c\x11\xdb\x15\xa5\x75\xbd\xcc\x25\xe2\x88\x92\x47\x12\x45\x1c\x07\xeb\xe9\x8f\x7c\x0f\x3e\xa5\x1b\xef\x92\xe9\xf1\x7f\xb6\x7a\xfe\x5b\x1a\x17\xe1\xda\x42\x6b\x35\x03\xda\x69\x10\x39\xf1\x14\x5e\xd9\x6f\xe1\x29\x4e\xa6\x0c\x65\x4f\x64\x65\x0b\x28\x28\x93\x52\xd1\x6d\x6f\x69\x98\x99\x19\x4f\xd7\x88\x79\x7e\xcc\x1a\x8b\x05\x7e\x0f\x21\xaf\xfa\x93\x3b\x5d\xa9\xe7\x9d\xa6\xce\x3e\x69\x9e\x35\x01\x5c\xa7\x5f\xc1\x07\xb3\x45\xda\x90\xa1\x15\x0d\xf3\x53\x8f\x67\x78\x0a\x37\x98\x47\x85\x3e\x33\x74\x76\xed\xdf\x7b\x2f\x7c\x80\xd3\x7d\x78\x8f\x0a\x2c\x25\x22\xb2\x8a\x24\x1d\xe2\xf3\x2c\xb6\x18\xfc\x8a\x36\x24\x7a\x18\x1b\x86\x24\x9f\x85\xca\x6c\x14\xea\xc9\xb3\xb5\x73\x48\x75\xdb\xfd\x62\x27\x9c\x89\x76\xf4\x7a\x00\xae\xaf\xd5\xc0\x91\x56\x0d\xd4\x73\x45\xb7\x22\x31\x85\xcb\xc9\x98\xe1\xa9\xa3\x6c\x54\x7f\x0c\xe5\x3a\x6a\xca\xad\x45\x3c\x28\x64\x2c\xa0\x6c\x8e\x38\x63\xfe\xfe\x99\x4e\xc1\xc3\x3b\x1d\x41\x2a\x02\x18\x4c\x3e\xf5\x8b\x84\x5e\xef\xb7\xa6\x79\x2c\x37\x15\xdf\x85\x42\x87\x72\x89\xc8\x1a\x50\x49\x65\x2f\x0e\x92\x60\xf6\x15\xef\xf4\x3f\x05\x7e\xd9\x3a\x07\xc7\x15\xb9\x36\x7c\x78\xa4\x23\xf7\x48\x99\x85\xf4\xd8\xa0\x61\x80\xd6\xed\xf2\xd0\xf0\x76\x95\x7a\xc6\x9e\x82\x74\xb1\x67\x4d\x83\x3c\x55\xa6\x17\x46\x00\x6b\xf5\x4b\xfe\xe4\x41\x9b\x13\xef\x02\xa1\x1c\xdc\x0c\xf9\x42\x8a\xd9\x64\x66\x10\x9b\x17\x2a\x78\x5e\xf6\x68\xb3\x2a\xec\x49\x56\x2a\xae\xe2\x21\x6c\xff\xb6\x6c\x81\x01\x5b\x92\x43\x4c\xdd\x75\x4e\xbd\xfd\xb9\x04\xd1\xe1\x3b\xb6\xee\x35\x02\x16\x2c\xd6\x48\x33\x75\x97\x93\x11\x97\xab\x49\x8c\x5a\x9f\x37\x88\x9b\xfe\x07\x80\x09\x3b\xf9\x2b\x1c\xdf\x51\x0e\x9a\x13\xeb\xa3\x4c\xb7\x10\xb5\xd9\x56\x93\xe5\xc0\xa4\xc9\x19\xf9\xf9\x78\xd9\x25\xdb\xbf\xc8\x2b\xb6\x08\xa1\xf0\xe6\x2b\xc8\xda\x45\xc8\x80\x21\x19\xd1\x75\x67\x03\x0b\xf3\x23\xdd\x4f\x17\x54\xe0\xde\x6b\x7c\xc4\x36\x52\x31\x7a\x69\x05\x1a\x16\xa2\xe3\xea\x37\x62\xe1\x21\x28\x7b\xee\x98\x72\x95\xfd\x26\x38\x76\xdd\xc5\x28\x67\x63\xed\xf3\xe3\xc7\x36\xb5\x1f\xfc\x0b\xc7\x5b\x9d\xb8\xdf\x0a\xa2\x16\x8a\x16\xad\x9f\xcf\x07\x70\xbf\xcb\x0f\xfc\x89\x3b\xa9\x49\x86\x96\x51\x62\x35\xbf\xe8\x6a\x13\xdf\x57\xca\xdf\x85\x5e\x0f\x06\x91\x7d\xfc\x77\x1e\xf4\xd8\x18\xc6\xd1\x91\xec\xb9\xb8\xea\xfb\xd4\x3e\x33\x38\xd9\xd3\x8f\xbf\xe0\xdb\xb3\x0b\x6a\x99\x86\x3c\xa1\x94\x03\xbc\x35\xbe\xfc\x8f\x48\xa4\x08\x11\xaa\x53\xc3\x94\x68\x17\x98\x38\x43\x73\x72\xa0\xfd\x2a\x46\xf3\x85\xfa\x54\x86\xd4\xe7\xc9\x8f\x96\xac\x63\x57\x14\x1c\x64\x4b\xc4\x31\x58\x33\x40\x53\xe5\x57\x7f\x48\xa6\x06\x1e\x4d\x82\xbe\xd4\x98\x9a\x33\x0b\xb5\x1d\x17\x77\x15\x4d\x48\xbb\xd7\xa6\x84\xe3\xf3\x07\xc3\x54\x11\x95\x19\x76\x0e\x83\x5e\xaf\x71\x66\xde\xe9\x07\xe8\x3b\x29\x41\x19\x1f\xc5\xc6\x7c\x80\xac\xe8\xe8\xad\xf6\x4c\x19\x40\x12\x07\x56\x34\x17\x18\xe7\x25\x50\x82\x2f\x13\x22\xc4\x7d\x3b\x99\xc1\xec\x62\x64\x68\x3b\xf3\x0f\xc0\x63\xe1\x76\xb1\x80\xb9\xb3\x25\xf7\x18\x79\x33\xa8\x39\x95\x51\x70\x02\xac\x52\xb9\xd4\xc7\x65\xa6\x60\xc6\x5e\x93\xa7\x48\xbf\x8b\x2f\xa1\xf3\x85\x94\x8b\xe1\xe7\x35\x02\x57\xa5\x2a\x65\x21\xd0\xb0\xcc\xc9\x90\xa3\xe0\xe1\xa0\x9f\x2d\xb8\x8f\x01\xcf\xb5\x70\xa6\xda\xde\x2e\xef\x25\x67\x57\xb7\x48\x1f\x0d\xad\xaf\x80\x0a\xe0\x26\x8d\x81\xa4\xed\x60\x45\x1c\xb5\xdf\x4e\x61\x78\xd0\x61\xf9\x4b\xdb\x96\x6d\xb6\x9d\x6e\x08\xcf\xce\x40\x5f\xaf\x4d\x2c\xb5\xe3\xc4\x05\xc6\xa2\xf5\x7b\x51\x9d\xff\x81\xd0\x4b\x21\x15\x06\xa8\xe3\x42\x7d\xde\x99\x5e\x00\xc7\xaf\x39\xf8\xa3\xe3\x7b\x45\x07\x0d\x88\xaa\xf5\x06\x93\xe0\x22\xe1\xf0\x66\x5b\xa7\x0d\x54\xa2\x5a\x33\x5a\x31\xcf\xd2\x12\xe8\xfc\xdb\x03\x40\x5e\xe3\x89\xa4\x9e\x98\xc3\x21\x34\xd6\xc0\xa0\x25\x49\xf4\xa4\x3f\x5f\xb1\x96\xc1\x13\x62\x2e\xc2\x6c\xaa\xe7\x11\x2a\x4f\x63\x79\xa6\xfc\x28\xee\xfd\x38\xe0\x79\xbb\x46\x76\x6b\xea\x5a\xa1\xb1\x7f\xe1\x24\xad\xc1\x8f\x11\xef\x2f\x5d\x3f\xf2\xe1\xc0\xeb\xb8\x84\x54\xc9\x63\x53\xf9\x2a\x5d\x73\x44\x1f\x52\x25\x62\x06\x5f\xa0\x94\xae\x3f\x13\x8e\xeb\x5d\x41\x1f\x60\xe0\xe1\x66\x72\xd4\x17\x73\xc3\xb8\x93\x4e\x2e\x67\x08\x75\x0d\xdf\x26\xad\xfc\x8c\xd6\x4d\x29\x01\xa6\xcc\x25\xc2\x41\xc0\xba\x47\x8f\xde\x5a\x1d\x0b\xb3\x28\x1a\x8b\xda\xc5\x36\x7f\xc4\xa6\x75\xdf\x69\x6f\xec\xbd\x27\x9e\xf6\x91\x20\x1c\xc5\x63\xcf\x83\xad\x9a\xd3\xe6\x94\x55\x9e\xc5\xa8\x99\x40\xd0\xb3\x20\xd8\x00\x08\x3d\xe5\xff\x81\xa9\xdc\xff\x0e\xff\xdb\x7d\xf8\x57\x38\x59\x9d\x1a\x58\xac\x1a\xaa\xa0\x32\x1f\xe8\x59\x39\xdb\x7c\xb8\x24\x7d\xeb\x51\xc5\x09\xef\x11\xbf\x08\x13\x50\x2e\x3e\xd0\xae\xc6\x96\x7c\x99\xd5\x0d\xa1\xb5\x64\xeb\xf4\xe3\x9a\xe7\xa8\x08\xfc\x12\x24\x98\x0e\x20\xc6\x1d\xde\x23\x31\xef\x73\x3c\x4c\xbf\x59\x4d\xad\x3c\xf1\x1d\xb4\xc0\xfe\xb5\x6b\x3d\x00\x3d\xba\x9e\x77\x08\x91\x7e\x0a\xcb\x7f\xdd\x20\x5e\x14\xb2\xac\xa5\x1c\x90\xd8\xbc\xcc\x0c\xce\x85\x15\x79\xf7\x4f\xa4\xda\x39\x37\xa5\x93\xf9\xb9\x0c\x55\x79\x7c\x40\x79\xe6\xdb\x22\x06\xe9\xc6\xf3\x83\xc2\x38\x0f\xbb\x19\xe0\xa8\x49\x0c\xed\xb5\x5f\x7e\x02\x93\x23\x15\x65\x92\x02\xa5\xbd\xf2\x6b\xb1\x02\xe2\xda\x59\x46\xd6\xf4\x6c\x88\x5b\x27\x3c\x0a\xed\x40\x9d\xd0\x53\x83\x16\x78\xb4\xaf\xc4\x19\x79\x8d\x13\x62\x57\x13\x71\x94\xc1\x40\x64\xa3\x5d\x18\xd7\x4a\x78\x8e\x77\x08\x53\x2d\x21\x8f\x23\xac\x41\xa2\x4f\xa8\x72\x1a\xf2\x3c\x83\xbf\x01\xed\xf2\xa6\x8c\x5f\x9f\xa2\x70\x81\x58\x5e\x72\xd4\xc0\xe6\x5c\x81\x2f\x9b\x19\x29\xba\xe4\xa1\x99\x05\x9b\x18\xad\xcb\xa0\x69\xba\x21\xde\xc6\x7d\x7e\x0d\x6b\x7f\xdf\x27\x3d\xdf\x71\x21\x7f\x2b\x73\x3f\x45\xc6\x6b\x74\xce\xf7\xf0\x6a\xe2\x25\xfe\x47\x28\xeb\x44\x3e\x1c\x00\x6b\xf9\x27\x73\xee\x60\xe7\xa1\x16\x51\xbf\xc4\x4f\x13\x5d\xc2\xd8\x6f\x63\xdb\xe8\x12\xb5\x89\xf2\x68\x18\x76\x97\xb9\x18\xa9\x1b\x1d\x45\xdc\x91\x65\x1e\x9c\x7d\x84\x4e\xdc\x85\x35\x06\xa6\xf6\x4e\xd7\x37\x97\x83\x12\x5e\x1e\x3d\x77\xe2\x62\x6f\x52\x2b\xb9\x8f\x01\x8d\xe5\xad\xdf\x6a\xce\x64\xde\x16\xa5\x0c\x51\xa1\x42\x51\xe3\x93\xc7\x8f\xc6\xed\x32\x46\xa3\x41\x43\xbb\x71\xa6\xea\x22\xfd\xfa\xb5\xd9\x6f\xe8\xe9\x5a\xbd\x7b\x14\x39\x89\x86\xeb\x9c\x9a\x9e\x8b\xd1\x7a\xa9\x81\xf3\x7f\x59\x3f\xbf\x98\xfa\x56\xf8\xba\xd5\x8b\x98\xf3\xe6\xab\xf1\x9b\x1f\x98\x6a\x02\x4a\xeb\xb8\x27\x81\xf0\x6a\xca\x55\x45\x95\xec\xa0\x84\x57\xc4\x7c\x8f\x48\x75\x9b\x8f\xe2\xaa\x6c\x0a\xc5\x19\xa2\x6e\x6d\xba\xcf\x0f\xcb\xa3\xb8\x44\x0c\x8b\xe7\x9f\xff\x3a\xdf\x5f\x40\x9e\xe7\x12\x96\xf7\x7d\x20\x39\xf3\x16\x18\x2e\x51\x14\xc6\x6b\xa2\xe4\x2a\xea\x1c\x6f\x94\xbe\x13\x8f\xdc\x9d\xe9\x49\x5f\x8b\xb6\xd7\xda\xed\x13\x11\x08\xc7\x59\x6e\x28\x7d\x9e\x8f\x2e\x0a\xc2\x08\x46\x2d\xa8\x14\xdc\x8a\x4d\x9f\x55\x7c\xfa\x2c\xe1\x88\x63\x66\x14\xbc\x27\xa3\xf7\xbb\xf2\xb7\x69\x28\xe3\x37\x6c\xc0\xd8\x5b\x0d\xcb\x22\x62\xe3\x46\x4a\x80\x91\xb1\x31\x06\xa0\x1c\xa9\x22\xb0\x0f\x1f\x04\x91\xb1\x98\xc8\x8b\xf5\x2b\x41\x08\x16\x09\x24\xfe\x27\x29\x59\xaa\xa2\xfc\x00\x6a\x62\x50\x3c\xc7\x3f\x54\xb2\xd0\xff\xe9\x45\xd2\xfd\x47\xf5\x14\x67\xec\xf7\x98\xa7\xc9\x2e\xd4\x55\x9b\x53\xb5\x70\xaa\x03\x29\xce\xf3\xe7\x72\xcb\x9f\xd5\xc0\x49\x3e\x02\x73\x3e\x19\xba\x67\xfb\x24\x89\x3a\x16\x9f\x7c\x32\x5e\xe2\x9f\xef\x47\x9e\x45\x08\x33\xd3\x4a\xa4\x0b\x10\x35\x57\xd3\x22\x59\xd3\xa1\x34\x03\x7f\xca\xbe\xb2\x25\x8e\x1c\xee\xd0\xbf\x13\x95\x3f\xe6\xc3\xe2\x3c\x7a\x00\x62\x2c\x90\xf8\xca\x45\x28\xf7\xc5\xed\xed\x2c\x77\xc9\x2d\xda\x57\xfc\xfb\x87\x10\xda\xad\xd8\xfb\x67\xa8\x56\x9e\x2d\xec\x37\xee\xc7\xa5\xd8\x86\xbd\x78\x03\xb6\x7b\xde\x6e\x4b\xe8\xa0\x59\xdc\x8d\x0e\x06\x14\xc3\x3d\xc9\xa8\x8c\x80\x4b\x46\xda\xdb\x5d\x60\x0b\x64\x88\xa0\xfc\xab\x9c\x3c\xff\x07\x3e\x5b\xfc\x45\x61\x00\xad\x48\xf6\x48\x73\x71\x0a\x67\x02\x5c\xaf\x97\x1f\xc0\xde\x91\x83\x47\xfb\x05\xdc\xc4\xa2\xc1\x5b\xa8\x2f\xbe\x91\xf7\x32\xbb\x99\xbc\x58\x8e\x72\x1f\x42\xe9\x8f\x88\xb5\xde\xe4\x89\xb2\xc4\x56\x77\xee\x92\xe7\x53\x7d\x00\xaa\x8a\x0d\x49\xa7\x70\xf0\x1c\x28\x61\x06\xec\x3b\xf5\xdf\xd9\x07\x85\xd0\x94\x3e\x7d\x94\x03\x18\xe1\xa0\x22\x9d\xc7\x7b\x85\xc6\xae\x65\x90\xa2\x5c\xec\x39\x3e\x4c\xa5\xff\xa3\x6f\x7a\x2a\xb5\x87\xf6\xef\x35\x45\xfe\x57\x28\xf3\x2f\x5e\xb4\x71\xaf\xb6\xf3\xc0\x55\xc6\xbb\xdb\x36\x99\xff\x66\xed\x47\x3b\x23\x14\xc2\x65\x6e\x4b\x0b\xc9\xcc\x2a\x28\xab\xb4\x61\x07\x00\xc2\xa0\xff\xed\x56\xf7\xcd\xf4\x7f\x46\x29\xfc\x0b\x81\xfe\xdf\xb5\x6a\xfb\x4f\xf0\x47\x8e\x72\xe7\xef\xf5\x01\x07\x1a\x9d\xe0\x38\xcf\x5f\xc2\xb4\xff\x6b\x91\x39\xf5\x97\x6b\x39\xfd\x7f\x16\x4c\x9b\x91\xec\xff\x47\x8f\xfc\xff\x0d\x70\xe0\x6c\xe1\xb2\xff\xff\x19\x03\xff\xdb\x92\xfd\xe1\xd7\xff\x2f\x00\x00\xff\xff\xfc\x4b\x38\xf0\x1e\x96\x00\x00") + +func testLargeJpg() ([]byte, error) { + return bindataRead( + _testLargeJpg, + "testdata/test-large.jpg", + ) +} + +var _testMediumHTML = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x59\x5b\x73\xeb\xb6\xf1\x7f\xf7\xa7\x40\xf0\x9f\x7f\x9e\x0e\x05\x51\x92\x65\x2b\xa1\x78\x9a\x4b\xc7\x69\x9b\x4c\xcf\x24\x99\xe9\xf4\xa9\x83\xcb\x92\x84\x05\x02\x34\x00\xca\x56\xa6\x1f\xbe\x03\x90\xba\x50\xa6\xa4\xd3\x4e\xf2\x70\x2c\x02\xbb\xfb\xdb\xc5\x62\x77\xb1\xc0\xc9\xbe\xf8\xfe\xef\xdf\xfd\xfa\xcf\x4f\x7f\x46\x95\xaf\x55\x9e\x85\xbf\x48\x51\x5d\xae\x31\x68\x9c\xdf\x65\x15\x50\x81\x1a\x6b\x0a\xa9\x60\x8d\x2b\xef\x9b\xaf\x08\xa1\xab\x09\x37\x35\x49\x88\x6b\x80\x13\xd3\x80\x76\x40\x2d\xaf\x48\x3a\x49\x09\xce\xef\x10\xca\x6a\xf0\x14\xf1\x8a\x5a\x07\x7e\x8d\x5b\x5f\x24\x8f\x27\x04\x4d\x6b\x58\xe3\xad\x84\xd7\xc6\x58\x8f\x11\x37\xda\x83\xf6\x6b\xfc\x2a\x85\xaf\xd6\x02\xb6\x92\x43\x12\x07\x1f\x90\xd4\xd2\x4b\xaa\x12\xc7\xa9\x82\x75\x3a\x99\x76\x40\x4a\xea\x0d\xaa\x2c\x14\x6b\x4c\x12\xc2\x8c\xf1\xce\x5b\xda\x4c\x6a\xa9\x27\xdc\xb9\x8f\xdb\xf5\x23\x03\x9e\x32\x46\xe7\x30\x9b\x03\x67\x74\x36\xe3\x45\xc1\xd2\xd5\x03\x9d\x89\xc5\x62\x4a\x8b\x45\x3a\x65\xe9\xbd\xc0\xc8\x82\x5a\x63\xe7\x77\x0a\x5c\x05\xe0\xc7\x14\x38\xe9\xa1\xc7\x7d\x10\x8f\x69\x90\x5d\xf0\xc7\x95\x60\x30\x7f\x58\xce\x17\xf7\xc5\x92\x15\x30\x87\xe5\x8c\x2d\x60\x31\x15\x73\x31\x5d\x5e\xc0\xf5\xd2\x2b\xc8\x9f\xcc\xf7\x86\x67\xa4\x1b\xdc\x65\x24\x38\x3a\xbf\xcb\x98\x11\xbb\xfc\x2e\xd3\x74\x8b\xb8\xa2\xce\xad\xb1\xa6\x5b\x46\x2d\xea\x7e\x12\x01\x05\x6d\x95\xc7\xc8\x9a\xb0\x21\x9a\x6e\x65\x49\xbd\x34\xba\xc3\x16\xf2\x20\x17\x7c\x4a\xa5\x06\xfb\x8e\xd2\x43\x05\x8d\x3d\x15\xa1\x8c\xb5\xde\x1b\x8d\xfc\xae\x81\x35\xee\x06\xf8\x4c\xc0\x9b\xb2\x54\x80\x91\xa0\x9e\xf6\x83\xa0\x46\x29\xda\xb8\xc3\x34\xb5\x65\xd8\xf1\x49\x2f\x73\x20\x77\x6a\x10\xca\x5c\x43\xf5\x1e\xd8\xd9\xc4\x68\xb5\xc3\xf9\xaf\x11\x0d\x1d\x97\x93\x91\xc0\x37\x2a\x24\xb9\xd1\x09\xa3\x16\xe7\x7f\x0c\x53\x46\xba\xe5\xf7\x23\x7a\xe6\x05\x66\xa9\x16\x78\x1f\x18\x38\xcf\x9c\xb7\x46\x97\xfb\x0d\xed\x47\x19\xa1\xd1\xed\x44\xc8\xed\xfb\x9d\xe9\x7c\x82\xc6\x7d\x94\xb5\xea\x44\xe5\x9e\x49\xd3\xed\xc1\x87\x31\x38\xf7\x3c\x94\x7b\xb9\x05\x9c\x67\xf4\x68\xd3\x0f\xa6\x86\x60\x41\x46\x94\x1c\x08\x9d\x70\x25\x84\x32\xd3\x7a\x9c\x7f\x13\x7e\x86\xdc\x19\x69\x55\xff\x55\x18\x5b\x9f\x79\xe0\xc4\xaa\x48\xed\xbf\xad\x2c\x2b\x8f\x91\x14\x6b\xfc\x96\x74\x05\x01\xa3\x60\x9d\xd1\xc1\xa8\x3e\x62\x7b\x42\x9e\x49\xdd\xb4\x7e\x8f\x1c\x70\x92\x10\xb1\xd6\xa8\x21\x44\xf2\xd2\x82\xdd\xe1\x3e\x30\x3d\xbc\x79\xdc\x97\x8f\x17\x8c\x1a\x45\x39\x54\x46\x09\xb0\x6b\xfc\xcb\x1e\x99\x04\xb4\x13\xef\x1f\x7e\x34\x0d\x3f\x17\x73\x64\x40\x7a\x6e\x6b\x66\xc2\x5e\xee\x77\xa5\x9a\xe5\x9d\x06\x54\x18\x8b\x9e\x0c\xfa\x44\xf9\x86\x96\xe0\x32\x52\xcd\x3a\x9e\xbb\xde\x5f\xbd\xc4\x09\x5a\x5c\x6c\x52\x5a\xd3\x36\xc7\x4c\xb8\xe2\x81\xc3\x0a\x69\xeb\x4d\x61\x78\x1b\x36\x7a\xff\x89\xd1\x96\xaa\x16\xd6\x78\xd4\x01\xd1\xbc\xa6\xb3\x0d\xb1\x1d\x92\x75\xa8\xb1\xa8\xa1\xbe\x42\xc6\xa2\x0d\xec\x5e\x8d\x15\x93\x81\x47\xc7\xb3\xe3\x68\x73\xc2\xbc\x3e\x8d\xbe\xbe\x58\xf4\x8c\xcc\x6b\xc4\xbc\x3e\xd6\xa6\x0e\xd9\xb5\xac\x96\x1e\xe7\x4f\xe6\x8b\x61\x4a\x85\x8d\x39\x4d\xb7\x7d\x8a\xf4\xfb\xb6\xdf\xaf\xbb\xac\xe9\x92\x0a\x55\xc6\x79\x87\x84\xe1\x6d\x0d\xda\xc7\xfa\x10\x57\x79\x08\xe6\xfe\x5c\x2a\x4d\x38\xba\x26\xc6\x96\x24\xa8\x0d\x31\xbd\xf7\x84\xbb\x33\x1a\x7d\x2b\x3d\x6b\xf9\x06\xfc\x07\xf4\x24\xfd\x0f\x2d\xfb\x80\x9e\x8c\x09\x85\xe7\x93\x35\xcf\xc0\x3d\xfa\xc1\x38\x2f\x75\x89\xa8\x16\xe8\x47\xda\x6a\x5e\x35\x54\x4c\x10\xfa\x39\x1c\x83\xbe\x02\x94\xd1\x3b\x34\x9e\x41\xe8\x13\x2d\x63\xd2\x45\xd3\xa4\x0e\x8b\xe9\x4c\x8d\x5c\x88\x0a\x11\x90\xf7\xf6\x20\x6f\x50\x5c\xdd\x5d\xd0\x55\x1b\x0b\x93\xbb\x41\x00\x5a\xf3\x3a\x52\xd3\x55\xe2\xea\x64\x89\x0f\xf1\xd6\x85\xe6\x22\xff\x64\x9a\x56\x51\x7b\x1a\x94\x8b\x83\xb7\x8f\x05\x45\x49\xe7\x93\x56\xc7\x23\x49\xe0\x4b\xa5\xa1\x94\xbe\x6a\x59\x3c\xe3\xe9\xab\x0b\xff\x12\x27\x36\x49\x69\xc2\x27\xce\xaf\x92\x63\x21\xb9\x84\x26\x4a\x2b\x9f\xa9\xda\x52\xf2\xfc\xea\x93\xd2\x0c\xb0\xce\x89\x57\x91\x4a\xa9\x93\xd2\x68\xc9\xc3\xd7\x00\x66\x40\xb9\x8e\x61\x12\x0b\x42\x3a\x12\xff\x0e\x41\x06\xa4\x5b\x28\xee\x45\x25\xc2\xca\x2d\x58\x52\xef\xdc\x8b\x3a\x87\x3a\xa7\xdf\xc0\x0b\x41\x4c\x1a\x6b\xbc\x61\x6d\xd1\x7d\x9c\x21\x8e\x70\xdc\xc0\xac\x8d\x68\x15\xc4\xe5\x94\x66\x74\xc1\x23\x1c\x37\x30\xad\x54\x8a\x92\x57\x60\xce\x84\xa4\x3a\xc3\x3b\xa3\x5e\xc5\xaa\x76\x0d\x58\x05\xa2\x04\x4b\x0a\xca\xac\xe4\x84\x1b\x0b\x84\x57\x54\x6a\x6e\x04\x10\x57\xc9\x7a\xa0\xe0\xf3\x44\xae\x6a\x7d\x96\xfa\xb7\xaa\x0d\xa6\x0e\xa1\x4f\xe6\xaf\xca\x2b\xc9\x48\xf3\x32\x10\xed\xa6\xae\x4a\x35\x9b\x92\x80\xb5\xc6\x0e\x37\xe0\x38\x7d\x5d\xda\x9a\x1a\x7c\x05\xad\x23\x5c\x49\xd0\xfe\x5f\xc7\x68\xe8\x09\x43\xd8\xdb\xfc\x57\xf5\x59\xc3\x0a\x59\x12\x1e\x0f\xc2\xf1\xf9\xab\xf2\x4e\xda\xb6\x71\xa0\x89\x32\xa5\x3d\xb3\xed\x8c\x76\x1d\xc7\x5b\xf0\xbc\xb2\xc4\x83\xf3\xb2\xd8\x11\xea\x1c\xd8\x61\xcc\x5d\xe0\xb9\x8a\xdb\x6a\xf9\xd6\x48\xbe\x51\x40\x36\xb4\x32\xc6\x27\x15\xe5\x9b\x01\xec\x38\xcb\x08\xaa\x99\xb4\x0c\x6c\x3c\x7e\x7e\xa3\x0d\xce\xcf\x26\xc6\x24\x0e\xe7\xd5\x1b\xe1\x76\xd7\x78\x43\x9c\xab\x82\xe4\x28\xe1\x06\x82\x06\x4f\xe2\x4d\x2a\x9c\xe8\x97\x28\x37\x30\x0c\x6d\x7d\x35\x3b\x13\xef\x26\xc7\x24\xc3\xe1\x39\x39\xe1\x2d\x6d\xc3\x83\xf0\xd8\xfc\x98\x7c\xb3\x29\x27\x52\x93\xba\x34\x93\x6d\xd4\x3a\x98\xb8\x22\xb1\xa3\xb5\x1a\x8a\xf4\x33\xef\x65\x14\x65\xf2\x2d\x5a\xb1\x9d\x05\x60\x9c\x9f\xcf\xf4\xcd\xfa\xb0\xf3\xbd\xd2\xbd\x9f\x9e\xc1\xe1\xf0\xfd\xc9\x58\x18\x39\x79\x6f\x9e\xbb\xe7\x0d\x79\xb0\xed\xc9\xa0\x5f\x3c\xd5\x82\x5a\x71\x02\x49\x2f\x89\xb8\x96\x59\x68\x7a\xb9\x96\x25\x61\xe0\xa4\x37\x76\x77\x53\x3a\x34\x4d\x6e\xd8\x35\xbd\xca\x8d\x24\x7d\x2f\xe4\x70\xbe\xff\x42\x7f\x42\xa5\x49\x02\xf1\x26\xd6\x49\x36\xc6\x6e\xf4\xa3\x59\x0b\x70\xfc\x4b\x5a\x37\x5f\xbf\xac\x83\xa2\x96\x96\xf0\xff\xf3\x6f\x4a\x13\xe7\xdc\xda\x79\x6a\x5d\xfc\x8e\x6d\xe3\xcf\xfb\x05\x48\x70\x38\xff\xc9\x38\x8f\x22\x47\xd0\xfc\x01\x1d\x1b\x96\xdf\x41\x73\x61\xec\xe6\xa2\xe6\x3a\x68\x8e\x1c\x7f\x80\xe6\xb6\x11\xd4\x83\xb8\xa4\xdb\x02\x07\xed\xd5\x0e\xf5\x7c\xb1\xab\x34\xba\x6f\x5a\x07\x37\xb4\xe1\x15\xe7\xd0\x3b\xc7\x80\xed\xae\x51\x85\x31\x1e\xec\xe1\x2e\xcf\x15\x50\x5b\xc8\xb7\x1b\xef\x05\xd7\xd7\xd9\x9f\x21\xa5\x10\x86\x48\xe7\xda\x60\xf4\x3f\x80\x39\xe9\x01\xfd\x25\x8e\x0f\x81\x32\xb8\x52\x84\x02\x94\xd4\xad\x0f\x39\xf0\xef\xfe\x12\x70\xab\x8b\x47\x3f\xf6\x0e\x1c\x87\x6c\x5a\xa5\xfa\xab\xe7\x31\x1c\xff\x0f\xe7\xdf\x52\xbe\x09\x3d\xb6\x37\x5d\xe1\x3d\xdc\x38\xce\x3c\x76\xe2\x29\x57\x19\xeb\x79\xeb\x1d\x46\x9e\x32\xa9\x05\xbc\xad\x71\x92\x1e\x5c\x57\x1b\x41\x15\x7e\x7f\xb9\x8b\xf3\x89\x90\x54\x99\xf2\x98\xdb\xef\x18\xfa\x47\xae\xd3\xae\xfb\x1d\xcf\xe0\x4d\x66\x78\xd9\x1a\x7d\x99\xe1\xca\x1c\x9e\x5e\x84\x74\xb5\x3c\xda\x89\xa8\x95\x34\xa9\xa4\x10\xa0\xd7\xd8\xdb\x16\x70\xfe\xa5\x97\x35\xb8\xaf\xcf\xaf\x63\x7d\x1d\x1b\x9a\x12\x5f\xa6\x70\xfe\x37\xd8\x31\x13\x8a\xd1\xc1\x3b\xa7\x57\x8b\x93\x1a\x79\x69\x49\xcc\x88\xdd\x70\x41\x9e\x32\x05\xc3\x19\x9b\x67\x5e\x20\xaa\x64\xa9\xd7\x78\xbf\x9b\x2c\xff\x98\x11\x96\x67\xc4\x8b\x40\xce\xd1\x57\xe8\xd7\x4a\x3a\x54\x83\x6e\xbb\x49\xe2\xed\x67\xe1\x90\x73\x9c\xfe\xaa\x1c\x02\xf6\x12\xd2\x58\xcc\x8e\x82\x17\xe7\xe0\x7f\x6d\xeb\x26\x84\x9e\x14\xa0\xbd\x2c\x24\xd8\xff\xce\xda\x32\x00\x86\xdb\xa6\x46\xfb\xd1\x29\xfc\x93\xe9\xe3\x1a\x99\x02\x35\x31\x31\xfe\x77\x74\x36\x8e\x0e\x5a\xdc\x42\xff\x6c\xff\x0c\x15\xca\x71\x85\x31\xdb\x7e\x67\x55\x70\x61\x6d\x6f\xb4\x6e\x54\x28\x51\x63\xda\xc8\x59\x74\xde\x8c\xef\xbe\xbe\x7e\x76\xca\x32\xaf\xc7\x13\x36\xff\x2e\x24\xf3\xfb\xa7\x92\x83\xfe\x93\x97\x92\xc1\xbb\x96\xe3\x56\x36\x1e\x39\xcb\x63\x4b\xf0\x1c\x5f\xcc\x92\xd9\x64\x3a\x99\xc7\xd7\xf0\x67\xf7\x71\xbb\x2e\x58\xb1\xe2\x0f\x0f\x62\xca\x17\x30\xe7\xf3\x05\x5d\x3c\xde\xaf\x1e\xa7\x3c\x85\xfb\x79\xba\x64\xcb\x59\x3a\x4b\x97\x53\xfe\x18\xdf\x42\x23\xe0\x7b\xe4\xe1\x23\x7b\x84\xbd\xa7\x82\x3e\xf0\x74\x3a\x2f\x78\x2a\x80\x32\xbe\x9a\xdd\x73\x9e\x16\x82\x31\xb6\x84\xc5\x7d\xca\x67\x69\xc1\x1f\xa6\xd7\x60\xe3\xd3\x7a\x44\x9b\x3f\xa4\x02\x1e\xe6\x29\x4f\x1f\xc5\x2a\xe5\x8b\xd5\x4a\xac\xa6\x2c\xa5\x6c\xca\x8a\xf9\x0a\x78\xb1\x5c\x8a\x25\x2f\x1e\x06\x68\xa4\x7f\x33\x27\xf1\xbf\x30\xfe\x13\x00\x00\xff\xff\xaa\x02\x23\x78\xd2\x18\x00\x00") + +func testMediumHTML() ([]byte, error) { + return bindataRead( + _testMediumHTML, + "testdata/test-medium.html", + ) +} + +var _testSmallTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x0a\xc9\xc8\x2c\x56\xc8\x2c\x56\x48\x54\x28\x49\xad\x28\x51\x48\xcb\xcc\x49\xd5\x03\x04\x00\x00\xff\xff\x11\xe2\x00\xb1\x14\x00\x00\x00") + +func testSmallTxt() ([]byte, error) { + return bindataRead( + _testSmallTxt, + "testdata/test-small.txt", + ) +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + return f() + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() ([]byte, error){ + "test-large.jpg": testLargeJpg, + "test-medium.html": testMediumHTML, + "test-small.txt": testSmallTxt, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// +// data/ +// foo.txt +// img/ +// a.png +// b.png +// +// then AssetDir("data") would return []string{"foo.txt", "img"} +// AssetDir("data/img") would return []string{"a.png", "b.png"} +// AssetDir("foo.txt") and AssetDir("notexist") would return an error +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + cannonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(cannonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for name := range node.Children { + rv = append(rv, name) + } + return rv, nil +} + +type _bintreeT struct { + Func func() ([]byte, error) + Children map[string]*_bintreeT +} + +var _bintree = &_bintreeT{nil, map[string]*_bintreeT{ + "testdata": {nil, map[string]*_bintreeT{ + "test-large.jpg": {testLargeJpg, map[string]*_bintreeT{}}, + "test-medium.html": {testMediumHTML, map[string]*_bintreeT{}}, + "test-small.txt": {testSmallTxt, map[string]*_bintreeT{}}, + }}, +}} diff --git a/go-cloud/blob/drivertest/drivertest.go b/go-cloud/blob/drivertest/drivertest.go new file mode 100644 index 000000000..50a313d8a --- /dev/null +++ b/go-cloud/blob/drivertest/drivertest.go @@ -0,0 +1,2865 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 drivertest provides a conformance test for implementations of +// driver. +package drivertest // import "gocloud.dev/blob/drivertest" + +import ( + "bytes" + "context" + "crypto/md5" + "errors" + "fmt" + "io" + "log" + "net/http" + "net/url" + "reflect" + "regexp" + "strconv" + "strings" + "sync" + "sync/atomic" + "testing" + "testing/iotest" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/escape" +) + +// Harness descibes the functionality test harnesses must provide to run +// conformance tests. +type Harness interface { + // MakeDriver creates a driver.Bucket to test. + // Multiple calls to MakeDriver during a test run must refer to the + // same storage bucket; i.e., a blob created using one driver.Bucket must + // be readable by a subsequent driver.Bucket. + MakeDriver(ctx context.Context) (driver.Bucket, error) + // MakeDriverForNonexistentBucket creates a driver.Bucket for a nonexistent + // bucket. If that concept doesn't make sense for a driver, return (nil, nil). + MakeDriverForNonexistentBucket(ctx context.Context) (driver.Bucket, error) + // HTTPClient should return an unauthorized *http.Client, or nil. + // Required if the service supports SignedURL. + HTTPClient() *http.Client + // Close closes resources used by the harness. + Close() +} + +// HarnessMaker describes functions that construct a harness for running tests. +// It is called exactly once per test; Harness.Close() will be called when the test is complete. +type HarnessMaker func(ctx context.Context, t *testing.T) (Harness, error) + +// AsTest represents a test of As functionality. +// The conformance test: +// 1. Calls BucketCheck. +// 2. Creates a blob in a directory, using BeforeWrite as a WriterOption. +// 3. Fetches the blob's attributes and calls AttributeCheck. +// 4. Creates a Reader for the blob using BeforeReader as a ReaderOption, +// +// and calls ReaderCheck with the resulting Reader. +// +// 5. Calls List using BeforeList as a ListOption, with Delimiter set so +// +// that only the directory is returned, and calls ListObjectCheck +// on the single directory list entry returned. +// +// 6. Calls List using BeforeList as a ListOption, and calls ListObjectCheck +// +// on the single blob entry returned. +// +// 7. Tries to read a non-existent blob, and calls ErrorCheck with the error. +// 8. Makes a copy of the blob, using BeforeCopy as a CopyOption. +// 9. Calls SignedURL using BeforeSign as a SignedURLOption for each supported +// +// signing method (i.e. GET, PUT and DELETE). +// +// For example, an AsTest might set a driver-specific field to a custom +// value in BeforeWrite, and then verify the custom value was returned in +// AttributesCheck and/or ReaderCheck. +type AsTest interface { + // Name should return a descriptive name for the test. + Name() string + // BucketCheck will be called to allow verification of Bucket.As. + BucketCheck(b *blob.Bucket) error + // ErrorCheck will be called to allow verification of Bucket.ErrorAs. + ErrorCheck(b *blob.Bucket, err error) error + // BeforeRead will be passed directly to ReaderOptions as part of reading + // a test blob. + BeforeRead(as func(any) bool) error + // BeforeWrite will be passed directly to WriterOptions as part of creating + // a test blob. + BeforeWrite(as func(any) bool) error + // BeforeCopy will be passed directly to CopyOptions as part of copying + // the test blob. + BeforeCopy(as func(any) bool) error + // BeforeList will be passed directly to ListOptions as part of listing the + // test blob. + BeforeList(as func(any) bool) error + // BeforeSign will be passed directly to SignedURLOptions as part of + // generating a signed URL to the test blob. + BeforeSign(as func(any) bool) error + // AttributesCheck will be called after fetching the test blob's attributes. + // It should call attrs.As and verify the results. + AttributesCheck(attrs *blob.Attributes) error + // ReaderCheck will be called after creating a blob.Reader. + // It should call r.As and verify the results. + ReaderCheck(r *blob.Reader) error + // ListObjectCheck will be called after calling List with the test object's + // name as the Prefix. It should call o.As and verify the results. + ListObjectCheck(o *blob.ListObject) error +} + +type verifyAsFailsOnNil struct{} + +func (verifyAsFailsOnNil) Name() string { + return "verify As returns false when passed nil" +} + +func (verifyAsFailsOnNil) BucketCheck(b *blob.Bucket) error { + if b.As(nil) { + return errors.New("want Bucket.As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) ErrorCheck(b *blob.Bucket, err error) (ret error) { + defer func() { + if recover() == nil { + ret = errors.New("want ErrorAs to panic when passed nil") + } + }() + b.ErrorAs(err, nil) + return nil +} + +func (verifyAsFailsOnNil) BeforeRead(as func(any) bool) error { + if as(nil) { + return errors.New("want BeforeReader's As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) BeforeWrite(as func(any) bool) error { + if as(nil) { + return errors.New("want BeforeWrite's As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) BeforeCopy(as func(any) bool) error { + if as(nil) { + return errors.New("want BeforeCopy's As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) BeforeList(as func(any) bool) error { + if as(nil) { + return errors.New("want BeforeList's As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) BeforeSign(as func(any) bool) error { + if as(nil) { + return errors.New("want BeforeSign's As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) AttributesCheck(attrs *blob.Attributes) error { + if attrs.As(nil) { + return errors.New("want Attributes.As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) ReaderCheck(r *blob.Reader) error { + if r.As(nil) { + return errors.New("want Reader.As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) ListObjectCheck(o *blob.ListObject) error { + if o.As(nil) { + return errors.New("want ListObject.As to return false when passed nil") + } + return nil +} + +// RunConformanceTests runs conformance tests for driver implementations of blob. +func RunConformanceTests(t *testing.T, newHarness HarnessMaker, asTests []AsTest) { + t.Helper() + + t.Run("TestNonexistentBucket", func(t *testing.T) { + testNonexistentBucket(t, newHarness) + }) + t.Run("TestList", func(t *testing.T) { + testList(t, newHarness) + }) + t.Run("TestListWeirdKeys", func(t *testing.T) { + testListWeirdKeys(t, newHarness) + }) + t.Run("TestListDelimiters", func(t *testing.T) { + testListDelimiters(t, newHarness) + }) + t.Run("TestDirsWithCharactersBeforeDelimiter", func(t *testing.T) { + testDirsWithCharactersBeforeDelimiter(t, newHarness) + }) + t.Run("TestRead", func(t *testing.T) { + testRead(t, newHarness) + }) + t.Run("TestAttributes", func(t *testing.T) { + testAttributes(t, newHarness) + }) + t.Run("TestWrite", func(t *testing.T) { + testWrite(t, newHarness) + }) + t.Run("TestCanceledWrite", func(t *testing.T) { + testCanceledWrite(t, newHarness) + }) + t.Run("TestConcurrentWriteAndRead", func(t *testing.T) { + testConcurrentWriteAndRead(t, newHarness) + }) + t.Run("TestUploadDownload", func(t *testing.T) { + testUploadDownload(t, newHarness) + }) + t.Run("TestMetadata", func(t *testing.T) { + testMetadata(t, newHarness) + }) + t.Run("TestMD5", func(t *testing.T) { + testMD5(t, newHarness) + }) + t.Run("TestCopy", func(t *testing.T) { + testCopy(t, newHarness) + }) + t.Run("TestDelete", func(t *testing.T) { + testDelete(t, newHarness) + }) + t.Run("TestKeys", func(t *testing.T) { + testKeys(t, newHarness) + }) + t.Run("TestSignedURL", func(t *testing.T) { + testSignedURL(t, newHarness) + }) + t.Run("TestIfNotExist", func(t *testing.T) { + testIfNotExist(t, newHarness) + }) + asTests = append(asTests, verifyAsFailsOnNil{}) + t.Run("TestAs", func(t *testing.T) { + for _, st := range asTests { + if st.Name() == "" { + t.Fatalf("AsTest.Name is required") + } + t.Run(st.Name(), func(t *testing.T) { + testAs(t, newHarness, st) + }) + } + }) +} + +// RunBenchmarks runs benchmarks for driver implementations of blob. +func RunBenchmarks(b *testing.B, bkt *blob.Bucket) { + b.Helper() + + b.Run("BenchmarkRead", func(b *testing.B) { + benchmarkRead(b, bkt) + }) + b.Run("BenchmarkWriteReadDelete", func(b *testing.B) { + benchmarkWriteReadDelete(b, bkt) + }) +} + +// testNonexistentBucket tests the functionality of IsAccessible. +func testNonexistentBucket(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + // Get a driver instance pointing to a nonexistent bucket. + { + drv, err := h.MakeDriverForNonexistentBucket(ctx) + if err != nil { + t.Fatal(err) + } + if drv == nil { + // No such thing as a "nonexistent bucket" for this driver. + t.Skip() + } + b := blob.NewBucket(drv) + defer b.Close() + exists, err := b.IsAccessible(ctx) + if err != nil { + t.Fatal(err) + } + if exists { + t.Error("got IsAccessible true for nonexistent bucket, want false") + } + } + + // Verify that IsAccessible returns true for a real bucket. + { + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + exists, err := b.IsAccessible(ctx) + if err != nil { + t.Fatal(err) + } + if !exists { + t.Error("got IsAccessible false for real bucket, want true") + } + } +} + +// testList tests the functionality of List. +func testList(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const keyPrefix = "blob-for-list" + content := []byte("hello") + + keyForIndex := func(i int) string { return fmt.Sprintf("%s-%d", keyPrefix, i) } + gotIndices := func(t *testing.T, objs []*driver.ListObject) []int { + t.Helper() + + var got []int + for _, obj := range objs { + if !strings.HasPrefix(obj.Key, keyPrefix) { + t.Errorf("got name %q, expected it to have prefix %q", obj.Key, keyPrefix) + continue + } + i, err := strconv.Atoi(obj.Key[len(keyPrefix)+1:]) + if err != nil { + t.Error(err) + continue + } + got = append(got, i) + } + return got + } + + tests := []struct { + name string + pageSize int + prefix string + wantPages [][]int + want []int + }{ + { + name: "no objects", + prefix: "no-objects-with-this-prefix", + wantPages: [][]int{nil}, + }, + { + name: "exactly 1 object due to prefix", + prefix: keyForIndex(1), + wantPages: [][]int{{1}}, + want: []int{1}, + }, + { + name: "no pagination", + prefix: keyPrefix, + wantPages: [][]int{{0, 1, 2}}, + want: []int{0, 1, 2}, + }, + { + name: "by 1", + prefix: keyPrefix, + pageSize: 1, + wantPages: [][]int{{0}, {1}, {2}}, + want: []int{0, 1, 2}, + }, + { + name: "by 2", + prefix: keyPrefix, + pageSize: 2, + wantPages: [][]int{{0, 1}, {2}}, + want: []int{0, 1, 2}, + }, + { + name: "by 3", + prefix: keyPrefix, + pageSize: 3, + wantPages: [][]int{{0, 1, 2}}, + want: []int{0, 1, 2}, + }, + } + + ctx := context.Background() + + // Creates blobs for sub-tests below. + // We only create the blobs once, for efficiency and because there's + // no guarantee that after we create them they will be immediately returned + // from List. The very first time the test is run against a Bucket, it may be + // flaky due to this race. + init := func(t *testing.T) (driver.Bucket, func()) { + t.Helper() + + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + // See if the blobs are already there. + b := blob.NewBucket(drv) + iter := b.List(&blob.ListOptions{Prefix: keyPrefix}) + found := iterToSetOfKeys(ctx, t, iter) + for i := 0; i < 3; i++ { + key := keyForIndex(i) + if !found[key] { + if err := b.WriteAll(ctx, key, content, nil); err != nil { + b.Close() + t.Fatal(err) + } + } + } + return drv, func() { b.Close(); h.Close() } + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + drv, done := init(t) + defer done() + + var gotPages [][]int + var got []int + var nextPageToken []byte + for { + page, err := drv.ListPaged(ctx, &driver.ListOptions{ + PageSize: tc.pageSize, + Prefix: tc.prefix, + PageToken: nextPageToken, + }) + if err != nil { + t.Fatal(err) + } + gotThisPage := gotIndices(t, page.Objects) + got = append(got, gotThisPage...) + gotPages = append(gotPages, gotThisPage) + if len(page.NextPageToken) == 0 { + break + } + nextPageToken = page.NextPageToken + } + if diff := cmp.Diff(gotPages, tc.wantPages); diff != "" { + t.Errorf("got\n%v\nwant\n%v\ndiff\n%s", gotPages, tc.wantPages, diff) + } + if diff := cmp.Diff(got, tc.want); diff != "" { + t.Errorf("got\n%v\nwant\n%v\ndiff\n%s", got, tc.want, diff) + } + }) + } + + // Verify pagination works when inserting in a retrieved page. + t.Run("PaginationConsistencyAfterInsert", func(t *testing.T) { + drv, done := init(t) + defer done() + + // Fetch a page of 2 results: 0, 1. + page, err := drv.ListPaged(ctx, &driver.ListOptions{ + PageSize: 2, + Prefix: keyPrefix, + }) + if err != nil { + t.Fatal(err) + } + got := gotIndices(t, page.Objects) + want := []int{0, 1} + if diff := cmp.Diff(got, want); diff != "" { + t.Fatalf("got\n%v\nwant\n%v\ndiff\n%s", got, want, diff) + } + + // Insert a key "0a" in the middle of the page we already retrieved. + b := blob.NewBucket(drv) + defer b.Close() + key := page.Objects[0].Key + "a" + if err := b.WriteAll(ctx, key, content, nil); err != nil { + t.Fatal(err) + } + defer func() { + _ = b.Delete(ctx, key) + }() + + // Fetch the next page. It should not include 0, 0a, or 1, and it should + // include 2. + page, err = drv.ListPaged(ctx, &driver.ListOptions{ + Prefix: keyPrefix, + PageToken: page.NextPageToken, + }) + if err != nil { + t.Fatal(err) + } + got = gotIndices(t, page.Objects) + want = []int{2} + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("got\n%v\nwant\n%v\ndiff\n%s", got, want, diff) + } + }) + + // Verify pagination works when deleting in a retrieved page. + t.Run("PaginationConsistencyAfterDelete", func(t *testing.T) { + drv, done := init(t) + defer done() + + // Fetch a page of 2 results: 0, 1. + page, err := drv.ListPaged(ctx, &driver.ListOptions{ + PageSize: 2, + Prefix: keyPrefix, + }) + if err != nil { + t.Fatal(err) + } + got := gotIndices(t, page.Objects) + want := []int{0, 1} + if diff := cmp.Diff(got, want); diff != "" { + t.Fatalf("got\n%v\nwant\n%v\ndiff\n%s", got, want, diff) + } + + // Delete key "1". + b := blob.NewBucket(drv) + defer b.Close() + key := page.Objects[1].Key + if err := b.Delete(ctx, key); err != nil { + t.Fatal(err) + } + defer func() { + _ = b.WriteAll(ctx, key, content, nil) + }() + + // Fetch the next page. It should not include 0 or 1, and it should + // include 2. + page, err = drv.ListPaged(ctx, &driver.ListOptions{ + Prefix: keyPrefix, + PageToken: page.NextPageToken, + }) + if err != nil { + t.Fatal(err) + } + got = gotIndices(t, page.Objects) + want = []int{2} + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("got\n%v\nwant\n%v\ndiff\n%s", got, want, diff) + } + }) +} + +// testListWeirdKeys tests the functionality of List on weird keys. +func testListWeirdKeys(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const keyPrefix = "list-weirdkeys-" + content := []byte("hello") + ctx := context.Background() + + // We're going to create a blob for each of the weird key strings, and + // then verify we can see them with List. + want := map[string]bool{} + for _, k := range escape.WeirdStrings { + want[keyPrefix+k] = true + } + + // Creates blobs for sub-tests below. + // We only create the blobs once, for efficiency and because there's + // no guarantee that after we create them they will be immediately returned + // from List. The very first time the test is run against a Bucket, it may be + // flaky due to this race. + init := func(t *testing.T) (*blob.Bucket, func()) { + t.Helper() + + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + // See if the blobs are already there. + b := blob.NewBucket(drv) + iter := b.List(&blob.ListOptions{Prefix: keyPrefix}) + found := iterToSetOfKeys(ctx, t, iter) + for _, k := range escape.WeirdStrings { + key := keyPrefix + k + if !found[key] { + if err := b.WriteAll(ctx, key, content, nil); err != nil { + b.Close() + t.Fatal(err) + } + } + } + return b, func() { b.Close(); h.Close() } + } + + b, done := init(t) + defer done() + + iter := b.List(&blob.ListOptions{Prefix: keyPrefix}) + got := iterToSetOfKeys(ctx, t, iter) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("got\n%v\nwant\n%v\ndiff\n%s", got, want, diff) + } +} + +// listResult is a recursive view of the hierarchy. It's used to verify List +// using Delimiter. +type listResult struct { + Key string + IsDir bool + // If IsDir is true and recursion is enabled, the recursive listing of the directory. + Sub []listResult +} + +// doList lists b using prefix and delim. +// If recurse is true, it recurses into directories filling in listResult.Sub. +func doList(ctx context.Context, b *blob.Bucket, prefix, delim string, recurse bool) ([]listResult, error) { + iter := b.List(&blob.ListOptions{ + Prefix: prefix, + Delimiter: delim, + }) + var retval []listResult + for { + obj, err := iter.Next(ctx) + if err == io.EOF { + if obj != nil { + return nil, errors.New("obj is not nil on EOF") + } + break + } + if err != nil { + return nil, err + } + var sub []listResult + if obj.IsDir && recurse { + sub, err = doList(ctx, b, obj.Key, delim, true) + if err != nil { + return nil, err + } + } + retval = append(retval, listResult{ + Key: obj.Key, + IsDir: obj.IsDir, + Sub: sub, + }) + } + return retval, nil +} + +// testListDelimiters tests the functionality of List using Delimiters. +func testListDelimiters(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const keyPrefix = "blob-for-delimiters-" + content := []byte("hello") + + // The set of files to use for these tests. The strings in each entry will + // be joined using delim, so the result is a directory structure like this + // (using / as delimiter): + // dir1/a.txt + // dir1/b.txt + // dir1/subdir/c.txt + // dir1/subdir/d.txt + // dir2/e.txt + // f.txt + keys := [][]string{ + {"dir1", "a.txt"}, + {"dir1", "b.txt"}, + {"dir1", "subdir", "c.txt"}, + {"dir1", "subdir", "d.txt"}, + {"dir2", "e.txt"}, + {"f.txt"}, + } + + // Test with several different delimiters. + tests := []struct { + name, delim string + // Expected result of doList with an empty delimiter. + // All keys should be listed at the top level, with no directories. + wantFlat []listResult + // Expected result of doList with delimiter and recurse = true. + // All keys should be listed, with keys in directories in the Sub field + // of their directory. + wantRecursive []listResult + // Expected result of repeatedly calling driver.ListPaged with delimiter + // and page size = 1. + wantPaged []listResult + // expected result of doList with delimiter and recurse = false + // after dir2/e.txt is deleted + // dir1/ and f.txt should be listed; dir2/ should no longer be present + // because there are no keys in it. + wantAfterDel []listResult + }{ + { + name: "fwdslash", + delim: "/", + wantFlat: []listResult{ + {Key: keyPrefix + "/dir1/a.txt"}, + {Key: keyPrefix + "/dir1/b.txt"}, + {Key: keyPrefix + "/dir1/subdir/c.txt"}, + {Key: keyPrefix + "/dir1/subdir/d.txt"}, + {Key: keyPrefix + "/dir2/e.txt"}, + {Key: keyPrefix + "/f.txt"}, + }, + wantRecursive: []listResult{ + { + Key: keyPrefix + "/dir1/", + IsDir: true, + Sub: []listResult{ + {Key: keyPrefix + "/dir1/a.txt"}, + {Key: keyPrefix + "/dir1/b.txt"}, + { + Key: keyPrefix + "/dir1/subdir/", + IsDir: true, + Sub: []listResult{ + {Key: keyPrefix + "/dir1/subdir/c.txt"}, + {Key: keyPrefix + "/dir1/subdir/d.txt"}, + }, + }, + }, + }, + { + Key: keyPrefix + "/dir2/", + IsDir: true, + Sub: []listResult{ + {Key: keyPrefix + "/dir2/e.txt"}, + }, + }, + {Key: keyPrefix + "/f.txt"}, + }, + wantPaged: []listResult{ + { + Key: keyPrefix + "/dir1/", + IsDir: true, + }, + { + Key: keyPrefix + "/dir2/", + IsDir: true, + }, + {Key: keyPrefix + "/f.txt"}, + }, + wantAfterDel: []listResult{ + { + Key: keyPrefix + "/dir1/", + IsDir: true, + }, + {Key: keyPrefix + "/f.txt"}, + }, + }, + { + name: "backslash", + delim: "\\", + wantFlat: []listResult{ + {Key: keyPrefix + "\\dir1\\a.txt"}, + {Key: keyPrefix + "\\dir1\\b.txt"}, + {Key: keyPrefix + "\\dir1\\subdir\\c.txt"}, + {Key: keyPrefix + "\\dir1\\subdir\\d.txt"}, + {Key: keyPrefix + "\\dir2\\e.txt"}, + {Key: keyPrefix + "\\f.txt"}, + }, + wantRecursive: []listResult{ + { + Key: keyPrefix + "\\dir1\\", + IsDir: true, + Sub: []listResult{ + {Key: keyPrefix + "\\dir1\\a.txt"}, + {Key: keyPrefix + "\\dir1\\b.txt"}, + { + Key: keyPrefix + "\\dir1\\subdir\\", + IsDir: true, + Sub: []listResult{ + {Key: keyPrefix + "\\dir1\\subdir\\c.txt"}, + {Key: keyPrefix + "\\dir1\\subdir\\d.txt"}, + }, + }, + }, + }, + { + Key: keyPrefix + "\\dir2\\", + IsDir: true, + Sub: []listResult{ + {Key: keyPrefix + "\\dir2\\e.txt"}, + }, + }, + {Key: keyPrefix + "\\f.txt"}, + }, + wantPaged: []listResult{ + { + Key: keyPrefix + "\\dir1\\", + IsDir: true, + }, + { + Key: keyPrefix + "\\dir2\\", + IsDir: true, + }, + {Key: keyPrefix + "\\f.txt"}, + }, + wantAfterDel: []listResult{ + { + Key: keyPrefix + "\\dir1\\", + IsDir: true, + }, + {Key: keyPrefix + "\\f.txt"}, + }, + }, + { + name: "abc", + delim: "abc", + wantFlat: []listResult{ + {Key: keyPrefix + "abcdir1abca.txt"}, + {Key: keyPrefix + "abcdir1abcb.txt"}, + {Key: keyPrefix + "abcdir1abcsubdirabcc.txt"}, + {Key: keyPrefix + "abcdir1abcsubdirabcd.txt"}, + {Key: keyPrefix + "abcdir2abce.txt"}, + {Key: keyPrefix + "abcf.txt"}, + }, + wantRecursive: []listResult{ + { + Key: keyPrefix + "abcdir1abc", + IsDir: true, + Sub: []listResult{ + {Key: keyPrefix + "abcdir1abca.txt"}, + {Key: keyPrefix + "abcdir1abcb.txt"}, + { + Key: keyPrefix + "abcdir1abcsubdirabc", + IsDir: true, + Sub: []listResult{ + {Key: keyPrefix + "abcdir1abcsubdirabcc.txt"}, + {Key: keyPrefix + "abcdir1abcsubdirabcd.txt"}, + }, + }, + }, + }, + { + Key: keyPrefix + "abcdir2abc", + IsDir: true, + Sub: []listResult{ + {Key: keyPrefix + "abcdir2abce.txt"}, + }, + }, + {Key: keyPrefix + "abcf.txt"}, + }, + wantPaged: []listResult{ + { + Key: keyPrefix + "abcdir1abc", + IsDir: true, + }, + { + Key: keyPrefix + "abcdir2abc", + IsDir: true, + }, + {Key: keyPrefix + "abcf.txt"}, + }, + wantAfterDel: []listResult{ + { + Key: keyPrefix + "abcdir1abc", + IsDir: true, + }, + {Key: keyPrefix + "abcf.txt"}, + }, + }, + } + + ctx := context.Background() + + // Creates blobs for sub-tests below. + // We only create the blobs once, for efficiency and because there's + // no guarantee that after we create them they will be immediately returned + // from List. The very first time the test is run against a Bucket, it may be + // flaky due to this race. + init := func(t *testing.T, delim string) (driver.Bucket, *blob.Bucket, func()) { + t.Helper() + + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + + // See if the blobs are already there. + prefix := keyPrefix + delim + iter := b.List(&blob.ListOptions{Prefix: prefix}) + found := iterToSetOfKeys(ctx, t, iter) + for _, keyParts := range keys { + key := prefix + strings.Join(keyParts, delim) + if !found[key] { + if err := b.WriteAll(ctx, key, content, nil); err != nil { + b.Close() + t.Fatal(err) + } + } + } + return drv, b, func() { b.Close(); h.Close() } + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + drv, b, done := init(t, tc.delim) + defer done() + + // Fetch without using delimiter. + got, err := doList(ctx, b, keyPrefix+tc.delim, "", true) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(got, tc.wantFlat); diff != "" { + t.Errorf("with no delimiter, got\n%v\nwant\n%v\ndiff\n%s", got, tc.wantFlat, diff) + } + + // Fetch using delimiter, recursively. + got, err = doList(ctx, b, keyPrefix+tc.delim, tc.delim, true) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(got, tc.wantRecursive); diff != "" { + t.Errorf("with delimiter, got\n%v\nwant\n%v\ndiff\n%s", got, tc.wantRecursive, diff) + } + + // Test pagination via driver.ListPaged. + var nextPageToken []byte + got = nil + for { + page, err := drv.ListPaged(ctx, &driver.ListOptions{ + Prefix: keyPrefix + tc.delim, + Delimiter: tc.delim, + PageSize: 1, + PageToken: nextPageToken, + }) + if err != nil { + t.Fatal(err) + } + if len(page.Objects) > 1 { + t.Errorf("got %d objects on a page, want 0 or 1", len(page.Objects)) + } + for _, obj := range page.Objects { + got = append(got, listResult{ + Key: obj.Key, + IsDir: obj.IsDir, + }) + } + if len(page.NextPageToken) == 0 { + break + } + nextPageToken = page.NextPageToken + } + if diff := cmp.Diff(got, tc.wantPaged); diff != "" { + t.Errorf("paged got\n%v\nwant\n%v\ndiff\n%s", got, tc.wantPaged, diff) + } + + // Delete dir2/e.txt and verify that dir2/ is no longer returned. + key := strings.Join(append([]string{keyPrefix}, "dir2", "e.txt"), tc.delim) + if err := b.Delete(ctx, key); err != nil { + t.Fatal(err) + } + // Attempt to restore dir2/e.txt at the end of the test for the next run. + defer func() { + _ = b.WriteAll(ctx, key, content, nil) + }() + + got, err = doList(ctx, b, keyPrefix+tc.delim, tc.delim, false) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(got, tc.wantAfterDel); diff != "" { + t.Errorf("after delete, got\n%v\nwant\n%v\ndiff\n%s", got, tc.wantAfterDel, diff) + } + }) + } +} + +// testDirsWithCharactersBeforeDelimiter tests a case where there's +// a directory on a pagination boundary that ends with a character that's +// less than the delimiter. +// See https://github.com/google/go-cloud/issues/3089. +func testDirsWithCharactersBeforeDelimiter(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const keyPrefix = "blob-for-dirs-with-chars-before-delimiter/" + content := []byte("hello") + + // The set of files to use for these tests. + keys := []string{ + "testFile1", + "t/t/t", + "t-/t.", + "dir1/testFile1dir1", + "dir2/testFile1dir2", + "d", + } + + // Note that "t-/" is before "t/". The delimiter is included in the + // alphabetical ordering. + want := []string{"d", "dir1/", "dir2/", "t-/", "t/", "testFile1"} + + // Create blobs. + // We only create the blobs once, for efficiency and because there's + // no guarantee that after we create them they will be immediately returned + // from List. The very first time the test is run against a Bucket, it may be + // flaky due to this race. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + + // See if the blobs are already there. + iter := b.List(&blob.ListOptions{Prefix: keyPrefix}) + found := iterToSetOfKeys(ctx, t, iter) + for _, key := range keys { + key = keyPrefix + key + if !found[key] { + if err := b.WriteAll(ctx, key, content, nil); err != nil { + b.Close() + t.Fatal(err) + } + } + } + defer b.Close() + defer h.Close() + + opts := &blob.ListOptions{ + Prefix: keyPrefix, + Delimiter: "/", + } + // All page sizes should return the same end result. + for pageSize := 10; pageSize != 0; pageSize-- { + var got []string + objs, token, err := b.ListPage(ctx, blob.FirstPageToken, pageSize, opts) + for { + if err != nil { + t.Fatal(err) + } + for _, o := range objs { + key := strings.TrimPrefix(o.Key, keyPrefix) + got = append(got, key) + } + if token == nil { + break + } + objs, token, err = b.ListPage(ctx, token, pageSize, opts) + } + if !reflect.DeepEqual(want, got) { + t.Fatalf("For page size %d, got \n%v\nwant\n%v", pageSize, got, want) + } + } +} + +func iterToSetOfKeys(ctx context.Context, t *testing.T, iter *blob.ListIterator) map[string]bool { + t.Helper() + + retval := map[string]bool{} + for { + if item, err := iter.Next(ctx); err == io.EOF { + break + } else if err != nil { + t.Fatal(err) + } else { + retval[item.Key] = true + } + } + return retval +} + +// testRead tests the functionality of NewReader, NewRangeReader, and Reader. +func testRead(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const key = "blob-for-reading" + content := []byte("abcdefghijklmnopqurstuvwxyz") + contentSize := int64(len(content)) + + tests := []struct { + name string + key string + offset, length int64 + want []byte + wantReadSize int64 + wantErr bool + // set to true to skip creation of the object for + // tests where we expect an error without any actual + // read. + skipCreate bool + }{ + { + name: "read of nonexistent key fails", + key: "key-does-not-exist", + length: -1, + wantErr: true, + }, + { + name: "negative offset fails", + key: key, + offset: -1, + wantErr: true, + skipCreate: true, + }, + { + name: "length 0 read", + key: key, + want: []byte{}, + }, + { + name: "read from positive offset to end", + key: key, + offset: 10, + length: -1, + want: content[10:], + wantReadSize: contentSize - 10, + }, + { + name: "read a part in middle", + key: key, + offset: 10, + length: 5, + want: content[10:15], + wantReadSize: 5, + }, + { + name: "read in full", + key: key, + length: -1, + want: content, + wantReadSize: contentSize, + }, + { + name: "read in full with negative length not -1", + key: key, + length: -42, + want: content, + wantReadSize: contentSize, + }, + } + + ctx := context.Background() + + // Creates a blob for sub-tests below. + init := func(t *testing.T, skipCreate bool) (*blob.Bucket, func()) { + t.Helper() + + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + if skipCreate { + return b, func() { b.Close(); h.Close() } + } + if err := b.WriteAll(ctx, key, content, nil); err != nil { + b.Close() + t.Fatal(err) + } + return b, func() { + _ = b.Delete(ctx, key) + b.Close() + h.Close() + } + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + b, done := init(t, tc.skipCreate) + defer done() + + r, err := b.NewRangeReader(ctx, tc.key, tc.offset, tc.length, nil) + if (err != nil) != tc.wantErr { + t.Errorf("got err %v want error %v", err, tc.wantErr) + } + if err != nil { + return + } + defer r.Close() + // Make the buffer bigger than needed to make sure we actually only read + // the expected number of bytes. + got := make([]byte, tc.wantReadSize+10) + n, err := r.Read(got) + // EOF error is optional, see https://golang.org/pkg/io/#Reader. + if err != nil && err != io.EOF { + t.Errorf("unexpected error during read: %v", err) + } + if int64(n) != tc.wantReadSize { + t.Errorf("got read length %d want %d", n, tc.wantReadSize) + } + if !cmp.Equal(got[:tc.wantReadSize], tc.want) { + t.Errorf("got %q want %q", string(got), string(tc.want)) + } + if r.Size() != contentSize { + t.Errorf("got size %d want %d", r.Size(), contentSize) + } + if r.ModTime().IsZero() { + t.Errorf("got zero mod time, want non-zero") + } + // For tests that successfully read, recreate the io.Reader and + // test it with iotest.TestReader. + r, err = b.NewRangeReader(ctx, tc.key, tc.offset, tc.length, nil) + if err != nil { + t.Errorf("failed to recreate Reader: %v", err) + return + } + defer r.Close() + if err = iotest.TestReader(r, tc.want); err != nil { + t.Errorf("iotest.TestReader failed: %v", err) + return + } + }) + } +} + +// testAttributes tests Attributes. +func testAttributes(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const ( + dirKey = "someDir" + key = dirKey + "/blob-for-attributes" + contentType = "text/plain" + cacheControl = "no-cache" + contentDisposition = "inline" + contentEncoding = "identity" + contentLanguage = "en" + ) + content := []byte("Hello World!") + + ctx := context.Background() + + // Creates a blob for sub-tests below. + init := func(t *testing.T) (*blob.Bucket, func()) { + t.Helper() + + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + opts := &blob.WriterOptions{ + ContentType: contentType, + CacheControl: cacheControl, + ContentDisposition: contentDisposition, + ContentEncoding: contentEncoding, + ContentLanguage: contentLanguage, + } + if err := b.WriteAll(ctx, key, content, opts); err != nil { + b.Close() + t.Fatal(err) + } + return b, func() { + _ = b.Delete(ctx, key) + b.Close() + h.Close() + } + } + + b, done := init(t) + defer done() + + for _, badKey := range []string{ + "not-found", + dirKey, + dirKey + "/", + } { + _, err := b.Attributes(ctx, badKey) + if err == nil { + t.Errorf("got nil want error") + } else if gcerrors.Code(err) != gcerrors.NotFound { + t.Errorf("got %v want NotFound error", err) + } else if !strings.Contains(err.Error(), badKey) { + t.Errorf("got %v want error to include missing key", err) + } + } + + a, err := b.Attributes(ctx, key) + if err != nil { + t.Fatalf("failed Attributes: %v", err) + } + // Also make a Reader so we can verify the subset of attributes + // that it exposes. + r, err := b.NewReader(ctx, key, nil) + if err != nil { + t.Fatalf("failed Attributes: %v", err) + } + if a.CacheControl != cacheControl { + t.Errorf("got CacheControl %q want %q", a.CacheControl, cacheControl) + } + if a.ContentDisposition != contentDisposition { + t.Errorf("got ContentDisposition %q want %q", a.ContentDisposition, contentDisposition) + } + if a.ContentEncoding != contentEncoding { + t.Errorf("got ContentEncoding %q want %q", a.ContentEncoding, contentEncoding) + } + if a.ContentLanguage != contentLanguage { + t.Errorf("got ContentLanguage %q want %q", a.ContentLanguage, contentLanguage) + } + if a.ContentType != contentType { + t.Errorf("got ContentType %q want %q", a.ContentType, contentType) + } + if r.ContentType() != contentType { + t.Errorf("got Reader.ContentType() %q want %q", r.ContentType(), contentType) + } + if !a.CreateTime.IsZero() { + if a.CreateTime.After(a.ModTime) { + t.Errorf("CreateTime %v is after ModTime %v", a.CreateTime, a.ModTime) + } + } + if a.ModTime.IsZero() { + t.Errorf("ModTime not set") + } + if a.Size != int64(len(content)) { + t.Errorf("got Size %d want %d", a.Size, len(content)) + } + if r.Size() != int64(len(content)) { + t.Errorf("got Reader.Size() %d want %d", r.Size(), len(content)) + } + if a.ETag == "" { + t.Error("ETag not set") + } + // Some basic syntax checks on ETag based on https://en.wikipedia.org/wiki/HTTP_ETag. + // It should be of the form "xxxx" or W/"xxxx". + if !strings.HasPrefix(a.ETag, "W/\"") && !strings.HasPrefix(a.ETag, "\"") { + t.Errorf("ETag should start with W/\" or \" (got %s)", a.ETag) + } + if !strings.HasSuffix(a.ETag, "\"") { + t.Errorf("ETag should end with \" (got %s)", a.ETag) + } + r.Close() + + // Modify and re-fetch attributes. + if err := b.WriteAll(ctx, key, content, nil); err != nil { + t.Fatal(err) + } + + a2, err := b.Attributes(ctx, key) + if err != nil { + t.Errorf("failed Attributes#2: %v", err) + } + if a2.ModTime.Before(a.ModTime) { + t.Errorf("ModTime %v is before %v", a2.ModTime, a.ModTime) + } +} + +// loadTestData loads test data, inlined using go-bindata. +func loadTestData(tb testing.TB, name string) []byte { + tb.Helper() + + data, err := Asset(name) + if err != nil { + tb.Fatal(err) + } + return data +} + +// testWrite tests the functionality of NewWriter and Writer. +func testWrite(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const key = "blob-for-reading" + const existingContent = "existing content" + smallText := loadTestData(t, "test-small.txt") + mediumHTML := loadTestData(t, "test-medium.html") + largeJpg := loadTestData(t, "test-large.jpg") + helloWorld := []byte("hello world") + helloWorldMD5 := md5.Sum(helloWorld) + + tests := []struct { + name string + key string + exists bool + content []byte + contentType string + disableContentTypeDetection bool + contentMD5 []byte + firstChunk int + wantContentType *regexp.Regexp + wantErr bool + wantReadErr bool // if wantErr is true, and Read after err should fail with something other than NotExists + }{ + { + name: "write to empty key fails", + wantErr: true, + wantReadErr: true, // read from empty key fails, but not always with NotExists + }, + { + name: "no write then close results in empty blob", + key: key, + }, + { + name: "no write then close results in empty blob, blob existed", + key: key, + }, + { + name: "invalid ContentType fails", + key: key, + contentType: "application/octet/stream", + wantErr: true, + }, + { + name: "ContentType is discovered if not provided", + key: key, + content: mediumHTML, + wantContentType: regexp.MustCompile("text/html"), + }, + { + name: "ContentType is left empty if not provided and DisableContentTypeDetection is true", + key: key, + content: mediumHTML, + disableContentTypeDetection: true, + // Sadly we can't really verify this; even though we write the ContentType + // empty, different providers return different values when we read it, + // from "application/octet-stream" to their own sniffing. + // wantContentType: regexp.MustCompile("^$"), + }, + { + name: "write with explicit ContentType overrides discovery", + key: key, + content: mediumHTML, + contentType: "application/json", + wantContentType: regexp.MustCompile("application/json"), + }, + { + name: "Content md5 match", + key: key, + content: helloWorld, + contentMD5: helloWorldMD5[:], + }, + { + name: "Content md5 did not match", + key: key, + content: []byte("not hello world"), + contentMD5: helloWorldMD5[:], + wantErr: true, + }, + { + name: "Content md5 did not match, blob existed", + exists: true, + key: key, + content: []byte("not hello world"), + contentMD5: helloWorldMD5[:], + wantErr: true, + }, + { + name: "a small text file gets a ContentType", + key: key, + content: smallText, + wantContentType: regexp.MustCompile("text/plain.*"), + }, + { + name: "a large jpg file gets a ContentType", + key: key, + content: largeJpg, + wantContentType: regexp.MustCompile("image/jpeg"), + }, + { + name: "a large jpg file written in two chunks gets a ContentType", + key: key, + firstChunk: 10, + content: largeJpg, + wantContentType: regexp.MustCompile("image/jpeg"), + }, + // TODO(issue #304): Fails for GCS. + /* + { + name: "ContentType is parsed and reformatted", + key: key, + content: []byte("foo"), + contentType: `FORM-DATA;name="foo"`, + wantContentType: `form-data; name=foo`, + }, + */ + } + + ctx := context.Background() + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + // If the test wants the blob to already exist, write it. + if tc.exists { + if err := b.WriteAll(ctx, key, []byte(existingContent), nil); err != nil { + t.Fatal(err) + } + defer func() { + _ = b.Delete(ctx, key) + }() + } + + // Write the content. + opts := &blob.WriterOptions{ + ContentType: tc.contentType, + DisableContentTypeDetection: tc.disableContentTypeDetection, + ContentMD5: tc.contentMD5[:], + } + w, err := b.NewWriter(ctx, tc.key, opts) + if err == nil { + if len(tc.content) > 0 { + if tc.firstChunk == 0 { + // Write the whole thing. + _, err = w.Write(tc.content) + } else { + // Write it in 2 chunks. + _, err = w.Write(tc.content[:tc.firstChunk]) + if err == nil { + _, err = w.Write(tc.content[tc.firstChunk:]) + } + } + } + if err == nil { + err = w.Close() + } + } + if (err != nil) != tc.wantErr { + t.Errorf("NewWriter or Close got err %v want error %v", err, tc.wantErr) + } + if err != nil { + // The write failed; verify that it had no effect. + buf, err := b.ReadAll(ctx, tc.key) + if tc.exists { + // Verify the previous content is still there. + if !bytes.Equal(buf, []byte(existingContent)) { + t.Errorf("Write failed as expected, but content doesn't match expected previous content; got \n%s\n want \n%s", string(buf), existingContent) + } + } else { + // Verify that the read fails with NotFound. + if err == nil { + t.Error("Write failed as expected, but Read after that didn't return an error") + } else if !tc.wantReadErr && gcerrors.Code(err) != gcerrors.NotFound { + t.Errorf("Write failed as expected, but Read after that didn't return the right error; got %v want NotFound", err) + } else if !strings.Contains(err.Error(), tc.key) { + t.Errorf("got %v want error to include missing key", err) + } + } + return + } + defer func() { _ = b.Delete(ctx, tc.key) }() + + // Read it back. + buf, err := b.ReadAll(ctx, tc.key) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(buf, tc.content) { + if len(buf) < 100 && len(tc.content) < 100 { + t.Errorf("read didn't match write; got \n%s\n want \n%s", string(buf), string(tc.content)) + } else { + t.Error("read didn't match write, content too large to display") + } + } + + // Verify the ContentType. + if tc.wantContentType != nil { + attrs, err := b.Attributes(ctx, tc.key) + if err != nil { + t.Fatal(err) + } + if !tc.wantContentType.MatchString(attrs.ContentType) { + t.Errorf("got ContentType %q, want one matching %v", attrs.ContentType, tc.wantContentType) + } + } + }) + } +} + +// testCanceledWrite tests the functionality of canceling an in-progress write. +func testCanceledWrite(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const key = "blob-for-canceled-write" + content := []byte("hello world") + cancelContent := []byte("going to cancel") + + tests := []struct { + description string + contentType string + exists bool + }{ + { + // The write will be buffered in the portable type as part of + // ContentType detection, so the first call to the Driver will be Close. + description: "EmptyContentType", + }, + { + // The write will be sent to the Driver, which may do its own + // internal buffering. + description: "NonEmptyContentType", + contentType: "text/plain", + }, + { + description: "BlobExists", + exists: true, + }, + // TODO(issue #482): Find a way to test that a chunked upload that's interrupted + // after some chunks are uploaded cancels correctly. + } + + ctx := context.Background() + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + cancelCtx, cancel := context.WithCancel(ctx) + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + opts := &blob.WriterOptions{ + ContentType: test.contentType, + } + // If the test wants the blob to already exist, write it. + if test.exists { + if err := b.WriteAll(ctx, key, content, opts); err != nil { + t.Fatal(err) + } + defer func() { + _ = b.Delete(ctx, key) + }() + } + + // Create a writer with the context that we're going + // to cancel. + w, err := b.NewWriter(cancelCtx, key, opts) + if err != nil { + t.Fatal(err) + } + // Write the content. + if _, err := w.Write(cancelContent); err != nil { + t.Fatal(err) + } + + // Verify that the previous content (if any) is still readable, + // because the write hasn't been Closed yet. + got, err := b.ReadAll(ctx, key) + if test.exists { + // The previous content should still be there. + if !cmp.Equal(got, content) { + t.Errorf("during unclosed write, got %q want %q", string(got), string(content)) + } + } else { + // The read should fail; the write hasn't been Closed so the + // blob shouldn't exist. + if err == nil { + t.Error("wanted read to return an error when write is not yet Closed") + } + } + + // Cancel the context to abort the write. + cancel() + // Close should return some kind of canceled context error. + // We can't verify the kind of error cleanly, so we just verify there's + // an error. + if err := w.Close(); err == nil { + t.Errorf("got Close error %v want canceled ctx error", err) + } + + // Verify the write was truly aborted. + got, err = b.ReadAll(ctx, key) + if test.exists { + // The previous content should still be there. + if !cmp.Equal(got, content) { + t.Errorf("after canceled write, got %q want %q", string(got), string(content)) + } + } else { + // The read should fail; the write was aborted so the + // blob shouldn't exist. + if err == nil { + t.Error("wanted read to return an error when write was canceled") + } + } + }) + } +} + +// testMetadata tests writing and reading the key/value metadata for a blob. +func testMetadata(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const key = "blob-for-metadata" + hello := []byte("hello") + + weirdMetadata := map[string]string{} + for _, k := range escape.WeirdStrings { + weirdMetadata[k] = k + } + + tests := []struct { + name string + metadata map[string]string + content []byte + contentType string + want map[string]string + wantErr bool + }{ + { + name: "empty", + content: hello, + metadata: map[string]string{}, + want: nil, + }, + { + name: "empty key fails", + content: hello, + metadata: map[string]string{"": "empty key value"}, + wantErr: true, + }, + { + name: "duplicate case-insensitive key fails", + content: hello, + metadata: map[string]string{"abc": "foo", "aBc": "bar"}, + wantErr: true, + }, + { + name: "valid metadata", + content: hello, + metadata: map[string]string{ + "key_a": "value-a", + "kEy_B": "value-b", + "key_c": "vAlUe-c", + }, + want: map[string]string{ + "key_a": "value-a", + "key_b": "value-b", + "key_c": "vAlUe-c", + }, + }, + { + name: "valid metadata with empty body", + content: nil, + metadata: map[string]string{"foo": "bar"}, + want: map[string]string{"foo": "bar"}, + }, + { + name: "valid metadata with content type", + content: hello, + contentType: "text/plain", + metadata: map[string]string{"foo": "bar"}, + want: map[string]string{"foo": "bar"}, + }, + { + name: "weird metadata keys", + content: hello, + metadata: weirdMetadata, + want: weirdMetadata, + }, + { + name: "non-utf8 metadata key", + content: hello, + metadata: map[string]string{escape.NonUTF8String: "bar"}, + wantErr: true, + }, + { + name: "non-utf8 metadata value", + content: hello, + metadata: map[string]string{"foo": escape.NonUTF8String}, + wantErr: true, + }, + } + + ctx := context.Background() + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + opts := &blob.WriterOptions{ + Metadata: tc.metadata, + ContentType: tc.contentType, + } + err = b.WriteAll(ctx, key, hello, opts) + if (err != nil) != tc.wantErr { + t.Errorf("got error %v want error %v", err, tc.wantErr) + } + if err != nil { + return + } + defer func() { + _ = b.Delete(ctx, key) + }() + a, err := b.Attributes(ctx, key) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(a.Metadata, tc.want); diff != "" { + t.Errorf("got\n%v\nwant\n%v\ndiff\n%s", a.Metadata, tc.want, diff) + } + }) + } +} + +// testMD5 tests reading MD5 hashes via List and Attributes. +func testMD5(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + ctx := context.Background() + + // Define two blobs with different content; we'll write them and then verify + // their returned MD5 hashes. + const aKey, bKey = "blob-for-md5-aaa", "blob-for-md5-bbb" + aContent, bContent := []byte("hello"), []byte("goodbye") + aMD5 := md5.Sum(aContent) + bMD5 := md5.Sum(bContent) + + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + // Write the two blobs. + if err := b.WriteAll(ctx, aKey, aContent, nil); err != nil { + t.Fatal(err) + } + defer func() { _ = b.Delete(ctx, aKey) }() + if err := b.WriteAll(ctx, bKey, bContent, nil); err != nil { + t.Fatal(err) + } + defer func() { _ = b.Delete(ctx, bKey) }() + + // Check the MD5 we get through Attributes. Note that it's always legal to + // return a nil MD5. + aAttr, err := b.Attributes(ctx, aKey) + if err != nil { + t.Fatal(err) + } + if aAttr.MD5 != nil && !bytes.Equal(aAttr.MD5, aMD5[:]) { + t.Errorf("got MD5\n%x\nwant\n%x", aAttr.MD5, aMD5) + } + + bAttr, err := b.Attributes(ctx, bKey) + if err != nil { + t.Fatal(err) + } + if bAttr.MD5 != nil && !bytes.Equal(bAttr.MD5, bMD5[:]) { + t.Errorf("got MD5\n%x\nwant\n%x", bAttr.MD5, bMD5) + } + + // Check the MD5 we get through List. Note that it's always legal to + // return a nil MD5. + iter := b.List(&blob.ListOptions{Prefix: "blob-for-md5-"}) + obj, err := iter.Next(ctx) + if err != nil { + t.Fatal(err) + } + if obj.Key != aKey { + t.Errorf("got name %q want %q", obj.Key, aKey) + } + if obj.MD5 != nil && !bytes.Equal(obj.MD5, aMD5[:]) { + t.Errorf("got MD5\n%x\nwant\n%x", obj.MD5, aMD5) + } + obj, err = iter.Next(ctx) + if err != nil { + t.Fatal(err) + } + if obj.Key != bKey { + t.Errorf("got name %q want %q", obj.Key, bKey) + } + if obj.MD5 != nil && !bytes.Equal(obj.MD5, bMD5[:]) { + t.Errorf("got MD5\n%x\nwant\n%x", obj.MD5, bMD5) + } +} + +// testCopy tests the functionality of Copy. +func testCopy(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const ( + srcKey = "blob-for-copying-src" + dstKey = "blob-for-copying-dest" + dstKeyExists = "blob-for-copying-dest-exists" + contentType = "text/plain" + cacheControl = "no-cache" + contentDisposition = "inline" + contentEncoding = "identity" + contentLanguage = "en" + ) + contents := []byte("Hello World") + + ctx := context.Background() + t.Run("NonExistentSourceFails", func(t *testing.T) { + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + err = b.Copy(ctx, dstKey, "does-not-exist", nil) + if err == nil { + t.Errorf("got nil want error") + } else if gcerrors.Code(err) != gcerrors.NotFound { + t.Errorf("got %v want NotFound error", err) + } else if !strings.Contains(err.Error(), "does-not-exist") { + t.Errorf("got %v want error to include missing key", err) + } + }) + + t.Run("Works", func(t *testing.T) { + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + // Create the source blob. + wopts := &blob.WriterOptions{ + ContentType: contentType, + CacheControl: cacheControl, + ContentDisposition: contentDisposition, + ContentEncoding: contentEncoding, + ContentLanguage: contentLanguage, + Metadata: map[string]string{"foo": "bar"}, + } + if err := b.WriteAll(ctx, srcKey, contents, wopts); err != nil { + t.Fatal(err) + } + + // Grab its attributes to compare to the copy's attributes later. + wantAttr, err := b.Attributes(ctx, srcKey) + if err != nil { + t.Fatal(err) + } + + // Clear uncomparable fields. + clearUncomparableFields := func(a *blob.Attributes) { + a.CreateTime = time.Time{} + a.ModTime = time.Time{} + a.ETag = "" + } + clearUncomparableFields(wantAttr) + + // Create another blob that we're going to overwrite. + if err := b.WriteAll(ctx, dstKeyExists, []byte("clobber me"), nil); err != nil { + t.Fatal(err) + } + + // Copy the source to the destination. + if err := b.Copy(ctx, dstKey, srcKey, nil); err != nil { + t.Errorf("got unexpected error copying blob: %v", err) + } + // Read the copy. + got, err := b.ReadAll(ctx, dstKey) + if err != nil { + t.Fatal(err) + } + if !cmp.Equal(got, contents) { + t.Errorf("got %q want %q", string(got), string(contents)) + } + // Verify attributes of the copy. + gotAttr, err := b.Attributes(ctx, dstKey) + if err != nil { + t.Fatal(err) + } + clearUncomparableFields(gotAttr) + if diff := cmp.Diff(gotAttr, wantAttr, cmpopts.IgnoreUnexported(blob.Attributes{})); diff != "" { + t.Errorf("got %v want %v diff %s", gotAttr, wantAttr, diff) + } + + // Copy the source to the second destination, where there's an existing blob. + // It should be overwritten. + if err := b.Copy(ctx, dstKeyExists, srcKey, nil); err != nil { + t.Errorf("got unexpected error copying blob: %v", err) + } + // Read the copy. + got, err = b.ReadAll(ctx, dstKeyExists) + if err != nil { + t.Fatal(err) + } + if !cmp.Equal(got, contents) { + t.Errorf("got %q want %q", string(got), string(contents)) + } + // Verify attributes of the copy. + gotAttr, err = b.Attributes(ctx, dstKeyExists) + if err != nil { + t.Fatal(err) + } + clearUncomparableFields(gotAttr) + if diff := cmp.Diff(gotAttr, wantAttr, cmpopts.IgnoreUnexported(blob.Attributes{})); diff != "" { + t.Errorf("got %v want %v diff %s", gotAttr, wantAttr, diff) + } + }) +} + +// testDelete tests the functionality of Delete. +func testDelete(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const key = "blob-for-deleting" + + ctx := context.Background() + t.Run("NonExistentFails", func(t *testing.T) { + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + err = b.Delete(ctx, "does-not-exist") + if err == nil { + t.Errorf("got nil want error") + } else if gcerrors.Code(err) != gcerrors.NotFound { + t.Errorf("got %v want NotFound error", err) + } else if !strings.Contains(err.Error(), "does-not-exist") { + t.Errorf("got %v want error to include missing key", err) + } + }) + + t.Run("Works", func(t *testing.T) { + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + // Create the blob. + if err := b.WriteAll(ctx, key, []byte("Hello world"), nil); err != nil { + t.Fatal(err) + } + // Delete it. + if err := b.Delete(ctx, key); err != nil { + t.Errorf("got unexpected error deleting blob: %v", err) + } + // Subsequent read fails with NotFound. + _, err = b.NewReader(ctx, key, nil) + if err == nil { + t.Errorf("read after delete got nil, want error") + } else if gcerrors.Code(err) != gcerrors.NotFound { + t.Errorf("read after delete want NotFound error, got %v", err) + } else if !strings.Contains(err.Error(), key) { + t.Errorf("got %v want error to include missing key", err) + } + // Subsequent delete also fails. + err = b.Delete(ctx, key) + if err == nil { + t.Errorf("delete after delete got nil, want error") + } else if gcerrors.Code(err) != gcerrors.NotFound { + t.Errorf("delete after delete got %v, want NotFound error", err) + } else if !strings.Contains(err.Error(), key) { + t.Errorf("got %v want error to include missing key", err) + } + }) +} + +// testConcurrentWriteAndRead tests that concurrent writing to multiple blob +// keys and concurrent reading from multiple blob keys works. +func testConcurrentWriteAndRead(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + // Prepare data. Each of the numKeys blobs has dataSize bytes, with each byte + // set to the numeric key index. For example, the blob at "key0" consists of + // all dataSize bytes set to 0. + const numKeys = 20 + const dataSize = 4 * 1024 + keyData := make(map[int][]byte) + for k := 0; k < numKeys; k++ { + data := make([]byte, dataSize) + for i := 0; i < dataSize; i++ { + data[i] = byte(k) + } + keyData[k] = data + } + + blobName := func(k int) string { + return fmt.Sprintf("key%d", k) + } + + var wg sync.WaitGroup + + errs := make(chan error, numKeys) + + // Write all blobs concurrently. + for k := 0; k < numKeys; k++ { + wg.Add(1) + go func(key int) { + if err := b.WriteAll(ctx, blobName(key), keyData[key], nil); err != nil { + errs <- fmt.Errorf("WriteAll key=%v: %w", key, err) + } + wg.Done() + }(k) + defer b.Delete(ctx, blobName(k)) + } + wg.Wait() + + close(errs) + + for err := range errs { + t.Fatalf("got error from concurrent blob write: %v", err) + } + + errs = make(chan error, numKeys) + + // Read all blobs concurrently and verify that they contain the expected data. + for k := 0; k < numKeys; k++ { + wg.Add(1) + go func(key int) { + buf, err := b.ReadAll(ctx, blobName(key)) + if err != nil { + errs <- err + } else if !bytes.Equal(buf, keyData[key]) { + errs <- fmt.Errorf("read data mismatch for key %d", key) + } + wg.Done() + }(k) + } + wg.Wait() + + close(errs) + + for err := range errs { + t.Fatalf("got error from concurrent blob write: %v", err) + } +} + +// testUploadDownload tests that Upload and Download work. For many drivers, +// these are implemented in the concrete type, but drivers that implement Reader.Download +// and/or Writer.Upload will have those called directly. +func testUploadDownload(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const key = "blob-for-upload-download" + const contents = "up and down" + contentsMD5 := md5.Sum([]byte(contents)) + + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + // Write a blob using Upload. + if err := b.Upload(ctx, key, strings.NewReader(contents), &blob.WriterOptions{ContentType: "text"}); err != nil { + t.Fatal(err) + } + defer b.Delete(ctx, key) + + // Read the blob using Download. + var bb bytes.Buffer + err = b.Download(ctx, key, &bb, nil) + if err != nil { + t.Fatal(err) + } + if bb.String() != contents { + t.Errorf("read data mismatch for key %s", key) + } + + // Write another blob using Upload and ContentMD5 checking (this disables the Upload optimization). + if err := b.Upload(ctx, key, strings.NewReader(contents), &blob.WriterOptions{ContentMD5: contentsMD5[:], ContentType: "text"}); err != nil { + t.Fatal(err) + } + defer b.Delete(ctx, key) +} + +// testKeys tests a variety of weird keys. +func testKeys(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const keyPrefix = "weird-keys" + content := []byte("hello") + ctx := context.Background() + + t.Run("non-UTF8 fails", func(t *testing.T) { + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + // Write the blob. + key := keyPrefix + escape.NonUTF8String + if err := b.WriteAll(ctx, key, content, nil); err == nil { + t.Error("got nil error, expected error for using non-UTF8 string as key") + } + }) + + for description, key := range escape.WeirdStrings { + t.Run(description, func(t *testing.T) { + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + // Write the blob. + key = keyPrefix + key + if err := b.WriteAll(ctx, key, content, nil); err != nil { + t.Fatal(err) + } + + defer func() { + err := b.Delete(ctx, key) + if err != nil { + t.Error(err) + } + }() + + // Verify read works. + got, err := b.ReadAll(ctx, key) + if err != nil { + t.Fatal(err) + } + if !cmp.Equal(got, content) { + t.Errorf("got %q want %q", string(got), string(content)) + } + + // Verify Attributes works. + _, err = b.Attributes(ctx, key) + if err != nil { + t.Error(err) + } + + // Verify SignedURL works. + url, err := b.SignedURL(ctx, key, nil) + if gcerrors.Code(err) != gcerrors.Unimplemented { + if err != nil { + t.Error(err) + } + client := h.HTTPClient() + if client == nil { + t.Error("can't verify SignedURL, Harness.HTTPClient() returned nil") + } + resp, err := client.Get(url) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + t.Errorf("got status code %d, want 200", resp.StatusCode) + } + got, err := io.ReadAll(resp.Body) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(got, content) { + t.Errorf("got body %q, want %q", string(got), string(content)) + } + } + + // Copy the blob. + // TODO: s3blob's Copy fails on repeatedfwdslashes. + if description != "repeatedfwdslashes" { + copyToKey := key + "-copy" + if err := b.Copy(ctx, copyToKey, key, nil); err != nil { + t.Fatal(err) + } + defer func() { + err := b.Delete(ctx, copyToKey) + if err != nil { + t.Error(err) + } + }() + got, err = b.ReadAll(ctx, copyToKey) + if err != nil { + t.Fatal(err) + } + if !cmp.Equal(got, content) { + t.Errorf("copied got %q want %q", string(got), string(content)) + } + } + }) + } +} + +// testSignedURL tests the functionality of SignedURL. +func testSignedURL(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const key = "blob-for-signing" + const contents = "hello world" + + ctx := context.Background() + + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + // Verify that a negative Expiry gives an error. This is enforced in the + // portable type, so works regardless of driver support. + _, err = b.SignedURL(ctx, key, &blob.SignedURLOptions{Expiry: -1 * time.Minute}) + if err == nil { + t.Error("got nil error, expected error for negative SignedURLOptions.Expiry") + } + + // Generate a signed URL for GET. + getURL, err := b.SignedURL(ctx, key, nil) + if err != nil { + if gcerrors.Code(err) == gcerrors.Unimplemented { + t.Skipf("SignedURL not supported") + return + } + t.Fatal(err) + } else if getURL == "" { + t.Fatal("got empty GET url") + } + + // Copy getURL, but remove all query params. This URL should not be allowed + // to GET since the client is unauthorized. + getURLNoParamsURL, err := url.Parse(getURL) + if err != nil { + t.Fatalf("failed to parse getURL: %v", err) + } + getURLNoParamsURL.RawQuery = "" + getURLNoParams := getURLNoParamsURL.String() + const ( + allowedContentType = "text/plain" + differentContentType = "application/octet-stream" + ) + + // Generate a signed URL for PUT, with a non-empty ContentType. + putURLWithContentType, err := b.SignedURL(ctx, key, &blob.SignedURLOptions{ + Method: http.MethodPut, + ContentType: allowedContentType, + }) + if gcerrors.Code(err) == gcerrors.Unimplemented { + t.Log("PUT URLs with content type not supported, skipping") + } else if err != nil { + t.Fatal(err) + } else if putURLWithContentType == "" { + t.Fatal("got empty PUT url") + } + + // Generate a signed URL for PUT, with an empty ContentType that's enforced. + putURLEnforcedAbsentContentType, err := b.SignedURL(ctx, key, &blob.SignedURLOptions{ + Method: http.MethodPut, + EnforceAbsentContentType: true, + }) + if gcerrors.Code(err) == gcerrors.Unimplemented { + t.Log("PUT URLs with enforced absent content type not supported, skipping") + } else if err != nil { + t.Fatal(err) + } else if putURLEnforcedAbsentContentType == "" { + t.Fatal("got empty PUT url") + } + + // Same as above, but not enforced. + putURLWithoutContentType, err := b.SignedURL(ctx, key, &blob.SignedURLOptions{ + Method: http.MethodPut, + }) + if err != nil { + t.Fatal(err) + } else if putURLWithoutContentType == "" { + t.Fatal("got empty PUT url") + } + + // Generate a signed URL for DELETE. + deleteURL, err := b.SignedURL(ctx, key, &blob.SignedURLOptions{Method: http.MethodDelete}) + if gcerrors.Code(err) == gcerrors.Unimplemented { + t.Log("DELETE URLs not supported, skipping") + } else if err != nil { + t.Fatal(err) + } else if deleteURL == "" { + t.Fatal("got empty DELETE url") + } + + client := h.HTTPClient() + if client == nil { + t.Fatal("can't verify SignedURL, Harness.HTTPClient() returned nil") + } + + // PUT the blob. Try with all URLs, only putURL should work when given the + // content type used in the signature. + type signedURLTest struct { + urlDescription string + url string + contentType string + wantSuccess bool + } + tests := []signedURLTest{ + {"getURL", getURL, "", false}, + } + if deleteURL != "" { + tests = append(tests, signedURLTest{"deleteURL", deleteURL, "", false}) + } + if putURLWithContentType != "" { + // Allowed content type should work. + // Different or empty content type should fail. + tests = append(tests, signedURLTest{"putURLWithContentType", putURLWithContentType, allowedContentType, true}) + tests = append(tests, signedURLTest{"putURLWithContentType", putURLWithContentType, differentContentType, false}) + tests = append(tests, signedURLTest{"putURLWithContentType", putURLWithContentType, "", false}) + } + if putURLEnforcedAbsentContentType != "" { + // Empty content type should work, non-empty should fail. + tests = append(tests, signedURLTest{"putURLEnforcedAbsentContentType", putURLEnforcedAbsentContentType, "", true}) + tests = append(tests, signedURLTest{"putURLEnforcedAbsentContentType", putURLEnforcedAbsentContentType, differentContentType, false}) + } + if putURLWithoutContentType != "" { + // Empty content type should work. + tests = append(tests, signedURLTest{"putURLWithoutContentType", putURLWithoutContentType, "", true}) + // From the SignedURLOptions docstring: + // If EnforceAbsentContentType is false and ContentType is the empty string, + // then PUTing without a Content-Type header will succeed, but it is + // implementation-specific whether providing a Content-Type header will fail. + // --> so, we don't have a test for putURLWithoutContentType and a non-empty ContentType. + } + for _, test := range tests { + req, err := http.NewRequest(http.MethodPut, test.url, strings.NewReader(contents)) + if err != nil { + t.Fatalf("failed to create PUT HTTP request using %q: %v", test.urlDescription, err) + } + if test.contentType != "" { + req.Header.Set("Content-Type", test.contentType) + } + if resp, err := client.Do(req); err != nil { + t.Fatalf("PUT to %q with ContentType %q failed: %v", test.urlDescription, test.contentType, err) + } else { + defer resp.Body.Close() + success := resp.StatusCode >= 200 && resp.StatusCode < 300 + if success != test.wantSuccess { + t.Errorf("PUT to %q with ContentType %q got status code %d, wanted 2xx? %v", test.urlDescription, test.contentType, resp.StatusCode, test.wantSuccess) + gotBody, _ := io.ReadAll(resp.Body) + t.Error(string(gotBody)) + } + } + } + + // GET it. Try with all URLs, only getURL should work. + tests = nil + if deleteURL != "" { + tests = append(tests, signedURLTest{"deleteURL", deleteURL, "", false}) + } + tests = append(tests, []signedURLTest{ + {"putURLWithoutContentType", putURLWithoutContentType, "", false}, + {"getURLNoParams", getURLNoParams, "", false}, + {"getURL", getURL, "", true}, + }...) + for _, test := range tests { + if resp, err := client.Get(test.url); err != nil { + t.Fatalf("GET with %s URL failed: %v", test.urlDescription, err) + } else { + defer resp.Body.Close() + success := resp.StatusCode >= 200 && resp.StatusCode < 300 + if success != test.wantSuccess { + t.Errorf("GET to %q got status code %d, want 2xx? %v", test.urlDescription, resp.StatusCode, test.wantSuccess) + gotBody, _ := io.ReadAll(resp.Body) + t.Error(string(gotBody)) + } else if success { + gotBody, err := io.ReadAll(resp.Body) + if err != nil { + t.Errorf("GET to %q failed to read response body: %v", test.urlDescription, err) + } else if gotBodyStr := string(gotBody); gotBodyStr != contents { + t.Errorf("GET to %q got body %q, want %q", test.urlDescription, gotBodyStr, contents) + } + } + } + } + + // DELETE it. Try with all URLs, only deleteURL should work. + tests = []signedURLTest{ + {"getURL", getURL, "", false}, + {"putURLWithoutContentType", putURLWithoutContentType, "", false}, + } + if deleteURL != "" { + tests = append(tests, signedURLTest{"deleteURL", deleteURL, "", true}) + } + for _, test := range tests { + req, err := http.NewRequest(http.MethodDelete, test.url, nil) + if err != nil { + t.Fatalf("failed to create DELETE HTTP request using %q: %v", test.urlDescription, err) + } + if resp, err := client.Do(req); err != nil { + t.Fatalf("DELETE to %q failed: %v", test.urlDescription, err) + } else { + defer resp.Body.Close() + success := resp.StatusCode >= 200 && resp.StatusCode < 300 + if success != test.wantSuccess { + gotBody, _ := io.ReadAll(resp.Body) + t.Error(string(gotBody)) + t.Fatalf("DELETE to %q got status code %d, want 2xx? %v", test.urlDescription, resp.StatusCode, test.wantSuccess) + } + } + } + + // GET should fail now that the blob has been deleted. + if deleteURL != "" { + if resp, err := client.Get(getURL); err != nil { + t.Errorf("GET after DELETE failed: %v", err) + } else { + defer resp.Body.Close() + if resp.StatusCode != 404 { + t.Errorf("GET after DELETE got status code %d, want 404", resp.StatusCode) + gotBody, _ := io.ReadAll(resp.Body) + t.Error(string(gotBody)) + } + } + } +} + +// testAs tests the various As functions, using AsTest. +func testAs(t *testing.T, newHarness HarnessMaker, st AsTest) { + t.Helper() + + const ( + dir = "mydir" + key = dir + "/as-test" + copyKey = dir + "/as-test-copy" + ) + content := []byte("hello world") + ctx := context.Background() + + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer b.Close() + + // Verify Bucket.As. + if err := st.BucketCheck(b); err != nil { + t.Error(err) + } + + // Create a blob, using the provided callback. + if err := b.WriteAll(ctx, key, content, &blob.WriterOptions{BeforeWrite: st.BeforeWrite}); err != nil { + t.Error(err) + } + defer func() { _ = b.Delete(ctx, key) }() + + // Verify Attributes.As. + attrs, err := b.Attributes(ctx, key) + if err != nil { + t.Fatal(err) + } + if err := st.AttributesCheck(attrs); err != nil { + t.Error(err) + } + + // Verify Reader.As. + r, err := b.NewReader(ctx, key, &blob.ReaderOptions{BeforeRead: st.BeforeRead}) + if err != nil { + t.Fatal(err) + } + defer r.Close() + if err := st.ReaderCheck(r); err != nil { + t.Error(err) + } + + // Verify ListObject.As for the directory. + iter := b.List(&blob.ListOptions{Prefix: dir, Delimiter: "/", BeforeList: st.BeforeList}) + found := false + for { + obj, err := iter.Next(ctx) + if err == io.EOF { + break + } + if found { + t.Fatal("got a second object returned from List, only wanted one") + } + found = true + if err != nil { + log.Fatal(err) + } + if err := st.ListObjectCheck(obj); err != nil { + t.Error(err) + } + } + + // Verify ListObject.As for the blob. + iter = b.List(&blob.ListOptions{Prefix: key, BeforeList: st.BeforeList}) + found = false + for { + obj, err := iter.Next(ctx) + if err == io.EOF { + break + } + if found { + t.Fatal("got a second object returned from List, only wanted one") + } + found = true + if err != nil { + log.Fatal(err) + } + if err := st.ListObjectCheck(obj); err != nil { + t.Error(err) + } + } + + _, gotErr := b.NewReader(ctx, "key-does-not-exist", nil) + if gotErr == nil { + t.Fatalf("got nil error from NewReader for nonexistent key, want an error") + } + if err := st.ErrorCheck(b, gotErr); err != nil { + t.Error(err) + } + + // Copy the blob, using the provided callback. + if err := b.Copy(ctx, copyKey, key, &blob.CopyOptions{BeforeCopy: st.BeforeCopy}); err != nil { + t.Error(err) + } else { + defer func() { _ = b.Delete(ctx, copyKey) }() + } + + for _, method := range []string{http.MethodGet, http.MethodPut, http.MethodDelete} { + _, err = b.SignedURL(ctx, key, &blob.SignedURLOptions{Method: method, BeforeSign: st.BeforeSign}) + if err != nil && gcerrors.Code(err) != gcerrors.Unimplemented { + t.Errorf("got err %v when signing url with method %q", err, method) + } + } +} + +func testIfNotExist(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const key = "blob-for-if-not-exist" + const contents = "up and down" + + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + b := blob.NewBucket(drv) + defer func() { _ = b.Close() }() + + opts := blob.WriterOptions{ + ContentType: "text", + IfNotExist: true, + } + + // Create the new blob; expected to work since it doesn't exist. + w1, err := b.NewWriter(ctx, key, &opts) + if err != nil { + t.Fatal(err) + } + defer func() { + _ = b.Delete(ctx, key) + }() + if _, err := w1.Write([]byte(contents)); err != nil { + t.Fatal(err) + } + if err := w1.Close(); err != nil { + t.Fatal(err) + } + + // Attempt a second write to the same key; expected to fail in + // either Write or Close, with FailedPrecondition. + w2, err := b.NewWriter(ctx, key, &opts) + if err != nil { + t.Fatal(err) + } + if _, err = w2.Write([]byte(contents)); err == nil { + err = w2.Close() + } else { + _ = w2.Close() + } + if err == nil { + t.Error("expected error rewriting key with IfNotExist, got nil") + } + if code := gcerrors.Code(err); code != gcerrors.FailedPrecondition { + t.Errorf("expected FailedPrecondition error, got %v", code) + } +} + +func benchmarkRead(b *testing.B, bkt *blob.Bucket) { + b.Helper() + + ctx := context.Background() + const key = "readbenchmark-blob" + + content := loadTestData(b, "test-large.jpg") + if err := bkt.WriteAll(ctx, key, content, nil); err != nil { + b.Fatal(err) + } + defer func() { + _ = bkt.Delete(ctx, key) + }() + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + var buffer bytes.Buffer + buffer.Grow(len(content)) + + for pb.Next() { + buffer.Reset() + r, err := bkt.NewReader(ctx, key, nil) + if err != nil { + b.Error(err) + } + + if _, err = io.Copy(&buffer, r); err != nil { + b.Error(err) + } + r.Close() + if !bytes.Equal(buffer.Bytes(), content) { + b.Error("read didn't match write") + } + } + }) +} + +func benchmarkWriteReadDelete(b *testing.B, bkt *blob.Bucket) { + b.Helper() + + ctx := context.Background() + const baseKey = "writereaddeletebenchmark-blob-" + + content := loadTestData(b, "test-large.jpg") + var nextID uint32 + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + key := fmt.Sprintf("%s%d", baseKey, atomic.AddUint32(&nextID, 1)) + for pb.Next() { + if err := bkt.WriteAll(ctx, key, content, nil); err != nil { + b.Error(err) + continue + } + buf, err := bkt.ReadAll(ctx, key) + if err != nil { + b.Error(err) + } + if !bytes.Equal(buf, content) { + b.Error("read didn't match write") + } + if err := bkt.Delete(ctx, key); err != nil { + b.Error(err) + continue + } + } + }) +} diff --git a/go-cloud/blob/example_openbucket_test.go b/go-cloud/blob/example_openbucket_test.go new file mode 100644 index 000000000..774100a11 --- /dev/null +++ b/go-cloud/blob/example_openbucket_test.go @@ -0,0 +1,88 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 blob_test + +import ( + "context" + "fmt" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + _ "github.com/DataDog/iceberg-go/go-cloud/blob/memblob" +) + +func Example_openFromURL() { + ctx := context.Background() + + // Connect to a bucket using a URL. + // This example uses "memblob", the in-memory implementation. + // We need to add a blank import line to register the memblob driver's + // URLOpener, which implements blob.BucketURLOpener: + // import _ "gocloud.dev/blob/memblob" + // memblob registers for the "mem" scheme. + // All blob.OpenBucket URLs also work with "blob+" or "blob+bucket+" prefixes, + // e.g., "blob+mem://" or "blob+bucket+mem://". + b, err := blob.OpenBucket(ctx, "mem://") + if err != nil { + log.Fatal(err) + } + defer b.Close() + + // Now we can use b to read or write to blobs in the bucket. + if err := b.WriteAll(ctx, "my-key", []byte("hello world"), nil); err != nil { + log.Fatal(err) + } + data, err := b.ReadAll(ctx, "my-key") + if err != nil { + log.Fatal(err) + } + fmt.Println(string(data)) + // Output: + // hello world +} + +func Example_openFromURLWithPrefix() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Connect to a bucket using a URL, using the "prefix" query parameter to + // target a subfolder in the bucket. + // The prefix should end with "/", so that the resulting bucket operates + // in a subfolder. + b, err := blob.OpenBucket(ctx, "mem://?prefix=a/subfolder/") + if err != nil { + log.Fatal(err) + } + defer b.Close() + + // Bucket operations on will be translated to "a/subfolder/". +} + +func Example_openFromURLWithSingleKey() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Connect to a bucket using a URL, using the "key" query parameter to + // make the bucket always reference that key. + b, err := blob.OpenBucket(ctx, "mem://?key=foo.txt") + if err != nil { + log.Fatal(err) + } + defer b.Close() + + // Bucket operations will ignore the passed-in key and always reference foo.txt. +} diff --git a/go-cloud/blob/example_test.go b/go-cloud/blob/example_test.go new file mode 100644 index 000000000..1a4e14645 --- /dev/null +++ b/go-cloud/blob/example_test.go @@ -0,0 +1,577 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 blob_test + +import ( + "context" + "fmt" + "io" + "log" + "os" + + "cloud.google.com/go/storage" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/fileblob" + _ "github.com/DataDog/iceberg-go/go-cloud/blob/gcsblob" + _ "github.com/DataDog/iceberg-go/go-cloud/blob/s3blob" +) + +func ExampleBucket_NewReader() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var bucket *blob.Bucket + + // Open the key "foo.txt" for reading with the default options. + r, err := bucket.NewReader(ctx, "foo.txt", nil) + if err != nil { + log.Fatal(err) + } + defer r.Close() + // Readers also have a limited view of the blob's metadata. + fmt.Println("Content-Type:", r.ContentType()) + fmt.Println() + // Copy from the reader to stdout. + if _, err := io.Copy(os.Stdout, r); err != nil { + log.Fatal(err) + } +} + +func ExampleBucket_NewRangeReader() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var bucket *blob.Bucket + + // Open the key "foo.txt" for reading at offset 1024 and read up to 4096 bytes. + r, err := bucket.NewRangeReader(ctx, "foo.txt", 1024, 4096, nil) + if err != nil { + log.Fatal(err) + } + defer r.Close() + // Copy from the read range to stdout. + if _, err := io.Copy(os.Stdout, r); err != nil { + log.Fatal(err) + } +} + +func ExampleBucket_NewWriter() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var bucket *blob.Bucket + + // Open the key "foo.txt" for writing with the default options. + w, err := bucket.NewWriter(ctx, "foo.txt", nil) + if err != nil { + log.Fatal(err) + } + _, writeErr := fmt.Fprintln(w, "Hello, World!") + // Always check the return value of Close when writing. + closeErr := w.Close() + if writeErr != nil { + log.Fatal(writeErr) + } + if closeErr != nil { + log.Fatal(closeErr) + } +} + +func ExampleBucket_NewWriter_cancel() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var bucket *blob.Bucket + + // Create a cancelable context from the existing context. + writeCtx, cancelWrite := context.WithCancel(ctx) + defer cancelWrite() + + // Open the key "foo.txt" for writing with the default options. + w, err := bucket.NewWriter(writeCtx, "foo.txt", nil) + if err != nil { + log.Fatal(err) + } + + // Assume some writes happened and we encountered an error. + // Now we want to abort the write. + + if err != nil { + // First cancel the context. + cancelWrite() + // You must still close the writer to avoid leaking resources. + w.Close() + } +} + +func ExampleBucket_Delete() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var bucket *blob.Bucket + + if err := bucket.Delete(ctx, "foo.txt"); err != nil { + log.Fatal(err) + } +} + +func Example() { + // Connect to a bucket when your program starts up. + // This example uses the file-based implementation in fileblob, and creates + // a temporary directory to use as the root directory. + dir, cleanup := newTempDir() + defer cleanup() + bucket, err := fileblob.OpenBucket(dir, nil) + if err != nil { + log.Fatal(err) + } + defer bucket.Close() + + // We now have a *blob.Bucket! We can write our application using the + // *blob.Bucket type, and have the freedom to change the initialization code + // above to choose a different service-specific driver later. + + // In this example, we'll write a blob and then read it. + ctx := context.Background() + if err := bucket.WriteAll(ctx, "foo.txt", []byte("Go Cloud Development Kit"), nil); err != nil { + log.Fatal(err) + } + b, err := bucket.ReadAll(ctx, "foo.txt") + if err != nil { + log.Fatal(err) + } + fmt.Println(string(b)) + + // Output: + // Go Cloud Development Kit +} + +func ExampleBucket_ErrorAs() { + // This example is specific to the s3blob implementation; it demonstrates + // access to the underlying awserr.Error type. + // The types exposed for ErrorAs by s3blob are documented in + // https://godoc.org/gocloud.dev/blob/s3blob#hdr-As + + ctx := context.Background() + + b, err := blob.OpenBucket(ctx, "s3://my-bucket") + if err != nil { + log.Fatal(err) + } + defer b.Close() + + _, err = b.ReadAll(ctx, "nosuchfile") + if err != nil { + var awsErr awserr.Error + if b.ErrorAs(err, &awsErr) { + fmt.Println(awsErr.Code()) + } + } +} + +func ExampleBucket_List() { + // Connect to a bucket when your program starts up. + // This example uses the file-based implementation. + dir, cleanup := newTempDir() + defer cleanup() + + // Create the file-based bucket. + bucket, err := fileblob.OpenBucket(dir, nil) + if err != nil { + log.Fatal(err) + } + defer bucket.Close() + + // Create some blob objects for listing: "foo[0..4].txt". + ctx := context.Background() + for i := 0; i < 5; i++ { + if err := bucket.WriteAll(ctx, fmt.Sprintf("foo%d.txt", i), []byte("Go Cloud Development Kit"), nil); err != nil { + log.Fatal(err) + } + } + + // Iterate over them. + // This will list the blobs created above because fileblob is strongly + // consistent, but is not guaranteed to work on all services. + iter := bucket.List(nil) + for { + obj, err := iter.Next(ctx) + if err == io.EOF { + break + } + if err != nil { + log.Fatal(err) + } + fmt.Println(obj.Key) + } + + // Output: + // foo0.txt + // foo1.txt + // foo2.txt + // foo3.txt + // foo4.txt +} + +func ExampleBucket_List_withDelimiter() { + // Connect to a bucket when your program starts up. + // This example uses the file-based implementation. + dir, cleanup := newTempDir() + defer cleanup() + + // Create the file-based bucket. + bucket, err := fileblob.OpenBucket(dir, nil) + if err != nil { + log.Fatal(err) + } + defer bucket.Close() + + // Create some blob objects in a hierarchy. + ctx := context.Background() + for _, key := range []string{ + "dir1/subdir/a.txt", + "dir1/subdir/b.txt", + "dir2/c.txt", + "d.txt", + } { + if err := bucket.WriteAll(ctx, key, []byte("Go Cloud Development Kit"), nil); err != nil { + log.Fatal(err) + } + } + + // list lists files in b starting with prefix. It uses the delimiter "/", + // and recurses into "directories", adding 2 spaces to indent each time. + // It will list the blobs created above because fileblob is strongly + // consistent, but is not guaranteed to work on all services. + var list func(context.Context, *blob.Bucket, string, string) + list = func(ctx context.Context, b *blob.Bucket, prefix, indent string) { + iter := b.List(&blob.ListOptions{ + Delimiter: "/", + Prefix: prefix, + }) + for { + obj, err := iter.Next(ctx) + if err == io.EOF { + break + } + if err != nil { + log.Fatal(err) + } + fmt.Printf("%s%s\n", indent, obj.Key) + if obj.IsDir { + list(ctx, b, obj.Key, indent+" ") + } + } + } + list(ctx, bucket, "", "") + + // Output: + // d.txt + // dir1/ + // dir1/subdir/ + // dir1/subdir/a.txt + // dir1/subdir/b.txt + // dir2/ + // dir2/c.txt +} + +func ExampleBucket_ListPage() { + // Connect to a bucket when your program starts up. + // This example uses the file-based implementation. + dir, cleanup := newTempDir() + defer cleanup() + + // Create the file-based bucket. + bucket, err := fileblob.OpenBucket(dir, nil) + if err != nil { + log.Fatal(err) + } + defer bucket.Close() + + // Create some blob objects for listing: "foo[0..7].txt". + ctx := context.Background() + for i := 0; i < 8; i++ { + if err := bucket.WriteAll(ctx, fmt.Sprintf("foo%d.txt", i), []byte("Go Cloud Development Kit"), nil); err != nil { + log.Fatal(err) + } + } + + // Iterate over them in pages. + // This will list the blobs created above because fileblob is strongly + // consistent, but is not guaranteed to work on all services. + + // The first page of 3 results. + objs, token, err := bucket.ListPage(ctx, blob.FirstPageToken, 3, nil) + if err != nil { + log.Fatal(err) + } + for _, obj := range objs { + fmt.Println(obj.Key) + } + fmt.Println("END OF PAGE 1") + + // The second page of 3 results. + objs, token, err = bucket.ListPage(ctx, token, 3, nil) + if err != nil { + log.Fatal(err) + } + for _, obj := range objs { + fmt.Println(obj.Key) + } + fmt.Println("END OF PAGE 2") + + // The third page with the last 2 results. + objs, token, err = bucket.ListPage(ctx, token, 3, nil) + if err != nil { + log.Fatal(err) + } + for _, obj := range objs { + fmt.Println(obj.Key) + } + fmt.Println("END OF PAGE 3") + + // There are no more pages, so token is now nil. Calling ListPage again will return io.EOF. + if token != nil { + fmt.Println("Token was not nil.") + } + + // Output: + // foo0.txt + // foo1.txt + // foo2.txt + // END OF PAGE 1 + // foo3.txt + // foo4.txt + // foo5.txt + // END OF PAGE 2 + // foo6.txt + // foo7.txt + // END OF PAGE 3 +} + +func ExampleBucket_As() { + // This example is specific to the gcsblob implementation; it demonstrates + // access to the underlying cloud.google.com/go/storage.Client type. + // The types exposed for As by gcsblob are documented in + // https://godoc.org/gocloud.dev/blob/gcsblob#hdr-As + + // This URL will open the bucket "my-bucket" using default credentials. + ctx := context.Background() + b, err := blob.OpenBucket(ctx, "gs://my-bucket") + if err != nil { + log.Fatal(err) + } + defer b.Close() + + // Access storage.Client fields via gcsClient here. + var gcsClient *storage.Client + if b.As(&gcsClient) { + email, err := gcsClient.ServiceAccount(ctx, "project-name") + if err != nil { + log.Fatal(err) + } + _ = email + } else { + log.Println("Unable to access storage.Client through Bucket.As") + } +} + +func ExampleWriterOptions() { + // This example is specific to the gcsblob implementation; it demonstrates + // access to the underlying cloud.google.com/go/storage.Writer type. + // The types exposed for As by gcsblob are documented in + // https://godoc.org/gocloud.dev/blob/gcsblob#hdr-As + + ctx := context.Background() + + b, err := blob.OpenBucket(ctx, "gs://my-bucket") + if err != nil { + log.Fatal(err) + } + defer b.Close() + + beforeWrite := func(as func(any) bool) error { + var sw *storage.Writer + if as(&sw) { + fmt.Println(sw.ChunkSize) + } + return nil + } + + options := blob.WriterOptions{BeforeWrite: beforeWrite} + if err := b.WriteAll(ctx, "newfile.txt", []byte("hello\n"), &options); err != nil { + log.Fatal(err) + } +} + +func ExampleListObject_As() { + // This example is specific to the gcsblob implementation; it demonstrates + // access to the underlying cloud.google.com/go/storage.ObjectAttrs type. + // The types exposed for As by gcsblob are documented in + // https://godoc.org/gocloud.dev/blob/gcsblob#hdr-As + + ctx := context.Background() + + b, err := blob.OpenBucket(ctx, "gs://my-bucket") + if err != nil { + log.Fatal(err) + } + defer b.Close() + + iter := b.List(nil) + for { + obj, err := iter.Next(ctx) + if err == io.EOF { + break + } + if err != nil { + log.Fatal(err) + } + // Access storage.ObjectAttrs via oa here. + var oa storage.ObjectAttrs + if obj.As(&oa) { + _ = oa.Owner + } + } +} + +func ExampleListOptions() { + // This example is specific to the gcsblob implementation; it demonstrates + // access to the underlying cloud.google.com/go/storage.Query type. + // The types exposed for As by gcsblob are documented in + // https://godoc.org/gocloud.dev/blob/gcsblob#hdr-As + + ctx := context.Background() + + b, err := blob.OpenBucket(ctx, "gs://my-bucket") + if err != nil { + log.Fatal(err) + } + defer b.Close() + + beforeList := func(as func(any) bool) error { + // Access storage.Query via q here. + var q *storage.Query + if as(&q) { + _ = q.Delimiter + } + return nil + } + + iter := b.List(&blob.ListOptions{Prefix: "", Delimiter: "/", BeforeList: beforeList}) + for { + obj, err := iter.Next(ctx) + if err == io.EOF { + break + } + if err != nil { + log.Fatal(err) + } + _ = obj + } +} + +func ExamplePrefixedBucket() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + var bucket *blob.Bucket + + // Wrap the bucket using blob.PrefixedBucket. + // The prefix should end with "/", so that the resulting bucket operates + // in a subfolder. + bucket = blob.PrefixedBucket(bucket, "a/subfolder/") + + // The original bucket is no longer usable; it has been closed. + // The wrapped bucket should be closed when done. + defer bucket.Close() + + // Bucket operations on will be translated to "a/subfolder/". +} + +func ExampleSingleKeyBucket() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + var bucket *blob.Bucket + + // Wrap the bucket using blob.SingleKeyBucket. + // The bucket always references the provided key. + bucket = blob.SingleKeyBucket(bucket, "foo.txt") + + // The original bucket is no longer usable; it has been closed. + // The wrapped bucket should be closed when done. + defer bucket.Close() + + // Bucket operations will ignore the passed-in key and always reference foo.txt. +} + +func ExampleReader_As() { + // This example is specific to the gcsblob implementation; it demonstrates + // access to the underlying cloud.google.com/go/storage.Reader type. + // The types exposed for As by gcsblob are documented in + // https://godoc.org/gocloud.dev/blob/gcsblob#hdr-As + + ctx := context.Background() + + b, err := blob.OpenBucket(ctx, "gs://my-bucket") + if err != nil { + log.Fatal(err) + } + defer b.Close() + + r, err := b.NewReader(ctx, "gopher.png", nil) + if err != nil { + log.Fatal(err) + } + defer r.Close() + + // Access storage.Reader via sr here. + var sr *storage.Reader + if r.As(&sr) { + _ = sr.Attrs + } +} + +func ExampleAttributes_As() { + // This example is specific to the gcsblob implementation; it demonstrates + // access to the underlying cloud.google.com/go/storage.ObjectAttrs type. + // The types exposed for As by gcsblob are documented in + // https://godoc.org/gocloud.dev/blob/gcsblob#hdr-As + ctx := context.Background() + + b, err := blob.OpenBucket(ctx, "gs://my-bucket") + if err != nil { + log.Fatal(err) + } + defer b.Close() + + attrs, err := b.Attributes(ctx, "gopher.png") + if err != nil { + log.Fatal(err) + } + + var oa storage.ObjectAttrs + if attrs.As(&oa) { + fmt.Println(oa.Owner) + } +} + +func newTempDir() (string, func()) { + dir, err := os.MkdirTemp("", "go-cloud-blob-example") + if err != nil { + panic(err) + } + return dir, func() { os.RemoveAll(dir) } +} diff --git a/go-cloud/blob/fileblob/attrs.go b/go-cloud/blob/fileblob/attrs.go new file mode 100644 index 000000000..1f8c84428 --- /dev/null +++ b/go-cloud/blob/fileblob/attrs.go @@ -0,0 +1,75 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 fileblob + +import ( + "encoding/json" + "fmt" + "os" +) + +const attrsExt = ".attrs" + +var errAttrsExt = fmt.Errorf("file extension %q is reserved", attrsExt) + +// xattrs stores extended attributes for an object. The format is like +// filesystem extended attributes, see +// https://www.freedesktop.org/wiki/CommonExtendedAttributes. +type xattrs struct { + CacheControl string `json:"user.cache_control"` + ContentDisposition string `json:"user.content_disposition"` + ContentEncoding string `json:"user.content_encoding"` + ContentLanguage string `json:"user.content_language"` + ContentType string `json:"user.content_type"` + Metadata map[string]string `json:"user.metadata"` + MD5 []byte `json:"md5"` +} + +// setAttrs creates a "path.attrs" file along with blob to store the attributes, +// it uses JSON format. +func setAttrs(path string, xa xattrs) error { + f, err := os.Create(path + attrsExt) + if err != nil { + return err + } + if err := json.NewEncoder(f).Encode(xa); err != nil { + f.Close() + os.Remove(f.Name()) + return err + } + return f.Close() +} + +// getAttrs looks at the "path.attrs" file to retrieve the attributes and +// decodes them into a xattrs struct. It doesn't return error when there is no +// such .attrs file. +func getAttrs(path string) (xattrs, error) { + f, err := os.Open(path + attrsExt) + if err != nil { + if os.IsNotExist(err) { + // Handle gracefully for non-existent .attr files. + return xattrs{ + ContentType: "application/octet-stream", + }, nil + } + return xattrs{}, err + } + xa := new(xattrs) + if err := json.NewDecoder(f).Decode(xa); err != nil { + f.Close() + return xattrs{}, err + } + return *xa, f.Close() +} diff --git a/go-cloud/blob/fileblob/example_test.go b/go-cloud/blob/fileblob/example_test.go new file mode 100644 index 000000000..5b5db67ce --- /dev/null +++ b/go-cloud/blob/fileblob/example_test.go @@ -0,0 +1,82 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 fileblob_test + +import ( + "context" + "fmt" + "log" + "os" + "path/filepath" + "strings" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/fileblob" +) + +func ExampleOpenBucket() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // The directory you pass to fileblob.OpenBucket must exist first. + const myDir = "path/to/local/directory" + if err := os.MkdirAll(myDir, 0o777); err != nil { + log.Fatal(err) + } + + // Create a file-based bucket. + bucket, err := fileblob.OpenBucket(myDir, nil) + if err != nil { + log.Fatal(err) + } + defer bucket.Close() +} + +func Example_openBucketFromURL() { + // Create a temporary directory. + dir, err := os.MkdirTemp("", "go-cloud-fileblob-example") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(dir) + + // On Unix, append the dir to "file://". + // On Windows, convert "\" to "/" and add a leading "/": + dirpath := filepath.ToSlash(dir) + if os.PathSeparator != '/' && !strings.HasPrefix(dirpath, "/") { + dirpath = "/" + dirpath + } + + // blob.OpenBucket creates a *blob.Bucket from a URL. + ctx := context.Background() + b, err := blob.OpenBucket(ctx, "file://"+dirpath) + if err != nil { + log.Fatal(err) + } + defer b.Close() + + // Now we can use b to read or write files to the container. + err = b.WriteAll(ctx, "my-key", []byte("hello world"), nil) + if err != nil { + log.Fatal(err) + } + data, err := b.ReadAll(ctx, "my-key") + if err != nil { + log.Fatal(err) + } + fmt.Println(string(data)) + + // Output: + // hello world +} diff --git a/go-cloud/blob/fileblob/fileblob.go b/go-cloud/blob/fileblob/fileblob.go new file mode 100644 index 000000000..91b236166 --- /dev/null +++ b/go-cloud/blob/fileblob/fileblob.go @@ -0,0 +1,1062 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 fileblob provides a blob implementation that uses the filesystem. +// Use OpenBucket to construct a *blob.Bucket. +// +// To avoid partial writes, fileblob writes to a temporary file and then renames +// the temporary file to the final path on Close. By default, it creates these +// temporary files in `os.TempDir`. If `os.TempDir` is on a different mount than +// your base bucket path, the `os.Rename` will fail with `invalid cross-device link`. +// To avoid this, either configure the temp dir to use by setting the environment +// variable `TMPDIR`, or set `Options.NoTempDir` to `true` (fileblob will create +// the temporary files next to the actual files instead of in a temporary directory). +// +// By default fileblob stores blob metadata in "sidecar" files under the original +// filename with an additional ".attrs" suffix. +// This behaviour can be changed via `Options.Metadata`; +// writing of those metadata files can be suppressed by setting it to +// `MetadataDontWrite` or its equivalent "metadata=skip" in the URL for the opener. +// In either case, absent any stored metadata many `blob.Attributes` fields +// will be set to default values. +// +// # URLs +// +// For blob.OpenBucket, fileblob registers for the scheme "file". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # Escaping +// +// Go CDK supports all UTF-8 strings; to make this work with services lacking +// full UTF-8 support, strings must be escaped (during writes) and unescaped +// (during reads). The following escapes are performed for fileblob: +// - Blob keys: ASCII characters 0-31 are escaped to "__0x__". +// If os.PathSeparator != "/", it is also escaped. +// Additionally, the "/" in "../", the trailing "/" in "//", and a trailing +// "/" is key names are escaped in the same way. +// On Windows, the characters "<>:"|?*" are also escaped. +// +// # As +// +// fileblob exposes the following types for As: +// - Bucket: os.FileInfo +// - Error: *os.PathError +// - ListObject: os.FileInfo +// - Reader: io.Reader +// - ReaderOptions.BeforeRead: *os.File +// - Attributes: os.FileInfo +// - CopyOptions.BeforeCopy: *os.File +// - WriterOptions.BeforeWrite: *os.File +package fileblob // import "gocloud.dev/blob/fileblob" + +import ( + "context" + "crypto/hmac" + "crypto/md5" + "crypto/sha256" + "encoding/base64" + "errors" + "fmt" + "hash" + "io" + "io/fs" + "net/url" + "os" + "path/filepath" + "strconv" + "strings" + "sync" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/escape" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +const defaultPageSize = 1000 + +func init() { + blob.DefaultURLMux().RegisterBucket(Scheme, &URLOpener{}) +} + +// Scheme is the URL scheme fileblob registers its URLOpener under on +// blob.DefaultMux. +const Scheme = "file" + +// URLOpener opens file bucket URLs like "file:///foo/bar/baz". +// +// The URL's host is ignored unless it is ".", which is used to signal a +// relative path. For example, "file://./../.." uses "../.." as the path. +// +// If os.PathSeparator != "/", any leading "/" from the path is dropped +// and remaining '/' characters are converted to os.PathSeparator. +// +// The following query parameters are supported: +// +// - create_dir: (any non-empty value) the directory is created (using os.MkDirAll) +// if it does not already exist. +// - dir_file_mode: any directories that are created (the base directory when create_dir +// is true, or subdirectories for keys) are created using this os.FileMode, parsed +// using os.Parseuint. Defaults to 0777. +// - no_tmp_dir: (any non-empty value) temporary files are created next to the final +// path instead of in os.TempDir. +// - base_url: the base URL to use to construct signed URLs; see URLSignerHMAC +// - secret_key_path: path to read for the secret key used to construct signed URLs; +// see URLSignerHMAC +// - metadata: if set to "skip", won't write metadata such as blob.Attributes +// as per the package docstring +// +// If either of base_url / secret_key_path are provided, both must be. +// +// - file:///a/directory +// -> Passes "/a/directory" to OpenBucket. +// - file://localhost/a/directory +// -> Also passes "/a/directory". +// - file://./../.. +// -> The hostname is ".", signaling a relative path; passes "../..". +// - file:///c:/foo/bar on Windows. +// -> Passes "c:\foo\bar". +// - file://localhost/c:/foo/bar on Windows. +// -> Also passes "c:\foo\bar". +// - file:///a/directory?base_url=/show&secret_key_path=secret.key +// -> Passes "/a/directory" to OpenBucket, and sets Options.URLSigner +// to a URLSignerHMAC initialized with base URL "/show" and secret key +// bytes read from the file "secret.key". +type URLOpener struct { + // Options specifies the default options to pass to OpenBucket. + Options Options +} + +// OpenBucketURL opens a blob.Bucket based on u. +func (o *URLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) { + path := u.Path + // Hostname == "." means a relative path, so drop the leading "/". + // Also drop the leading "/" on Windows. + if u.Host == "." || os.PathSeparator != '/' { + path = strings.TrimPrefix(path, "/") + } + opts, err := o.forParams(ctx, u.Query()) + if err != nil { + return nil, fmt.Errorf("open bucket %v: %v", u, err) + } + return OpenBucket(filepath.FromSlash(path), opts) +} + +var recognizedParams = map[string]bool{ + "create_dir": true, + "base_url": true, + "secret_key_path": true, + "metadata": true, + "no_tmp_dir": true, + "dir_file_mode": true, +} + +type metadataOption string // Not exported as subject to change. + +// Settings for Options.Metadata. +const ( + // Metadata gets written to a separate file. + MetadataInSidecar metadataOption = "" + // Writes won't carry metadata, as per the package docstring. + MetadataDontWrite metadataOption = "skip" +) + +func (o *URLOpener) forParams(ctx context.Context, q url.Values) (*Options, error) { + for k := range q { + if _, ok := recognizedParams[k]; !ok { + return nil, fmt.Errorf("invalid query parameter %q", k) + } + } + opts := new(Options) + *opts = o.Options + + // Note: can't just use q.Get, because then we can't distinguish between + // "not set" (we should leave opts alone) vs "set to empty string" (which is + // one of the legal values, we should override opts). + metadataVal := q["metadata"] + if len(metadataVal) > 0 { + switch metadataOption(metadataVal[0]) { + case MetadataDontWrite: + opts.Metadata = MetadataDontWrite + case MetadataInSidecar: + opts.Metadata = MetadataInSidecar + default: + return nil, errors.New("fileblob.OpenBucket: unsupported value for query parameter 'metadata'") + } + } + if q.Get("create_dir") != "" { + opts.CreateDir = true + } + if fms := q.Get("dir_file_mode"); fms != "" { + fm, err := strconv.ParseUint(fms, 10, 32) + if err != nil { + return nil, fmt.Errorf("fileblob.OpenBucket: invalid dir_file_mode %q: %v", fms, err) + } + opts.DirFileMode = os.FileMode(fm) + } + if q.Get("no_tmp_dir") != "" { + opts.NoTempDir = true + } + baseURL := q.Get("base_url") + keyPath := q.Get("secret_key_path") + if (baseURL == "") != (keyPath == "") { + return nil, errors.New("fileblob.OpenBucket: must supply both base_url and secret_key_path query parameters") + } + if baseURL != "" { + burl, err := url.Parse(baseURL) + if err != nil { + return nil, err + } + sk, err := os.ReadFile(keyPath) + if err != nil { + return nil, err + } + opts.URLSigner = NewURLSignerHMAC(burl, sk) + } + return opts, nil +} + +// Options sets options for constructing a *blob.Bucket backed by fileblob. +type Options struct { + // URLSigner implements signing URLs (to allow access to a resource without + // further authorization) and verifying that a given URL is unexpired and + // contains a signature produced by the URLSigner. + // URLSigner is only required for utilizing the SignedURL API. + URLSigner URLSigner + + // If true, create the directory backing the Bucket if it does not exist + // (using os.MkdirAll). + CreateDir bool + + // The FileMode to use when creating directories for the top-level directory + // backing the bucket (when CreateDir is true), and for subdirectories for keys. + // Defaults to 0777. + DirFileMode os.FileMode + + // If true, don't use os.TempDir for temporary files, but instead place them + // next to the actual files. This may result in "stranded" temporary files + // (e.g., if the application is killed before the file cleanup runs). + // + // If your bucket directory is on a different mount than os.TempDir, you will + // need to set this to true, as os.Rename will fail across mount points. + NoTempDir bool + + // Refers to the strategy for how to deal with metadata (such as blob.Attributes). + // For supported values please see the Metadata* constants. + // If left unchanged, 'MetadataInSidecar' will be used. + Metadata metadataOption +} + +type bucket struct { + dir string + opts *Options +} + +// openBucket creates a driver.Bucket that reads and writes to dir. +// dir must exist. +func openBucket(dir string, opts *Options) (driver.Bucket, error) { + if opts == nil { + opts = &Options{} + } + if opts.DirFileMode == 0 { + opts.DirFileMode = os.FileMode(0o777) + } + + absdir, err := filepath.Abs(dir) + if err != nil { + return nil, fmt.Errorf("failed to convert %s into an absolute path: %v", dir, err) + } + info, err := os.Stat(absdir) + + // Optionally, create the directory if it does not already exist. + if err != nil && opts.CreateDir && os.IsNotExist(err) { + err = os.MkdirAll(absdir, opts.DirFileMode) + if err != nil { + return nil, fmt.Errorf("tried to create directory but failed: %v", err) + } + info, err = os.Stat(absdir) + } + if err != nil { + return nil, err + } + if !info.IsDir() { + return nil, fmt.Errorf("%s is not a directory", absdir) + } + return &bucket{dir: absdir, opts: opts}, nil +} + +// OpenBucket creates a *blob.Bucket backed by the filesystem and rooted at +// dir, which must exist. See the package documentation for an example. +func OpenBucket(dir string, opts *Options) (*blob.Bucket, error) { + drv, err := openBucket(dir, opts) + if err != nil { + return nil, err + } + return blob.NewBucket(drv), nil +} + +func (b *bucket) Close() error { + return nil +} + +// escapeKey does all required escaping for UTF-8 strings to work the filesystem. +func escapeKey(s string) string { + s = escape.HexEscape(s, func(r []rune, i int) bool { + c := r[i] + switch { + case c < 32: + return true + // We're going to replace '/' with os.PathSeparator below. In order for this + // to be reversible, we need to escape raw os.PathSeparators. + case os.PathSeparator != '/' && c == os.PathSeparator: + return true + // For "../", escape the trailing slash. + case i > 1 && c == '/' && r[i-1] == '.' && r[i-2] == '.': + return true + // For "//", escape the trailing slash. + case i > 0 && c == '/' && r[i-1] == '/': + return true + // Escape the trailing slash in a key. + case c == '/' && i == len(r)-1: + return true + // https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file + case os.PathSeparator == '\\' && (c == '>' || c == '<' || c == ':' || c == '"' || c == '|' || c == '?' || c == '*'): + return true + } + return false + }) + // Replace "/" with os.PathSeparator if needed, so that the local filesystem + // can use subdirectories. + if os.PathSeparator != '/' { + s = strings.Replace(s, "/", string(os.PathSeparator), -1) + } + return s +} + +// unescapeKey reverses escapeKey. +func unescapeKey(s string) string { + if os.PathSeparator != '/' { + s = strings.Replace(s, string(os.PathSeparator), "/", -1) + } + s = escape.HexUnescape(s) + return s +} + +func (b *bucket) ErrorCode(err error) gcerrors.ErrorCode { + switch { + case os.IsNotExist(err): + return gcerrors.NotFound + default: + return gcerrors.Unknown + } +} + +// path returns the full path for a key +func (b *bucket) path(key string) (string, error) { + path := filepath.Join(b.dir, escapeKey(key)) + if strings.HasSuffix(path, attrsExt) { + return "", errAttrsExt + } + return path, nil +} + +// forKey returns the full path, os.FileInfo, and attributes for key. +func (b *bucket) forKey(key string) (string, os.FileInfo, *xattrs, error) { + path, err := b.path(key) + if err != nil { + return "", nil, nil, err + } + info, err := os.Stat(path) + if err != nil { + return "", nil, nil, err + } + if info.IsDir() { + return "", nil, nil, os.ErrNotExist + } + xa, err := getAttrs(path) + if err != nil { + return "", nil, nil, err + } + return path, info, &xa, nil +} + +// ListPaged implements driver.ListPaged. +func (b *bucket) ListPaged(ctx context.Context, opts *driver.ListOptions) (*driver.ListPage, error) { + var pageToken string + if len(opts.PageToken) > 0 { + pageToken = string(opts.PageToken) + } + pageSize := opts.PageSize + if pageSize == 0 { + pageSize = defaultPageSize + } + // If opts.Delimiter != "", lastPrefix contains the last "directory" key we + // added. It is used to avoid adding it again; all files in this "directory" + // are collapsed to the single directory entry. + var lastPrefix string + var lastKeyAdded string + + // If the Prefix contains a "/", we can set the root of the Walk + // to the path specified by the Prefix as any files below the path will not + // match the Prefix. + // Note that we use "/" explicitly and not os.PathSeparator, as the opts.Prefix + // is in the unescaped form. + root := b.dir + if i := strings.LastIndex(opts.Prefix, "/"); i > -1 { + root = filepath.Join(root, opts.Prefix[:i]) + } + + // Do a full recursive scan of the root directory. + var result driver.ListPage + err := filepath.WalkDir(root, func(path string, info fs.DirEntry, err error) error { + if err != nil { + // Couldn't read this file/directory for some reason; just skip it. + return nil + } + // Skip the self-generated attribute files. + if strings.HasSuffix(path, attrsExt) { + return nil + } + // os.Walk returns the root directory; skip it. + if path == b.dir { + return nil + } + // Strip the prefix from path. + prefixLen := len(b.dir) + // Include the separator for non-root. + if b.dir != "/" { + prefixLen++ + } + path = path[prefixLen:] + // Unescape the path to get the key. + key := unescapeKey(path) + // Skip all directories. If opts.Delimiter is set, we'll create + // pseudo-directories later. + // Note that returning nil means that we'll still recurse into it; + // we're just not adding a result for the directory itself. + if info.IsDir() { + key += "/" + // Avoid recursing into subdirectories if the directory name already + // doesn't match the prefix; any files in it are guaranteed not to match. + if len(key) > len(opts.Prefix) && !strings.HasPrefix(key, opts.Prefix) { + return filepath.SkipDir + } + // Similarly, avoid recursing into subdirectories if we're making + // "directories" and all of the files in this subdirectory are guaranteed + // to collapse to a "directory" that we've already added. + if lastPrefix != "" && strings.HasPrefix(key, lastPrefix) { + return filepath.SkipDir + } + return nil + } + // Skip files/directories that don't match the Prefix. + if !strings.HasPrefix(key, opts.Prefix) { + return nil + } + var md5 []byte + if xa, err := getAttrs(path); err == nil { + // Note: we only have the MD5 hash for blobs that we wrote. + // For other blobs, md5 will remain nil. + md5 = xa.MD5 + } + fi, err := info.Info() + if err != nil { + return err + } + asFunc := func(i any) bool { + p, ok := i.(*os.FileInfo) + if !ok { + return false + } + *p = fi + return true + } + obj := &driver.ListObject{ + Key: key, + ModTime: fi.ModTime(), + Size: fi.Size(), + MD5: md5, + AsFunc: asFunc, + } + // If using Delimiter, collapse "directories". + if opts.Delimiter != "" { + // Strip the prefix, which may contain Delimiter. + keyWithoutPrefix := key[len(opts.Prefix):] + // See if the key still contains Delimiter. + // If no, it's a file and we just include it. + // If yes, it's a file in a "sub-directory" and we want to collapse + // all files in that "sub-directory" into a single "directory" result. + if idx := strings.Index(keyWithoutPrefix, opts.Delimiter); idx != -1 { + prefix := opts.Prefix + keyWithoutPrefix[0:idx+len(opts.Delimiter)] + // We've already included this "directory"; don't add it. + if prefix == lastPrefix { + return nil + } + // Update the object to be a "directory". + obj = &driver.ListObject{ + Key: prefix, + IsDir: true, + AsFunc: asFunc, + } + lastPrefix = prefix + } + } + // If there's a pageToken, skip anything before it. + if pageToken != "" && obj.Key <= pageToken { + return nil + } + // If we've already got a full page of results, set NextPageToken and stop. + // Unless the current object is a directory, in which case there may + // still be objects coming that are alphabetically before it (since + // we appended the delimiter). In that case, keep going; we'll trim the + // extra entries (if any) before returning. + if len(result.Objects) == pageSize && !obj.IsDir { + result.NextPageToken = []byte(result.Objects[pageSize-1].Key) + return io.EOF + } + result.Objects = append(result.Objects, obj) + // Normally, objects are added in the correct order (by Key). + // However, sometimes adding the file delimiter messes that up (e.g., + // if the file delimiter is later in the alphabet than the last character + // of a key). + // Detect if this happens and swap if needed. + if len(result.Objects) > 1 && obj.Key < lastKeyAdded { + i := len(result.Objects) - 1 + result.Objects[i-1], result.Objects[i] = result.Objects[i], result.Objects[i-1] + lastKeyAdded = result.Objects[i].Key + } else { + lastKeyAdded = obj.Key + } + return nil + }) + if err != nil && err != io.EOF { + return nil, err + } + if len(result.Objects) > pageSize { + result.Objects = result.Objects[0:pageSize] + result.NextPageToken = []byte(result.Objects[pageSize-1].Key) + } + return &result, nil +} + +// As implements driver.As. +func (b *bucket) As(i any) bool { + p, ok := i.(*os.FileInfo) + if !ok { + return false + } + fi, err := os.Stat(b.dir) + if err != nil { + return false + } + *p = fi + return true +} + +// As implements driver.ErrorAs. +func (b *bucket) ErrorAs(err error, i any) bool { + if perr, ok := err.(*os.PathError); ok { + if p, ok := i.(**os.PathError); ok { + *p = perr + return true + } + } + return false +} + +// Attributes implements driver.Attributes. +func (b *bucket) Attributes(ctx context.Context, key string) (*driver.Attributes, error) { + _, info, xa, err := b.forKey(key) + if err != nil { + return nil, err + } + return &driver.Attributes{ + CacheControl: xa.CacheControl, + ContentDisposition: xa.ContentDisposition, + ContentEncoding: xa.ContentEncoding, + ContentLanguage: xa.ContentLanguage, + ContentType: xa.ContentType, + Metadata: xa.Metadata, + // CreateTime left as the zero time. + ModTime: info.ModTime(), + Size: info.Size(), + MD5: xa.MD5, + ETag: fmt.Sprintf("\"%x-%x\"", info.ModTime().UnixNano(), info.Size()), + AsFunc: func(i any) bool { + p, ok := i.(*os.FileInfo) + if !ok { + return false + } + *p = info + return true + }, + }, nil +} + +// NewRangeReader implements driver.NewRangeReader. +func (b *bucket) NewRangeReader(ctx context.Context, key string, offset, length int64, opts *driver.ReaderOptions) (driver.Reader, error) { + path, info, xa, err := b.forKey(key) + if err != nil { + return nil, err + } + f, err := os.Open(path) + if err != nil { + return nil, err + } + if opts.BeforeRead != nil { + if err := opts.BeforeRead(func(i any) bool { + p, ok := i.(**os.File) + if !ok { + return false + } + *p = f + return true + }); err != nil { + return nil, err + } + } + if offset > 0 { + if _, err := f.Seek(offset, io.SeekStart); err != nil { + return nil, err + } + } + r := io.Reader(f) + if length >= 0 { + r = io.LimitReader(r, length) + } + return &reader{ + r: r, + c: f, + attrs: driver.ReaderAttributes{ + ContentType: xa.ContentType, + ModTime: info.ModTime(), + Size: info.Size(), + }, + }, nil +} + +type reader struct { + r io.Reader + c io.Closer + attrs driver.ReaderAttributes +} + +func (r *reader) Read(p []byte) (int, error) { + if r.r == nil { + return 0, io.EOF + } + return r.r.Read(p) +} + +func (r *reader) Close() error { + if r.c == nil { + return nil + } + return r.c.Close() +} + +func (r *reader) Attributes() *driver.ReaderAttributes { + return &r.attrs +} + +func (r *reader) As(i any) bool { + p, ok := i.(*io.Reader) + if !ok { + return false + } + *p = r.r + return true +} + +func createTemp(path string, noTempDir bool) (*os.File, error) { + // Use a custom createTemp function rather than os.CreateTemp() as + // os.CreateTemp() sets the permissions of the tempfile to 0600, rather than + // 0666, making it inconsistent with the directories and attribute files. + try := 0 + for { + // Append the current time with nanosecond precision and .tmp to the + // base path. If the file already exists try again. Nanosecond changes enough + // between each iteration to make a conflict unlikely. Using the full + // time lowers the chance of a collision with a file using a similar + // pattern, but has undefined behavior after the year 2262. + var name string + if noTempDir { + name = path + } else { + name = filepath.Join(os.TempDir(), filepath.Base(path)) + } + name += "." + strconv.FormatInt(time.Now().UnixNano(), 16) + ".tmp" + f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o666) + if os.IsExist(err) { + if try++; try < 10000 { + continue + } + return nil, &os.PathError{Op: "createtemp", Path: path + ".*.tmp", Err: os.ErrExist} + } + return f, err + } +} + +// NewTypedWriter implements driver.NewTypedWriter. +func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType string, opts *driver.WriterOptions) (driver.Writer, error) { + path, err := b.path(key) + if err != nil { + return nil, err + } + if err := os.MkdirAll(filepath.Dir(path), b.opts.DirFileMode); err != nil { + return nil, err + } + f, err := createTemp(path, b.opts.NoTempDir) + if err != nil { + return nil, err + } + if opts.BeforeWrite != nil { + if err := opts.BeforeWrite(func(i any) bool { + p, ok := i.(**os.File) + if !ok { + return false + } + *p = f + return true + }); err != nil { + return nil, err + } + } + + if b.opts.Metadata == MetadataDontWrite { + w := &writer{ + ctx: ctx, + File: f, + path: path, + ifNotExist: opts.IfNotExist, + mu: &sync.Mutex{}, + } + return w, nil + } + + var metadata map[string]string + if len(opts.Metadata) > 0 { + metadata = opts.Metadata + } + attrs := xattrs{ + CacheControl: opts.CacheControl, + ContentDisposition: opts.ContentDisposition, + ContentEncoding: opts.ContentEncoding, + ContentLanguage: opts.ContentLanguage, + ContentType: contentType, + Metadata: metadata, + } + w := &writerWithSidecar{ + ctx: ctx, + f: f, + path: path, + attrs: attrs, + contentMD5: opts.ContentMD5, + md5hash: md5.New(), + ifNotExist: opts.IfNotExist, + mu: &sync.Mutex{}, + } + return w, nil +} + +// writerWithSidecar implements the strategy of storing metadata in a distinct file. +type writerWithSidecar struct { + ctx context.Context + f *os.File + path string + attrs xattrs + contentMD5 []byte + // We compute the MD5 hash so that we can store it with the file attributes, + // not for verification. + md5hash hash.Hash + ifNotExist bool + mu *sync.Mutex +} + +func (w *writerWithSidecar) Write(p []byte) (n int, err error) { + n, err = w.f.Write(p) + if err != nil { + // Don't hash the unwritten tail twice when writing is resumed. + w.md5hash.Write(p[:n]) + return n, err + } + if _, err := w.md5hash.Write(p); err != nil { + return n, err + } + return n, nil +} + +func (w *writerWithSidecar) Close() error { + err := w.f.Close() + if err != nil { + return err + } + // Always delete the temp file. On success, it will have been renamed so + // the Remove will fail. + defer func() { + _ = os.Remove(w.f.Name()) + }() + + // Check if the write was cancelled. + if err := w.ctx.Err(); err != nil { + return err + } + + md5sum := w.md5hash.Sum(nil) + w.attrs.MD5 = md5sum + + // Write the attributes file. + if err := setAttrs(w.path, w.attrs); err != nil { + return err + } + + if w.ifNotExist { + w.mu.Lock() + defer w.mu.Unlock() + _, err = os.Stat(w.path) + if err == nil { + return gcerr.New(gcerrors.FailedPrecondition, err, 1, "File already exist") + } + } + // Rename the temp file to path. + if err := os.Rename(w.f.Name(), w.path); err != nil { + _ = os.Remove(w.path + attrsExt) + return err + } + return nil +} + +// writer is a file with a temporary name until closed. +// +// Embedding os.File allows the likes of io.Copy to use optimizations., +// which is why it is not folded into writerWithSidecar. +type writer struct { + *os.File + ctx context.Context + path string + ifNotExist bool + mu *sync.Mutex +} + +func (w *writer) Upload(r io.Reader) error { + _, err := w.ReadFrom(r) + return err +} + +func (w *writer) Close() error { + err := w.File.Close() + if err != nil { + return err + } + // Always delete the temp file. On success, it will have been renamed so + // the Remove will fail. + tempname := w.File.Name() + defer os.Remove(tempname) + + // Check if the write was cancelled. + if err := w.ctx.Err(); err != nil { + return err + } + + if w.ifNotExist { + w.mu.Lock() + defer w.mu.Unlock() + _, err = os.Stat(w.path) + if err == nil { + return gcerr.New(gcerrors.FailedPrecondition, err, 1, "File already exist") + } + } + + // Rename the temp file to path. + if err := os.Rename(tempname, w.path); err != nil { + return err + } + return nil +} + +// Copy implements driver.Copy. +func (b *bucket) Copy(ctx context.Context, dstKey, srcKey string, opts *driver.CopyOptions) error { + // Note: we could use NewRangeReader here, but since we need to copy all of + // the metadata (from xa), it's more efficient to do it directly. + srcPath, _, xa, err := b.forKey(srcKey) + if err != nil { + return err + } + f, err := os.Open(srcPath) + if err != nil { + return err + } + defer f.Close() + + // We'll write the copy using Writer, to avoid re-implementing making of a + // temp file, cleaning up after partial failures, etc. + wopts := driver.WriterOptions{ + CacheControl: xa.CacheControl, + ContentDisposition: xa.ContentDisposition, + ContentEncoding: xa.ContentEncoding, + ContentLanguage: xa.ContentLanguage, + Metadata: xa.Metadata, + BeforeWrite: opts.BeforeCopy, + } + // Create a cancelable context so we can cancel the write if there are + // problems. + writeCtx, cancel := context.WithCancel(ctx) + defer cancel() + w, err := b.NewTypedWriter(writeCtx, dstKey, xa.ContentType, &wopts) + if err != nil { + return err + } + _, err = io.Copy(w, f) + if err != nil { + cancel() // cancel before Close cancels the write + w.Close() + return err + } + return w.Close() +} + +// Delete implements driver.Delete. +func (b *bucket) Delete(ctx context.Context, key string) error { + path, err := b.path(key) + if err != nil { + return err + } + err = os.Remove(path) + if err != nil { + return err + } + if err = os.Remove(path + attrsExt); err != nil && !os.IsNotExist(err) { + return err + } + return nil +} + +// SignedURL implements driver.SignedURL +func (b *bucket) SignedURL(ctx context.Context, key string, opts *driver.SignedURLOptions) (string, error) { + if b.opts.URLSigner == nil { + return "", gcerr.New(gcerr.Unimplemented, nil, 1, "fileblob.SignedURL: bucket does not have an Options.URLSigner") + } + if opts.BeforeSign != nil { + if err := opts.BeforeSign(func(any) bool { return false }); err != nil { + return "", err + } + } + surl, err := b.opts.URLSigner.URLFromKey(ctx, key, opts) + if err != nil { + return "", err + } + return surl.String(), nil +} + +// URLSigner defines an interface for creating and verifying a signed URL for +// objects in a fileblob bucket. Signed URLs are typically used for granting +// access to an otherwise-protected resource without requiring further +// authentication, and callers should take care to restrict the creation of +// signed URLs as is appropriate for their application. +type URLSigner interface { + // URLFromKey defines how the bucket's object key will be turned + // into a signed URL. URLFromKey must be safe to call from multiple goroutines. + URLFromKey(ctx context.Context, key string, opts *driver.SignedURLOptions) (*url.URL, error) + + // KeyFromURL must be able to validate a URL returned from URLFromKey. + // KeyFromURL must only return the object if if the URL is + // both unexpired and authentic. KeyFromURL must be safe to call from + // multiple goroutines. Implementations of KeyFromURL should not modify + // the URL argument. + KeyFromURL(ctx context.Context, surl *url.URL) (string, error) +} + +// URLSignerHMAC signs URLs by adding the object key, expiration time, and a +// hash-based message authentication code (HMAC) into the query parameters. +// Values of URLSignerHMAC with the same secret key will accept URLs produced by +// others as valid. +type URLSignerHMAC struct { + baseURL *url.URL + secretKey []byte +} + +// NewURLSignerHMAC creates a URLSignerHMAC. If the secret key is empty, +// then NewURLSignerHMAC panics. +func NewURLSignerHMAC(baseURL *url.URL, secretKey []byte) *URLSignerHMAC { + if len(secretKey) == 0 { + panic("creating URLSignerHMAC: secretKey is required") + } + uc := new(url.URL) + *uc = *baseURL + return &URLSignerHMAC{ + baseURL: uc, + secretKey: secretKey, + } +} + +// URLFromKey creates a signed URL by copying the baseURL and appending the +// object key, expiry, and signature as a query params. +func (h *URLSignerHMAC) URLFromKey(ctx context.Context, key string, opts *driver.SignedURLOptions) (*url.URL, error) { + sURL := new(url.URL) + *sURL = *h.baseURL + + q := sURL.Query() + q.Set("obj", key) + q.Set("expiry", strconv.FormatInt(time.Now().Add(opts.Expiry).Unix(), 10)) + q.Set("method", opts.Method) + if opts.ContentType != "" { + q.Set("contentType", opts.ContentType) + } + q.Set("signature", h.getMAC(q)) + sURL.RawQuery = q.Encode() + + return sURL, nil +} + +func (h *URLSignerHMAC) getMAC(q url.Values) string { + signedVals := url.Values{} + signedVals.Set("obj", q.Get("obj")) + signedVals.Set("expiry", q.Get("expiry")) + signedVals.Set("method", q.Get("method")) + if contentType := q.Get("contentType"); contentType != "" { + signedVals.Set("contentType", contentType) + } + msg := signedVals.Encode() + + hsh := hmac.New(sha256.New, h.secretKey) + hsh.Write([]byte(msg)) + return base64.RawURLEncoding.EncodeToString(hsh.Sum(nil)) +} + +// KeyFromURL checks expiry and signature, and returns the object key +// only if the signed URL is both authentic and unexpired. +func (h *URLSignerHMAC) KeyFromURL(ctx context.Context, sURL *url.URL) (string, error) { + q := sURL.Query() + + exp, err := strconv.ParseInt(q.Get("expiry"), 10, 64) + if err != nil || time.Now().Unix() > exp { + return "", errors.New("retrieving blob key from URL: key cannot be retrieved") + } + + if !h.checkMAC(q) { + return "", errors.New("retrieving blob key from URL: key cannot be retrieved") + } + return q.Get("obj"), nil +} + +func (h *URLSignerHMAC) checkMAC(q url.Values) bool { + mac := q.Get("signature") + expected := h.getMAC(q) + // This compares the Base-64 encoded MACs + return hmac.Equal([]byte(mac), []byte(expected)) +} diff --git a/go-cloud/blob/fileblob/fileblob_test.go b/go-cloud/blob/fileblob/fileblob_test.go new file mode 100644 index 000000000..9455f603f --- /dev/null +++ b/go-cloud/blob/fileblob/fileblob_test.go @@ -0,0 +1,535 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 fileblob + +import ( + "context" + "errors" + "fmt" + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/blob/drivertest" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +type harness struct { + dir string + prefix string + metadataHow metadataOption + noTempDir bool + server *httptest.Server + urlSigner URLSigner + closer func() +} + +func newHarness(ctx context.Context, t *testing.T, prefix string, metadataHow metadataOption, noTempDir bool) (drivertest.Harness, error) { + t.Helper() + + if metadataHow == MetadataDontWrite { + // Skip tests for if no metadata gets written. + // For these it is currently undefined whether any gets read (back). + switch name := t.Name(); { + case strings.Contains(name, "ContentType"), strings.HasSuffix(name, "TestAttributes"), strings.Contains(name, "TestMetadata/"): + t.SkipNow() + return nil, nil + } + } + + dir := filepath.Join(os.TempDir(), "go-cloud-fileblob") + if err := os.MkdirAll(dir, os.ModePerm); err != nil { + return nil, err + } + if prefix != "" { + if err := os.MkdirAll(filepath.Join(dir, prefix), os.ModePerm); err != nil { + return nil, err + } + } + h := &harness{dir: dir, prefix: prefix, metadataHow: metadataHow, noTempDir: noTempDir} + + localServer := httptest.NewServer(http.HandlerFunc(h.serveSignedURL)) + h.server = localServer + + u, err := url.Parse(h.server.URL) + if err != nil { + return nil, err + } + h.urlSigner = NewURLSignerHMAC(u, []byte("I'm a secret key")) + + h.closer = func() { _ = os.RemoveAll(dir); localServer.Close() } + + return h, nil +} + +func (h *harness) serveSignedURL(w http.ResponseWriter, r *http.Request) { + objKey, err := h.urlSigner.KeyFromURL(r.Context(), r.URL) + if err != nil { + w.WriteHeader(http.StatusForbidden) + return + } + + allowedMethod := r.URL.Query().Get("method") + if allowedMethod == "" { + allowedMethod = http.MethodGet + } + if allowedMethod != r.Method { + w.WriteHeader(http.StatusForbidden) + return + } + contentType := r.URL.Query().Get("contentType") + if r.Header.Get("Content-Type") != contentType { + w.WriteHeader(http.StatusForbidden) + return + } + + bucket, err := OpenBucket(h.dir, &Options{}) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + defer bucket.Close() + + switch r.Method { + case http.MethodGet: + reader, err := bucket.NewReader(r.Context(), objKey, nil) + if err != nil { + w.WriteHeader(http.StatusNotFound) + return + } + defer reader.Close() + io.Copy(w, reader) + case http.MethodPut: + writer, err := bucket.NewWriter(r.Context(), objKey, &blob.WriterOptions{ + ContentType: contentType, + }) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + io.Copy(writer, r.Body) + if err := writer.Close(); err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + case http.MethodDelete: + if err := bucket.Delete(r.Context(), objKey); err != nil { + w.WriteHeader(http.StatusNotFound) + return + } + default: + w.WriteHeader(http.StatusForbidden) + } +} + +func (h *harness) HTTPClient() *http.Client { + return &http.Client{} +} + +func (h *harness) MakeDriver(ctx context.Context) (driver.Bucket, error) { + opts := &Options{ + URLSigner: h.urlSigner, + Metadata: h.metadataHow, + NoTempDir: h.noTempDir, + } + drv, err := openBucket(h.dir, opts) + if err != nil { + return nil, err + } + if h.prefix == "" { + return drv, nil + } + return driver.NewPrefixedBucket(drv, h.prefix), nil +} + +func (h *harness) MakeDriverForNonexistentBucket(ctx context.Context) (driver.Bucket, error) { + // Does not make sense for this driver, as it verifies + // that the directory exists in OpenBucket. + return nil, nil +} + +func (h *harness) Close() { + h.closer() +} + +func TestConformance(t *testing.T) { + newHarnessNoPrefix := func(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return newHarness(ctx, t, "", MetadataInSidecar, false) + } + drivertest.RunConformanceTests(t, newHarnessNoPrefix, []drivertest.AsTest{verifyAs{}}) +} + +func TestConformanceNoTempDir(t *testing.T) { + newHarnessNoTmpDir := func(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return newHarness(ctx, t, "", MetadataInSidecar, true) + } + drivertest.RunConformanceTests(t, newHarnessNoTmpDir, []drivertest.AsTest{verifyAs{}}) +} + +func TestConformanceWithPrefix(t *testing.T) { + const prefix = "some/prefix/dir/" + newHarnessWithPrefix := func(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return newHarness(ctx, t, prefix, MetadataInSidecar, false) + } + drivertest.RunConformanceTests(t, newHarnessWithPrefix, []drivertest.AsTest{verifyAs{prefix: prefix}}) +} + +func TestConformanceSkipMetadata(t *testing.T) { + newHarnessSkipMetadata := func(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return newHarness(ctx, t, "", MetadataDontWrite, false) + } + drivertest.RunConformanceTests(t, newHarnessSkipMetadata, []drivertest.AsTest{verifyAs{}}) +} + +func BenchmarkFileblob(b *testing.B) { + dir := filepath.Join(os.TempDir(), "go-cloud-fileblob") + if err := os.MkdirAll(dir, os.ModePerm); err != nil { + b.Fatal(err) + } + bkt, err := OpenBucket(dir, nil) + if err != nil { + b.Fatal(err) + } + drivertest.RunBenchmarks(b, bkt) +} + +// File-specific unit tests. +func TestNewBucket(t *testing.T) { + t.Run("BucketDirMissing", func(t *testing.T) { + dir := t.TempDir() + + _, gotErr := OpenBucket(filepath.Join(dir, "notfound"), nil) + if gotErr == nil { + t.Errorf("got nil want error") + } + }) + t.Run("BucketDirMissingWithCreateDir", func(t *testing.T) { + dir := t.TempDir() + + b, gotErr := OpenBucket(filepath.Join(dir, "notfound"), &Options{CreateDir: true}) + if gotErr != nil { + t.Errorf("got error %v", gotErr) + } + defer b.Close() + + // Make sure the subdir has gotten permissions to be used. + gotErr = b.WriteAll(context.Background(), "key", []byte("delme"), nil) + if gotErr != nil { + t.Errorf("got error writing to bucket from CreateDir %v", gotErr) + } + }) + t.Run("BucketIsFile", func(t *testing.T) { + dir := t.TempDir() + + f, err := os.CreateTemp(dir, "fileblob") + if err != nil { + t.Fatal(err) + } + _, gotErr := OpenBucket(f.Name(), nil) + if gotErr == nil { + t.Errorf("got nil want error") + } + }) +} + +func TestSignedURLReturnsUnimplementedWithNoURLSigner(t *testing.T) { + dir := t.TempDir() + + b, err := OpenBucket(dir, nil) + if err != nil { + t.Fatal(err) + } + defer b.Close() + _, gotErr := b.SignedURL(context.Background(), "key", nil) + if gcerrors.Code(gotErr) != gcerrors.Unimplemented { + t.Errorf("want Unimplemented error, got %v", gotErr) + } +} + +type verifyAs struct { + prefix string +} + +func (verifyAs) Name() string { return "verify As types for fileblob" } + +func (verifyAs) BucketCheck(b *blob.Bucket) error { + var fi os.FileInfo + if !b.As(&fi) { + return errors.New("Bucket.As failed") + } + return nil +} + +func (verifyAs) BeforeRead(as func(any) bool) error { + var f *os.File + if !as(&f) { + return errors.New("BeforeRead.As failed") + } + return nil +} + +func (verifyAs) BeforeWrite(as func(any) bool) error { + var f *os.File + if !as(&f) { + return errors.New("BeforeWrite.As failed") + } + return nil +} + +func (verifyAs) BeforeCopy(as func(any) bool) error { + var f *os.File + if !as(&f) { + return errors.New("BeforeCopy.As failed") + } + return nil +} +func (verifyAs) BeforeList(as func(any) bool) error { return nil } +func (verifyAs) BeforeSign(as func(any) bool) error { return nil } +func (verifyAs) AttributesCheck(attrs *blob.Attributes) error { + var fi os.FileInfo + if !attrs.As(&fi) { + return errors.New("Attributes.As failed") + } + return nil +} + +func (verifyAs) ReaderCheck(r *blob.Reader) error { + var ior io.Reader + if !r.As(&ior) { + return errors.New("Reader.As failed") + } + return nil +} + +func (verifyAs) ListObjectCheck(o *blob.ListObject) error { + var fi os.FileInfo + if !o.As(&fi) { + return errors.New("ListObject.As failed") + } + return nil +} + +func (v verifyAs) ErrorCheck(b *blob.Bucket, err error) error { + var perr *os.PathError + if !b.ErrorAs(err, &perr) { + return errors.New("want ErrorAs to succeed for PathError") + } + wantSuffix := filepath.Join("go-cloud-fileblob", v.prefix, "key-does-not-exist") + if got := perr.Path; !strings.HasSuffix(got, wantSuffix) { + return fmt.Errorf("got path %q, want suffix %q", got, wantSuffix) + } + return nil +} + +func TestOpenBucketFromURL(t *testing.T) { + const subdir = "mysubdir" + dir := filepath.Join(os.TempDir(), "fileblob") + if err := os.MkdirAll(dir, os.ModePerm); err != nil { + t.Fatal(err) + } + if err := os.MkdirAll(filepath.Join(dir, subdir), os.ModePerm); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(dir, "myfile.txt"), []byte("hello world"), 0o666); err != nil { + t.Fatal(err) + } + // To avoid making another temp dir, use the bucket directory to hold the secret key file. + secretKeyPath := filepath.Join(dir, "secret.key") + if err := os.WriteFile(secretKeyPath, []byte("secret key"), 0o666); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(dir, subdir, "myfileinsubdir.txt"), []byte("hello world in subdir"), 0o666); err != nil { + t.Fatal(err) + } + // Convert dir to a URL path, adding a leading "/" if needed on Windows. + dirpath := filepath.ToSlash(dir) + if os.PathSeparator != '/' && !strings.HasPrefix(dirpath, "/") { + dirpath = "/" + dirpath + } + + tests := []struct { + URL string + Key string + WantErr bool + WantReadErr bool + Want string + }{ + // Bucket doesn't exist -> error at construction time. + {"file:///bucket-not-found", "", true, false, ""}, + // File doesn't exist -> error at read time. + {"file://" + dirpath, "filenotfound.txt", false, true, ""}, + // Relative path using host="."; bucket is created but error at read time. + {"file://./../..", "filenotfound.txt", false, true, ""}, + // OK. + {"file://" + dirpath, "myfile.txt", false, false, "hello world"}, + // OK, with no_tmp_dir. + {"file://" + dirpath + "?no_tmp_dir", "myfile.txt", false, false, "hello world"}, + // OK, host is ignored. + {"file://localhost" + dirpath, "myfile.txt", false, false, "hello world"}, + // OK, with prefix. + {"file://" + dirpath + "?prefix=" + subdir + "/", "myfileinsubdir.txt", false, false, "hello world in subdir"}, + // Subdir does not exist. + {"file://" + dirpath + "subdir", "", true, false, ""}, + // Subdir does not exist, but create_dir creates it. Error is at file read time. + {"file://" + dirpath + "subdir2?create_dir=true", "filenotfound.txt", false, true, ""}, + // Invalid dir_file_mode. + {"file://" + dirpath + "subdir?dir_file_mode=x", "myfile.txt", true, false, ""}, + // Another invalid dir_file_mode. + {"file://" + dirpath + "subdir?dir_file_mode=-1", "myfile.txt", true, false, ""}, + // Valid dir_file_mode. + {"file://" + dirpath + "subdir3?dir_file_mode=666&create_dir=true", "filenotfound.txt", false, true, ""}, + // Invalid query parameter. + {"file://" + dirpath + "?param=value", "myfile.txt", true, false, ""}, + // Unrecognized value for parameter "metadata". + {"file://" + dirpath + "?metadata=nosuchstrategy", "myfile.txt", true, false, ""}, + // OK, with params. + { + fmt.Sprintf("file://%s?base_url=/show&secret_key_path=%s", dirpath, secretKeyPath), + "myfile.txt", false, false, "hello world", + }, + // Bad secret key filename. + { + fmt.Sprintf("file://%s?base_url=/show&secret_key_path=%s", dirpath, "bad"), + "myfile.txt", true, false, "", + }, + // Missing base_url. + { + fmt.Sprintf("file://%s?secret_key_path=%s", dirpath, secretKeyPath), + "myfile.txt", true, false, "", + }, + // Missing secret_key_path. + {"file://" + dirpath + "?base_url=/show", "myfile.txt", true, false, ""}, + } + + ctx := context.Background() + for i, test := range tests { + b, err := blob.OpenBucket(ctx, test.URL) + if b != nil { + defer b.Close() + } + if (err != nil) != test.WantErr { + t.Errorf("#%d: %s: got error %v, want error %v", i, test.URL, err, test.WantErr) + } + if err != nil { + continue + } + got, err := b.ReadAll(ctx, test.Key) + if (err != nil) != test.WantReadErr { + t.Errorf("%s: got read error %v, want error %v", test.URL, err, test.WantReadErr) + } + if err != nil { + continue + } + if string(got) != test.Want { + t.Errorf("%s: got %q want %q", test.URL, got, test.Want) + } + } +} + +func TestListAtRoot(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("/ as root is a unix concept") + } + + ctx := context.Background() + b, err := OpenBucket("/", nil) + if err != nil { + t.Fatalf("Got error creating bucket; %#v", err) + } + defer b.Close() + + dir := t.TempDir() + + f, err := os.Create(filepath.Join(dir, "file.txt")) + if err != nil { + t.Fatalf("Got error creating file: %#v", err) + } + defer f.Close() + + it := b.List(&blob.ListOptions{ + Prefix: dir[1:], + }) + obj, err := it.Next(ctx) + if err != nil { + t.Fatalf("Got error reading next item from list: %#v", err) + } + if obj.Key != filepath.Join(dir, "file.txt")[1:] { + t.Fatalf("Got unexpected filename in list: %q", obj.Key) + } + _, err = it.Next(ctx) + if err != io.EOF { + t.Fatalf("Expecting an EOF on next item in list, got: %#v", err) + } +} + +func TestSkipMetadata(t *testing.T) { + dir := t.TempDir() + + dirpath := filepath.ToSlash(dir) + if os.PathSeparator != '/' && !strings.HasPrefix(dirpath, "/") { + dirpath = "/" + dirpath + } + + tests := []struct { + URL string + wantSidecar bool + }{ + {"file://" + dirpath + "?metadata=skip", false}, + {"file://" + dirpath, true}, // Implicitly sets the default strategy… + {"file://" + dirpath + "?metadata=", true}, // … and explicitly. + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + for _, test := range tests { + b, err := blob.OpenBucket(ctx, test.URL) + if b != nil { + defer b.Close() + } + if err != nil { + t.Fatal(err) + } + + err = b.WriteAll(ctx, "key", []byte("hello world"), &blob.WriterOptions{ + ContentType: "text/plain", + }) + if err != nil { + t.Fatal(err) + } + + _, err = os.Stat(filepath.Join(dir, "key"+attrsExt)) + if gotSidecar := !errors.Is(err, os.ErrNotExist); test.wantSidecar != gotSidecar { + t.Errorf("Metadata sidecar file (extension %s) exists: %v, did we want it: %v", + attrsExt, gotSidecar, test.wantSidecar) + } + b.Delete(ctx, "key") + } +} diff --git a/go-cloud/blob/gcsblob/example_test.go b/go-cloud/blob/gcsblob/example_test.go new file mode 100644 index 000000000..422bc379d --- /dev/null +++ b/go-cloud/blob/gcsblob/example_test.go @@ -0,0 +1,70 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcsblob_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/gcsblob" + "github.com/DataDog/iceberg-go/go-cloud/gcp" +) + +func ExampleOpenBucket() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Your GCP credentials. + // See https://cloud.google.com/docs/authentication/production + // for more info on alternatives. + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + log.Fatal(err) + } + + // Create an HTTP client. + // This example uses the default HTTP transport and the credentials + // created above. + client, err := gcp.NewHTTPClient( + gcp.DefaultTransport(), + gcp.CredentialsTokenSource(creds)) + if err != nil { + log.Fatal(err) + } + + // Create a *blob.Bucket. + bucket, err := gcsblob.OpenBucket(ctx, client, "my-bucket", nil) + if err != nil { + log.Fatal(err) + } + defer bucket.Close() +} + +func Example_openBucketFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/blob/gcsblob" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // blob.OpenBucket creates a *blob.Bucket from a URL. + // This URL will open the bucket "my-bucket" using default credentials. + bucket, err := blob.OpenBucket(ctx, "gs://my-bucket") + if err != nil { + log.Fatal(err) + } + defer bucket.Close() +} diff --git a/go-cloud/blob/gcsblob/gcsblob.go b/go-cloud/blob/gcsblob/gcsblob.go new file mode 100644 index 000000000..44dc8e784 --- /dev/null +++ b/go-cloud/blob/gcsblob/gcsblob.go @@ -0,0 +1,783 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcsblob provides a blob implementation that uses GCS. Use OpenBucket +// to construct a *blob.Bucket. +// +// # URLs +// +// For blob.OpenBucket, gcsblob registers for the scheme "gs". +// The default URL opener will set up a connection using default credentials +// from the environment, as described in +// https://cloud.google.com/docs/authentication/production. +// You may force the use of an unauthenticated client by setting +// GoogleAccessID to "-" (via Options or via the URL parameter "access_id"). +// Some environments, such as GCE, come without a private key. In such cases +// the IAM Credentials API will be configured for use in Options.MakeSignBytes, +// which will introduce latency to any and all calls to bucket.SignedURL +// that you can avoid by installing a service account credentials file or +// obtaining and configuring a private key: +// https://cloud.google.com/iam/docs/creating-managing-service-account-keys +// +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # Escaping +// +// Go CDK supports all UTF-8 strings; to make this work with services lacking +// full UTF-8 support, strings must be escaped (during writes) and unescaped +// (during reads). The following escapes are performed for gcsblob: +// - Blob keys: ASCII characters 10 and 13 are escaped to "__0x__". +// Additionally, the "/" in "../" is escaped in the same way. +// +// # As +// +// gcsblob exposes the following types for As: +// - Bucket: *storage.Client +// - Error: *googleapi.Error +// - ListObject: storage.ObjectAttrs +// - ListOptions.BeforeList: *storage.Query +// - Reader: *storage.Reader +// - ReaderOptions.BeforeRead: **storage.ObjectHandle, *storage.Reader (if accessing both, must be in that order) +// - Attributes: storage.ObjectAttrs +// - CopyOptions.BeforeCopy: *CopyObjectHandles, *storage.Copier (if accessing both, must be in that order) +// - WriterOptions.BeforeWrite: **storage.ObjectHandle, *storage.Writer (if accessing both, must be in that order) +// - SignedURLOptions.BeforeSign: *storage.SignedURLOptions +package gcsblob // import "gocloud.dev/blob/gcsblob" + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + "sort" + "strconv" + "strings" + "sync" + "time" + + "cloud.google.com/go/compute/metadata" + "cloud.google.com/go/storage" + "github.com/google/wire" + "golang.org/x/oauth2/google" + "google.golang.org/api/googleapi" + "google.golang.org/api/iterator" + "google.golang.org/api/option" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/internal/escape" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/useragent" +) + +const defaultPageSize = 1000 + +func init() { + blob.DefaultURLMux().RegisterBucket(Scheme, new(lazyCredsOpener)) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + wire.Struct(new(URLOpener), "Client"), +) + +// readDefaultCredentials gets the field values from the supplied JSON data. +// For its possible formats please see +// https://cloud.google.com/iam/docs/creating-managing-service-account-keys#iam-service-account-keys-create-go +// +// Use "golang.org/x/oauth2/google".DefaultCredentials.JSON to get +// the contents of the preferred credential file. +// +// Returns null-values for fields that have not been obtained. +func readDefaultCredentials(credFileAsJSON []byte) (AccessID string, PrivateKey []byte) { + // For example, a credentials file as generated for service accounts through the web console. + var contentVariantA struct { + ClientEmail string `json:"client_email"` + PrivateKey string `json:"private_key"` + } + if err := json.Unmarshal(credFileAsJSON, &contentVariantA); err == nil { + AccessID = contentVariantA.ClientEmail + PrivateKey = []byte(contentVariantA.PrivateKey) + } + if AccessID != "" { + return + } + + // If obtained through the REST API. + var contentVariantB struct { + Name string `json:"name"` + PrivateKeyData string `json:"privateKeyData"` + } + if err := json.Unmarshal(credFileAsJSON, &contentVariantB); err == nil { + nextFieldIsAccessID := false + for _, s := range strings.Split(contentVariantB.Name, "/") { + if nextFieldIsAccessID { + AccessID = s + break + } + nextFieldIsAccessID = s == "serviceAccounts" + } + PrivateKey = []byte(contentVariantB.PrivateKeyData) + } + + return +} + +// lazyCredsOpener obtains Application Default Credentials on the first call +// to OpenBucketURL. +type lazyCredsOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazyCredsOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) { + o.init.Do(func() { + var opts Options + var creds *google.Credentials + if os.Getenv("STORAGE_EMULATOR_HOST") != "" { + creds, _ = google.CredentialsFromJSON(ctx, []byte(`{"type": "service_account", "project_id": "my-project-id"}`)) + } else { + var err error + creds, err = gcp.DefaultCredentials(ctx) + if err != nil { + fmt.Printf("Warning: unable to load GCP Default Credentials: %v", err) + // Use empty credentials, in case the user isn't going to actually use + // them; e.g., getting signed URLs with GoogleAccessID=-. + creds, _ = google.CredentialsFromJSON(ctx, []byte(`{"type": "service_account"}`)) + } + + // Populate default values from credentials files, where available. + opts.GoogleAccessID, opts.PrivateKey = readDefaultCredentials(creds.JSON) + + // ... else, on GCE, at least get the instance's main service account. + if opts.GoogleAccessID == "" && metadata.OnGCE() { + mc := metadata.NewClient(nil) + opts.GoogleAccessID, _ = mc.Email("") + } + } + + // Provide a default factory for SignBytes for environments without a private key. + if len(opts.PrivateKey) <= 0 && opts.GoogleAccessID != "" { + iam := new(credentialsClient) + // We cannot hold onto the first context: it might've been cancelled already. + ctx := context.Background() + opts.MakeSignBytes = iam.CreateMakeSignBytesWith(ctx, opts.GoogleAccessID) + } + + client, err := gcp.NewHTTPClient(gcp.DefaultTransport(), creds.TokenSource) + if err != nil { + o.err = err + return + } + o.opener = &URLOpener{Client: client, Options: opts} + }) + if o.err != nil { + return nil, fmt.Errorf("open bucket %v: %v", u, o.err) + } + return o.opener.OpenBucketURL(ctx, u) +} + +// Scheme is the URL scheme gcsblob registers its URLOpener under on +// blob.DefaultMux. +const Scheme = "gs" + +// URLOpener opens GCS URLs like "gs://mybucket". +// +// The URL host is used as the bucket name. +// +// The following query parameters are supported: +// +// - anonymous: A value of "true" forces the use of an unauthenticated client. +// - access_id: Sets Options.GoogleAccessID; only used in SignedURL, except that +// a value of "-" forces the use of an unauthenticated client. +// - private_key_path: Path to read for Options.PrivateKey; only used in SignedURL. +type URLOpener struct { + // Client must be set to a non-nil HTTP client authenticated with + // Cloud Storage scope or equivalent (unless anonymous=true). + Client *gcp.HTTPClient + + // Options specifies the default options to pass to OpenBucket. + Options Options +} + +// OpenBucketURL opens the GCS bucket with the same name as the URL's host. +func (o *URLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) { + opts, client, err := o.forParams(ctx, u.Query()) + if err != nil { + return nil, fmt.Errorf("open bucket %v: %v", u, err) + } + return OpenBucket(ctx, client, u.Host, opts) +} + +func (o *URLOpener) forParams(ctx context.Context, q url.Values) (*Options, *gcp.HTTPClient, error) { + for k := range q { + if k != "access_id" && k != "private_key_path" && k != "anonymous" { + return nil, nil, fmt.Errorf("invalid query parameter %q", k) + } + } + opts := new(Options) + *opts = o.Options + client := o.Client + if anon := q.Get("anonymous"); anon != "" { + isAnon, err := strconv.ParseBool(anon) + if err != nil { + return nil, nil, fmt.Errorf("invalid value %q for query parameter \"anonymous\": %w", anon, err) + } + if isAnon { + opts.clear() + client = gcp.NewAnonymousHTTPClient(gcp.DefaultTransport()) + } + } + if accessID := q.Get("access_id"); accessID != "" && accessID != opts.GoogleAccessID { + opts.clear() + if accessID == "-" { + client = gcp.NewAnonymousHTTPClient(gcp.DefaultTransport()) + } else { + opts.GoogleAccessID = accessID + } + } + if keyPath := q.Get("private_key_path"); keyPath != "" { + pk, err := os.ReadFile(keyPath) + if err != nil { + return nil, nil, err + } + opts.PrivateKey = pk + } else if _, exists := q["private_key_path"]; exists { + // A possible default value has been cleared by setting this to an empty value: + // The private key might have expired, or falling back to SignBytes/MakeSignBytes + // is intentional such as for tests or involving a key stored in a HSM/TPM. + opts.PrivateKey = nil + } + return opts, client, nil +} + +// Options sets options for constructing a *blob.Bucket backed by GCS. +type Options struct { + // GoogleAccessID represents the authorizer for SignedURL. + // If set to "-", an unauthenticated client will be used. + // Required to use SignedURL. + // See https://godoc.org/cloud.google.com/go/storage#SignedURLOptions. + GoogleAccessID string + + // PrivateKey is the Google service account private key. + // Exactly one of PrivateKey or SignBytes must be non-nil to use SignedURL. + // See https://godoc.org/cloud.google.com/go/storage#SignedURLOptions. + // Deprecated: Use MakeSignBytes instead. + PrivateKey []byte + + // SignBytes is a function for implementing custom signing. + // Exactly one of PrivateKey, SignBytes, or MakeSignBytes must be non-nil to use SignedURL. + // See https://godoc.org/cloud.google.com/go/storage#SignedURLOptions. + // Deprecated: Use MakeSignBytes instead. + SignBytes func([]byte) ([]byte, error) + + // MakeSignBytes is a factory for functions that are being used in place of an empty SignBytes. + // If your implementation of 'SignBytes' needs a request context, set this instead. + MakeSignBytes func(requestCtx context.Context) SignBytesFunc + + // ClientOptions are passed when constructing the storage.Client. + ClientOptions []option.ClientOption +} + +// clear clears all the fields of o. +func (o *Options) clear() { + o.GoogleAccessID = "" + o.PrivateKey = nil + o.SignBytes = nil + o.MakeSignBytes = nil +} + +// SignBytesFunc is shorthand for the signature of Options.SignBytes. +type SignBytesFunc func([]byte) ([]byte, error) + +// openBucket returns a GCS Bucket that communicates using the given HTTP client. +func openBucket(ctx context.Context, client *gcp.HTTPClient, bucketName string, opts *Options) (*bucket, error) { + if client == nil { + return nil, errors.New("gcsblob.OpenBucket: client is required") + } + if bucketName == "" { + return nil, errors.New("gcsblob.OpenBucket: bucketName is required") + } + + // We wrap the provided http.Client to add a Go CDK User-Agent. + clientOpts := []option.ClientOption{option.WithHTTPClient(useragent.HTTPClient(&client.Client, "blob"))} + if host := os.Getenv("STORAGE_EMULATOR_HOST"); host != "" { + clientOpts = []option.ClientOption{ + option.WithoutAuthentication(), + option.WithEndpoint("http://" + host + "/storage/v1/"), + option.WithHTTPClient(http.DefaultClient), + } + } + if opts == nil { + opts = &Options{} + } + clientOpts = append(clientOpts, opts.ClientOptions...) + c, err := storage.NewClient(ctx, clientOpts...) + if err != nil { + return nil, err + } + return &bucket{name: bucketName, client: c, opts: opts}, nil +} + +// OpenBucket returns a *blob.Bucket backed by an existing GCS bucket. See the +// package documentation for an example. +func OpenBucket(ctx context.Context, client *gcp.HTTPClient, bucketName string, opts *Options) (*blob.Bucket, error) { + drv, err := openBucket(ctx, client, bucketName, opts) + if err != nil { + return nil, err + } + return blob.NewBucket(drv), nil +} + +// bucket represents a GCS bucket, which handles read, write and delete operations +// on objects within it. +type bucket struct { + name string + client *storage.Client + opts *Options +} + +var emptyBody = io.NopCloser(strings.NewReader("")) + +// reader reads a GCS object. It implements driver.Reader. +type reader struct { + body io.ReadCloser + attrs driver.ReaderAttributes + raw *storage.Reader +} + +func (r *reader) Read(p []byte) (int, error) { + return r.body.Read(p) +} + +// Close closes the reader itself. It must be called when done reading. +func (r *reader) Close() error { + return r.body.Close() +} + +func (r *reader) Attributes() *driver.ReaderAttributes { + return &r.attrs +} + +func (r *reader) As(i any) bool { + p, ok := i.(**storage.Reader) + if !ok { + return false + } + *p = r.raw + return true +} + +func (b *bucket) ErrorCode(err error) gcerrors.ErrorCode { + if errors.Is(err, storage.ErrObjectNotExist) || errors.Is(err, storage.ErrBucketNotExist) { + return gcerrors.NotFound + } + if gerr, ok := err.(*googleapi.Error); ok { + switch gerr.Code { + case http.StatusForbidden: + // 'Permission 'storage.objects.list' denied on resource (or it may not exist)' + // So we have to pick one. + return gcerrors.NotFound + case http.StatusNotFound: + return gcerrors.NotFound + case http.StatusPreconditionFailed: + return gcerrors.FailedPrecondition + case http.StatusTooManyRequests: + return gcerrors.ResourceExhausted + } + } + return gcerrors.Unknown +} + +func (b *bucket) Close() error { + return nil +} + +// ListPaged implements driver.ListPaged. +func (b *bucket) ListPaged(ctx context.Context, opts *driver.ListOptions) (*driver.ListPage, error) { + bkt := b.client.Bucket(b.name) + query := &storage.Query{ + Prefix: escapeKey(opts.Prefix), + Delimiter: escapeKey(opts.Delimiter), + } + if opts.BeforeList != nil { + asFunc := func(i any) bool { + p, ok := i.(**storage.Query) + if !ok { + return false + } + *p = query + return true + } + if err := opts.BeforeList(asFunc); err != nil { + return nil, err + } + } + pageSize := opts.PageSize + if pageSize == 0 { + pageSize = defaultPageSize + } + iter := bkt.Objects(ctx, query) + pager := iterator.NewPager(iter, pageSize, string(opts.PageToken)) + var objects []*storage.ObjectAttrs + nextPageToken, err := pager.NextPage(&objects) + if err != nil { + return nil, err + } + page := driver.ListPage{NextPageToken: []byte(nextPageToken)} + if len(objects) > 0 { + page.Objects = make([]*driver.ListObject, len(objects)) + for i, obj := range objects { + toCopy := obj + asFunc := func(val any) bool { + p, ok := val.(*storage.ObjectAttrs) + if !ok { + return false + } + *p = *toCopy + return true + } + if obj.Prefix == "" { + // Regular blob. + page.Objects[i] = &driver.ListObject{ + Key: unescapeKey(obj.Name), + ModTime: obj.Updated, + Size: obj.Size, + MD5: obj.MD5, + AsFunc: asFunc, + } + } else { + // "Directory". + page.Objects[i] = &driver.ListObject{ + Key: unescapeKey(obj.Prefix), + IsDir: true, + AsFunc: asFunc, + } + } + } + // GCS always returns "directories" at the end; sort them. + sort.Slice(page.Objects, func(i, j int) bool { + return page.Objects[i].Key < page.Objects[j].Key + }) + } + return &page, nil +} + +// As implements driver.As. +func (b *bucket) As(i any) bool { + p, ok := i.(**storage.Client) + if !ok { + return false + } + *p = b.client + return true +} + +// As implements driver.ErrorAs. +func (b *bucket) ErrorAs(err error, i any) bool { + switch v := err.(type) { + case *googleapi.Error: + if p, ok := i.(**googleapi.Error); ok { + *p = v + return true + } + } + return false +} + +// Attributes implements driver.Attributes. +func (b *bucket) Attributes(ctx context.Context, key string) (*driver.Attributes, error) { + key = escapeKey(key) + bkt := b.client.Bucket(b.name) + obj := bkt.Object(key) + attrs, err := obj.Attrs(ctx) + if err != nil { + return nil, err + } + // GCS seems to unquote the ETag; restore them. + // It should be of the form "xxxx" or W/"xxxx". + eTag := attrs.Etag + if !strings.HasPrefix(eTag, "W/\"") && !strings.HasPrefix(eTag, "\"") && !strings.HasSuffix(eTag, "\"") { + eTag = fmt.Sprintf("%q", eTag) + } + return &driver.Attributes{ + CacheControl: attrs.CacheControl, + ContentDisposition: attrs.ContentDisposition, + ContentEncoding: attrs.ContentEncoding, + ContentLanguage: attrs.ContentLanguage, + ContentType: attrs.ContentType, + Metadata: attrs.Metadata, + CreateTime: attrs.Created, + ModTime: attrs.Updated, + Size: attrs.Size, + MD5: attrs.MD5, + ETag: eTag, + AsFunc: func(i any) bool { + p, ok := i.(*storage.ObjectAttrs) + if !ok { + return false + } + *p = *attrs + return true + }, + }, nil +} + +// NewRangeReader implements driver.NewRangeReader. +func (b *bucket) NewRangeReader(ctx context.Context, key string, offset, length int64, opts *driver.ReaderOptions) (driver.Reader, error) { + key = escapeKey(key) + bkt := b.client.Bucket(b.name) + obj := bkt.Object(key) + + // Add an extra level of indirection so that BeforeRead can replace obj + // if needed. For example, ObjectHandle.If returns a new ObjectHandle. + // Also, make the Reader lazily in case this replacement happens. + objp := &obj + makeReader := func() (*storage.Reader, error) { + return (*objp).NewRangeReader(ctx, offset, length) + } + + var r *storage.Reader + var rerr error + madeReader := false + if opts.BeforeRead != nil { + asFunc := func(i any) bool { + if p, ok := i.(***storage.ObjectHandle); ok && !madeReader { + *p = objp + return true + } + if p, ok := i.(**storage.Reader); ok { + if !madeReader { + r, rerr = makeReader() + madeReader = true + if r == nil { + return false + } + } + *p = r + return true + } + return false + } + if err := opts.BeforeRead(asFunc); err != nil { + return nil, err + } + } + if !madeReader { + r, rerr = makeReader() + } + if rerr != nil { + return nil, rerr + } + return &reader{ + body: r, + attrs: driver.ReaderAttributes{ + ContentType: r.Attrs.ContentType, + ModTime: r.Attrs.LastModified, + Size: r.Attrs.Size, + }, + raw: r, + }, nil +} + +// escapeKey does all required escaping for UTF-8 strings to work with GCS. +func escapeKey(key string) string { + return escape.HexEscape(key, func(r []rune, i int) bool { + switch { + // GCS doesn't handle these characters (determined via experimentation). + case r[i] == 10 || r[i] == 13: + return true + // For "../", escape the trailing slash. + case i > 1 && r[i] == '/' && r[i-1] == '.' && r[i-2] == '.': + return true + } + return false + }) +} + +// unescapeKey reverses escapeKey. +func unescapeKey(key string) string { + return escape.HexUnescape(key) +} + +// NewTypedWriter implements driver.NewTypedWriter. +func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType string, opts *driver.WriterOptions) (driver.Writer, error) { + key = escapeKey(key) + bkt := b.client.Bucket(b.name) + obj := bkt.Object(key) + + if opts.IfNotExist { + obj = obj.If(storage.Conditions{DoesNotExist: true}) + } + // Add an extra level of indirection so that BeforeWrite can replace obj + // if needed. For example, ObjectHandle.If returns a new ObjectHandle. + // Also, make the Writer lazily in case this replacement happens. + objp := &obj + makeWriter := func() *storage.Writer { + w := (*objp).NewWriter(ctx) + w.CacheControl = opts.CacheControl + w.ContentDisposition = opts.ContentDisposition + w.ContentEncoding = opts.ContentEncoding + w.ContentLanguage = opts.ContentLanguage + w.ContentType = contentType + w.ChunkSize = bufferSize(opts.BufferSize) + w.Metadata = opts.Metadata + w.MD5 = opts.ContentMD5 + w.ForceEmptyContentType = opts.DisableContentTypeDetection + return w + } + + var w *storage.Writer + if opts.BeforeWrite != nil { + asFunc := func(i any) bool { + if p, ok := i.(***storage.ObjectHandle); ok && w == nil { + *p = objp + return true + } + if p, ok := i.(**storage.Writer); ok { + if w == nil { + w = makeWriter() + } + *p = w + return true + } + return false + } + if err := opts.BeforeWrite(asFunc); err != nil { + return nil, err + } + } + if w == nil { + w = makeWriter() + } + return w, nil +} + +// CopyObjectHandles holds the ObjectHandles for the destination and source +// of a Copy. It is used by the BeforeCopy As hook. +type CopyObjectHandles struct { + Dst, Src *storage.ObjectHandle +} + +// Copy implements driver.Copy. +func (b *bucket) Copy(ctx context.Context, dstKey, srcKey string, opts *driver.CopyOptions) error { + dstKey = escapeKey(dstKey) + srcKey = escapeKey(srcKey) + bkt := b.client.Bucket(b.name) + + // Add an extra level of indirection so that BeforeCopy can replace the + // dst or src ObjectHandles if needed. + // Also, make the Copier lazily in case this replacement happens. + handles := CopyObjectHandles{ + Dst: bkt.Object(dstKey), + Src: bkt.Object(srcKey), + } + makeCopier := func() *storage.Copier { + return handles.Dst.CopierFrom(handles.Src) + } + + var copier *storage.Copier + if opts.BeforeCopy != nil { + asFunc := func(i any) bool { + if p, ok := i.(**CopyObjectHandles); ok && copier == nil { + *p = &handles + return true + } + if p, ok := i.(**storage.Copier); ok { + if copier == nil { + copier = makeCopier() + } + *p = copier + return true + } + return false + } + if err := opts.BeforeCopy(asFunc); err != nil { + return err + } + } + if copier == nil { + copier = makeCopier() + } + _, err := copier.Run(ctx) + return err +} + +// Delete implements driver.Delete. +func (b *bucket) Delete(ctx context.Context, key string) error { + key = escapeKey(key) + bkt := b.client.Bucket(b.name) + obj := bkt.Object(key) + return obj.Delete(ctx) +} + +func (b *bucket) SignedURL(ctx context.Context, key string, dopts *driver.SignedURLOptions) (string, error) { + numSigners := 0 + if b.opts.PrivateKey != nil { + numSigners++ + } + if b.opts.SignBytes != nil { + numSigners++ + } + if b.opts.MakeSignBytes != nil { + numSigners++ + } + if b.opts.GoogleAccessID == "" || numSigners != 1 { + return "", gcerr.New(gcerr.Unimplemented, nil, 1, "gcsblob: to use SignedURL, you must call OpenBucket with a valid Options.GoogleAccessID and exactly one of Options.PrivateKey, Options.SignBytes, or Options.MakeSignBytes") + } + + key = escapeKey(key) + opts := &storage.SignedURLOptions{ + Expires: time.Now().Add(dopts.Expiry), + Method: dopts.Method, + ContentType: dopts.ContentType, + GoogleAccessID: b.opts.GoogleAccessID, + PrivateKey: b.opts.PrivateKey, + SignBytes: b.opts.SignBytes, + } + if b.opts.MakeSignBytes != nil { + opts.SignBytes = b.opts.MakeSignBytes(ctx) + } + if dopts.BeforeSign != nil { + asFunc := func(i any) bool { + v, ok := i.(**storage.SignedURLOptions) + if ok { + *v = opts + } + return ok + } + if err := dopts.BeforeSign(asFunc); err != nil { + return "", err + } + } + return storage.SignedURL(b.name, key, opts) +} + +func bufferSize(size int) int { + if size == 0 { + return googleapi.DefaultUploadChunkSize + } else if size > 0 { + return size + } + return 0 // disable buffering +} diff --git a/go-cloud/blob/gcsblob/gcsblob_test.go b/go-cloud/blob/gcsblob/gcsblob_test.go new file mode 100644 index 000000000..5d43ab2e2 --- /dev/null +++ b/go-cloud/blob/gcsblob/gcsblob_test.go @@ -0,0 +1,842 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcsblob + +import ( + "context" + "errors" + "flag" + "fmt" + "io" + "net/http" + "net/url" + "os" + "os/user" + "path/filepath" + "testing" + "time" + + "cloud.google.com/go/storage" + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/blob/drivertest" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "google.golang.org/api/googleapi" +) + +const ( + // These constants capture values that were used during the last -record. + // + // If you want to use --record mode, + // 1. Create a bucket in your GCP project: + // https://console.cloud.google.com/storage/browser, then "Create Bucket". + // 2. Update the bucketName constant to your bucket name. + // 3. Create a service account in your GCP project and update the + // serviceAccountID constant to it. + // 4. Download a private key to a .pem file as described here: + // https://godoc.org/cloud.google.com/go/storage#SignedURLOptions + // and pass a path to it via the --privatekey flag. + // TODO(issue #300): Use Terraform to provision a bucket, and get the bucket + // name from the Terraform output instead (saving a copy of it for replay). + bucketName = "go-cloud-blob-test-bucket" + serviceAccountID = "storage-updater@go-cloud-test-216917.iam.gserviceaccount.com" +) + +var pathToPrivateKey = flag.String("privatekey", "", "path to .pem file containing private key (required for --record); defaults to ~/Downloads/gcs-private-key.pem") + +type harness struct { + client *gcp.HTTPClient + opts *Options + rt http.RoundTripper + closer func() +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + opts := &Options{GoogleAccessID: serviceAccountID} + if *setup.Record { + if *pathToPrivateKey == "" { + usr, _ := user.Current() + *pathToPrivateKey = filepath.Join(usr.HomeDir, "Downloads", "gcs-private-key.pem") + } + // Use a real private key for signing URLs during -record. + pk, err := os.ReadFile(*pathToPrivateKey) + if err != nil { + t.Fatalf("Couldn't find private key at %v: %v", *pathToPrivateKey, err) + } + opts.PrivateKey = pk + } else { + // Use a dummy signer in replay mode. + opts.SignBytes = func(b []byte) ([]byte, error) { return []byte("signed!"), nil } + } + client, rt, done := setup.NewGCPClient(ctx, t) + return &harness{client: client, opts: opts, rt: rt, closer: done}, nil +} + +func (h *harness) HTTPClient() *http.Client { + return &http.Client{Transport: h.rt} +} + +func (h *harness) MakeDriver(ctx context.Context) (driver.Bucket, error) { + return openBucket(ctx, h.client, bucketName, h.opts) +} + +func (h *harness) MakeDriverForNonexistentBucket(ctx context.Context) (driver.Bucket, error) { + return openBucket(ctx, h.client, "bucket-does-not-exist", h.opts) +} + +func (h *harness) Close() { + h.closer() +} + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyContentLanguage{}}) +} + +func BenchmarkGcsblob(b *testing.B) { + ctx := context.Background() + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + b.Fatal(err) + } + client, err := gcp.NewHTTPClient(gcp.DefaultTransport(), gcp.CredentialsTokenSource(creds)) + if err != nil { + b.Fatal(err) + } + bkt, err := OpenBucket(context.Background(), client, bucketName, nil) + if err != nil { + b.Fatal(err) + } + drivertest.RunBenchmarks(b, bkt) +} + +const language = "nl" + +// verifyContentLanguage uses As to access the underlying GCS types and +// read/write the ContentLanguage field. +type verifyContentLanguage struct{} + +func (verifyContentLanguage) Name() string { + return "verify ContentLanguage can be written and read through As" +} + +func (verifyContentLanguage) BucketCheck(b *blob.Bucket) error { + var client *storage.Client + if !b.As(&client) { + return errors.New("Bucket.As failed") + } + return nil +} + +func (verifyContentLanguage) ErrorCheck(b *blob.Bucket, err error) error { + // Can't really verify this one because the storage library returns + // a sentinel error, storage.ErrObjectNotExist, for "not exists" + // instead of the supported As type googleapi.Error. + // Call ErrorAs anyway, and expect it to fail. + var to *googleapi.Error + if b.ErrorAs(err, &to) { + return errors.New("expected ErrorAs to fail") + } + return nil +} + +func (verifyContentLanguage) BeforeRead(as func(any) bool) error { + var objp **storage.ObjectHandle + if !as(&objp) { + return errors.New("BeforeRead.As failed to get ObjectHandle") + } + var sr *storage.Reader + if !as(&sr) { + return errors.New("BeforeRead.As failed to get Reader") + } + return nil +} + +func (verifyContentLanguage) BeforeWrite(as func(any) bool) error { + var objp **storage.ObjectHandle + if !as(&objp) { + return errors.New("Writer.As failed to get ObjectHandle") + } + var sw *storage.Writer + if !as(&sw) { + return errors.New("Writer.As failed to get Writer") + } + sw.ContentLanguage = language + return nil +} + +func (verifyContentLanguage) BeforeCopy(as func(any) bool) error { + var coh *CopyObjectHandles + if !as(&coh) { + return errors.New("BeforeCopy.As failed to get CopyObjectHandles") + } + var copier *storage.Copier + if !as(&copier) { + return errors.New("BeforeCopy.As failed") + } + return nil +} + +func (verifyContentLanguage) BeforeList(as func(any) bool) error { + var q *storage.Query + if !as(&q) { + return errors.New("List.As failed") + } + // Nothing to do. + return nil +} + +func (verifyContentLanguage) BeforeSign(as func(any) bool) error { + var opts *storage.SignedURLOptions + if !as(&opts) { + return errors.New("BeforeSign.As failed") + } + // Nothing to do. + return nil +} + +func (verifyContentLanguage) AttributesCheck(attrs *blob.Attributes) error { + var oa storage.ObjectAttrs + if !attrs.As(&oa) { + return errors.New("Attributes.As returned false") + } + if got := oa.ContentLanguage; got != language { + return fmt.Errorf("got %q want %q", got, language) + } + return nil +} + +func (verifyContentLanguage) ReaderCheck(r *blob.Reader) error { + var rr *storage.Reader + if !r.As(&rr) { + return errors.New("Reader.As returned false") + } + // GCS doesn't return Content-Language via storage.Reader. + return nil +} + +func (verifyContentLanguage) ListObjectCheck(o *blob.ListObject) error { + var oa storage.ObjectAttrs + if !o.As(&oa) { + return errors.New("ListObject.As returned false") + } + if o.IsDir { + return nil + } + if got := oa.ContentLanguage; got != language { + return fmt.Errorf("got %q want %q", got, language) + } + return nil +} + +// GCS-specific unit tests. +func TestBufferSize(t *testing.T) { + tests := []struct { + size int + want int + }{ + { + size: 5 * 1024 * 1024, + want: 5 * 1024 * 1024, + }, + { + size: 0, + want: googleapi.DefaultUploadChunkSize, + }, + { + size: -1024, + want: 0, + }, + } + for i, test := range tests { + got := bufferSize(test.size) + if got != test.want { + t.Errorf("%d) got buffer size %d, want %d", i, got, test.want) + } + } +} + +func TestOpenBucket(t *testing.T) { + tests := []struct { + description string + bucketName string + nilClient bool + want string + wantErr bool + }{ + { + description: "empty bucket name results in error", + wantErr: true, + }, + { + description: "nil client results in error", + bucketName: "foo", + nilClient: true, + wantErr: true, + }, + { + description: "success", + bucketName: "foo", + want: "foo", + }, + } + + ctx := context.Background() + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + var client *gcp.HTTPClient + if !test.nilClient { + var done func() + client, _, done = setup.NewGCPClient(ctx, t) + defer done() + } + + // Create driver impl. + drv, err := openBucket(ctx, client, test.bucketName, nil) + if (err != nil) != test.wantErr { + t.Errorf("got err %v want error %v", err, test.wantErr) + } + if err == nil && drv != nil && drv.name != test.want { + t.Errorf("got %q want %q", drv.name, test.want) + } + + // Create portable type. + b, err := OpenBucket(ctx, client, test.bucketName, nil) + if b != nil { + defer b.Close() + } + if (err != nil) != test.wantErr { + t.Errorf("got err %v want error %v", err, test.wantErr) + } + }) + } +} + +// TestBeforeReadNonExistentKey tests using BeforeRead on a nonexistent key. +func TestBeforeReadNonExistentKey(t *testing.T) { + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + bucket := blob.NewBucket(drv) + defer bucket.Close() + + // Try reading a nonexistent key. + _, err = bucket.NewReader(ctx, "nonexistent-key", &blob.ReaderOptions{ + BeforeRead: func(asFunc func(any) bool) error { + var objp **storage.ObjectHandle + if !asFunc(&objp) { + return errors.New("Reader.As failed to get ObjectHandle") + } + var rp *storage.Reader + if asFunc(&rp) { + return errors.New("Reader.As unexpectedly got storage.Reader") + } + return nil + }, + }) + if err == nil || gcerrors.Code(err) != gcerrors.NotFound { + t.Errorf("got error %v, wanted NotFound for Read", err) + } +} + +// TestPreconditions tests setting of ObjectHandle preconditions via As. +func TestPreconditions(t *testing.T) { + const ( + key = "precondition-key" + key2 = "precondition-key2" + content = "hello world" + ) + + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + drv, err := h.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + bucket := blob.NewBucket(drv) + defer bucket.Close() + + // Try writing with a failing precondition. + if err := bucket.WriteAll(ctx, key, []byte(content), &blob.WriterOptions{ + BeforeWrite: func(asFunc func(any) bool) error { + var objp **storage.ObjectHandle + if !asFunc(&objp) { + return errors.New("Writer.As failed to get ObjectHandle") + } + // Replace the ObjectHandle with a new one that adds Conditions. + *objp = (*objp).If(storage.Conditions{GenerationMatch: -999}) + return nil + }, + }); err == nil || gcerrors.Code(err) != gcerrors.FailedPrecondition { + t.Errorf("got error %v, wanted FailedPrecondition for Write", err) + } + + // Repeat with a precondition that will pass. + if err := bucket.WriteAll(ctx, key, []byte(content), &blob.WriterOptions{ + BeforeWrite: func(asFunc func(any) bool) error { + var objp **storage.ObjectHandle + if !asFunc(&objp) { + return errors.New("Writer.As failed to get ObjectHandle") + } + // Replace the ObjectHandle with a new one that adds Conditions. + *objp = (*objp).If(storage.Conditions{DoesNotExist: true}) + return nil + }, + }); err != nil { + t.Errorf("got error %v, wanted nil", err) + } + defer bucket.Delete(ctx, key) + + // Try reading with a failing precondition. + _, err = bucket.NewReader(ctx, key, &blob.ReaderOptions{ + BeforeRead: func(asFunc func(any) bool) error { + var objp **storage.ObjectHandle + if !asFunc(&objp) { + return errors.New("Reader.As failed to get ObjectHandle") + } + // Replace the ObjectHandle with a new one. + *objp = (*objp).Generation(999999) + return nil + }, + }) + if err == nil || gcerrors.Code(err) != gcerrors.NotFound { + t.Errorf("got error %v, wanted NotFound for Read", err) + } + + attrs, err := bucket.Attributes(ctx, key) + if err != nil { + t.Fatal(err) + } + var oa storage.ObjectAttrs + if !attrs.As(&oa) { + t.Fatal("Attributes.As failed") + } + generation := oa.Generation + + // Repeat with a precondition that will pass. + reader, err := bucket.NewReader(ctx, key, &blob.ReaderOptions{ + BeforeRead: func(asFunc func(any) bool) error { + var objp **storage.ObjectHandle + if !asFunc(&objp) { + return errors.New("Reader.As failed to get ObjectHandle") + } + // Replace the ObjectHandle with a new one. + *objp = (*objp).Generation(generation) + return nil + }, + }) + if err != nil { + t.Fatal(err) + } + defer reader.Close() + gotBytes, err := io.ReadAll(reader) + if err != nil { + t.Fatal(err) + } + if got := string(gotBytes); got != content { + t.Errorf("got %q want %q", got, content) + } + + // Try copying with a failing precondition on Dst. + err = bucket.Copy(ctx, key2, key, &blob.CopyOptions{ + BeforeCopy: func(asFunc func(any) bool) error { + var coh *CopyObjectHandles + if !asFunc(&coh) { + return errors.New("Copy.As failed to get CopyObjectHandles") + } + // Replace the dst ObjectHandle with a new one. + coh.Dst = coh.Dst.If(storage.Conditions{GenerationMatch: -999}) + return nil + }, + }) + if err == nil || gcerrors.Code(err) != gcerrors.FailedPrecondition { + t.Errorf("got error %v, wanted FailedPrecondition for Copy", err) + } + + // Try copying with a failing precondition on Src. + err = bucket.Copy(ctx, key2, key, &blob.CopyOptions{ + BeforeCopy: func(asFunc func(any) bool) error { + var coh *CopyObjectHandles + if !asFunc(&coh) { + return errors.New("Copy.As failed to get CopyObjectHandles") + } + // Replace the src ObjectHandle with a new one. + coh.Src = coh.Src.Generation(9999999) + return nil + }, + }) + if err == nil || gcerrors.Code(err) != gcerrors.NotFound { + t.Errorf("got error %v, wanted NotFound for Copy", err) + } + + // Repeat with preconditions on Dst and Src that will succeed. + err = bucket.Copy(ctx, key2, key, &blob.CopyOptions{ + BeforeCopy: func(asFunc func(any) bool) error { + var coh *CopyObjectHandles + if !asFunc(&coh) { + return errors.New("Reader.As failed to get CopyObjectHandles") + } + coh.Dst = coh.Dst.If(storage.Conditions{DoesNotExist: true}) + coh.Src = coh.Src.Generation(generation) + return nil + }, + }) + if err != nil { + t.Error(err) + } + defer bucket.Delete(ctx, key2) +} + +func TestURLOpenerForParams(t *testing.T) { + ctx := context.Background() + + // Create a file for use as a dummy private key file. + privateKey := []byte("some content") + pkFile, err := os.CreateTemp("", "my-private-key") + if err != nil { + t.Fatal(err) + } + defer os.Remove(pkFile.Name()) + if _, err := pkFile.Write(privateKey); err != nil { + t.Fatal(err) + } + if err := pkFile.Close(); err != nil { + t.Fatal(err) + } + + tests := []struct { + name string + currOpts Options + query url.Values + wantOpts Options + wantClient bool + wantErr bool + }{ + { + name: "InvalidParam", + query: url.Values{ + "foo": {"bar"}, + }, + wantErr: true, + }, + { + name: "AccessID", + query: url.Values{ + "access_id": {"bar"}, + }, + wantOpts: Options{GoogleAccessID: "bar"}, + }, + { + name: "AccessID override", + currOpts: Options{GoogleAccessID: "foo"}, + query: url.Values{ + "access_id": {"bar"}, + }, + wantOpts: Options{GoogleAccessID: "bar"}, + }, + { + name: "AccessID override to - makes new client", + currOpts: Options{GoogleAccessID: "foo"}, + query: url.Values{ + "access_id": {"-"}, + }, + wantOpts: Options{}, // cleared + wantClient: true, + }, + { + name: "AccessID not overridden", + currOpts: Options{GoogleAccessID: "bar"}, + wantOpts: Options{GoogleAccessID: "bar"}, + }, + { + name: "Invalid value for anonymous", + query: url.Values{ + "anonymous": {"bad"}, + }, + wantErr: true, + }, + { + name: "Anonymous", + currOpts: Options{GoogleAccessID: "foo"}, + query: url.Values{ + "anonymous": {"true"}, + }, + wantOpts: Options{}, // cleared + wantClient: true, + }, + { + name: "BadPrivateKeyPath", + query: url.Values{ + "private_key_path": {"/path/does/not/exist"}, + }, + wantErr: true, + }, + { + name: "PrivateKeyPath", + query: url.Values{ + "private_key_path": {pkFile.Name()}, + }, + wantOpts: Options{PrivateKey: privateKey}, + }, + { + name: "PrivateKey cleared", + currOpts: Options{PrivateKey: privateKey}, + query: url.Values{ + "private_key_path": {""}, + }, + wantOpts: Options{}, + }, + { + name: "AccessID change clears PrivateKey and MakeSignBytes", + currOpts: Options{ + GoogleAccessID: "foo", + PrivateKey: privateKey, + MakeSignBytes: func(context.Context) SignBytesFunc { + return func([]byte) ([]byte, error) { + return nil, context.DeadlineExceeded + } + }, + }, + query: url.Values{ + "access_id": {"bar"}, + }, + wantOpts: Options{GoogleAccessID: "bar"}, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + o := &URLOpener{Options: test.currOpts} + got, gotClient, err := o.forParams(ctx, test.query) + if (err != nil) != test.wantErr { + t.Errorf("got err %v want error %v", err, test.wantErr) + } + if err != nil { + return + } + if diff := cmp.Diff(got, &test.wantOpts); diff != "" { + t.Errorf("opener.forParams(...) diff (-want +got):\n%s", diff) + } + if test.wantClient != (gotClient != nil) { + t.Errorf("opener.forParams client return value was unexpected, got %v want %v", gotClient != nil, test.wantClient) + } + }) + } +} + +func TestOpenBucketFromURL(t *testing.T) { + cleanup := setup.FakeGCPDefaultCredentials(t) + defer cleanup() + + pkFile, err := os.CreateTemp("", "my-private-key") + if err != nil { + t.Fatal(err) + } + defer os.Remove(pkFile.Name()) + if err := os.WriteFile(pkFile.Name(), []byte("key"), 0o666); err != nil { + t.Fatal(err) + } + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"gs://mybucket", false}, + // OK, setting access_id. + {"gs://mybucket?access_id=foo", false}, + // OK, setting private_key_path. + {"gs://mybucket?private_key_path=" + pkFile.Name(), false}, + // OK, clearing any pre-existing private key. + {"gs://mybucket?private_key_path=", false}, + // Invalid private_key_path. + {"gs://mybucket?private_key_path=invalid-path", true}, + // Invalid parameter. + {"gs://mybucket?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + b, err := blob.OpenBucket(ctx, test.URL) + if b != nil { + defer b.Close() + } + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + } +} + +func TestReadDefaultCredentials(t *testing.T) { + tests := []struct { + givenJSON string + WantAccessID string + WantPrivateKey []byte + }{ + // Variant A: service account file + { + `{ + "type": "service_account", + "project_id": "project-id", + "private_key_id": "key-id", + "private_key": "-----BEGIN PRIVATE KEY-----\nprivate-key\n-----END PRIVATE KEY-----\n", + "client_email": "service-account-email", + "client_id": "client-id", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://accounts.google.com/o/oauth2/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/service-account-email" + }`, + "service-account-email", + []byte("-----BEGIN PRIVATE KEY-----\nprivate-key\n-----END PRIVATE KEY-----\n"), + }, + // Variant A: credentials file absent a private key (stripped) + { + `{ + "google": {}, + "client_email": "service-account-email", + "client_id": "client-id" + }`, + "service-account-email", + []byte(""), + }, + // Variant B: obtained through the REST API + { + `{ + "name": "projects/project-id/serviceAccounts/service-account-email/keys/key-id", + "privateKeyType": "TYPE_GOOGLE_CREDENTIALS_FILE", + "privateKeyData": "private-key", + "validAfterTime": "date", + "validBeforeTime": "date", + "keyAlgorithm": "KEY_ALG_RSA_2048" + }`, + "service-account-email", + []byte("private-key"), + }, + // An empty input shall not throw an exception + {"", "", nil}, + } + + for i, test := range tests { + inJSON := []byte(test.givenJSON) + if len(test.givenJSON) == 0 { + inJSON = nil + } + + gotAccessID, gotPrivateKey := readDefaultCredentials(inJSON) + if gotAccessID != test.WantAccessID || string(gotPrivateKey) != string(test.WantPrivateKey) { + t.Errorf("Mismatched field values in case %d:\n -- got: %v, %v\n -- want: %v, %v", i, + gotAccessID, gotPrivateKey, + test.WantAccessID, test.WantPrivateKey, + ) + } + } +} + +func TestRemainingSignedURLSchemes(t *testing.T) { + tests := []struct { + name string + currOpts Options + wantSignedURL string // Not the actual URL, which is subject to change, but a mimickry. + wantErr bool + }{ + { + name: "no scheme available, error", + wantErr: true, + }, + { + name: "too many schemes configured", + currOpts: Options{ + GoogleAccessID: "foo", + PrivateKey: []byte("private-key"), + SignBytes: func([]byte) ([]byte, error) { + return []byte("signed"), nil + }, + }, + wantErr: true, + }, + { + name: "SignBytes", + currOpts: Options{ + GoogleAccessID: "foo", + SignBytes: func([]byte) ([]byte, error) { + return []byte("signed"), nil + }, + }, + wantSignedURL: "https://host/go-cloud-blob-test-bucket/some-key?GoogleAccessId=foo&Signature=c2lnbmVk", + }, + { + name: "MakeSignBytes is being used", + currOpts: Options{ + GoogleAccessID: "foo", + MakeSignBytes: func(context.Context) SignBytesFunc { + return func([]byte) ([]byte, error) { + return []byte("signed"), nil + } + }, + }, + wantSignedURL: "https://host/go-cloud-blob-test-bucket/some-key?GoogleAccessId=foo&Signature=c2lnbmVk", + }, + } + + ctx := context.Background() + signOpts := &driver.SignedURLOptions{ + Expiry: 30 * time.Second, + Method: http.MethodGet, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + bucket := bucket{name: bucketName, opts: &test.currOpts} + + // SignedURL doesn't check whether a key exists. + gotURL, gotErr := bucket.SignedURL(ctx, "some-key", signOpts) + if (gotErr != nil) != test.wantErr { + t.Errorf("Got unexpected error %v", gotErr) + } + if test.wantSignedURL == "" { + return + } + + got, _ := url.Parse(gotURL) + want, _ := url.Parse(test.wantSignedURL) + gotParams, wantParams := got.Query(), want.Query() + for _, param := range []string{"GoogleAccessId", "Signature"} { + if gotParams.Get(param) != wantParams.Get(param) { + // Print the full URL because the parameter might've not been set at all. + t.Errorf("Query parameter in SignedURL differs: %v\n -- got URL: %v\n -- want URL: %v", + param, got, want) + } + } + }) + } +} diff --git a/go-cloud/blob/gcsblob/iam.go b/go-cloud/blob/gcsblob/iam.go new file mode 100644 index 000000000..927793b91 --- /dev/null +++ b/go-cloud/blob/gcsblob/iam.go @@ -0,0 +1,74 @@ +// Copyright 2020 The Go Cloud Development Kit 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 +// +// https://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. + +// This is an implementation for Options.MakeSignBytes +// that serves as example for how to keep a private key in a separate +// process, service, or HSM/TPM, yet use it as signer for blob.Bucket. + +package gcsblob + +import ( + "context" + "sync" + + credentials "cloud.google.com/go/iam/credentials/apiv1" + "cloud.google.com/go/iam/credentials/apiv1/credentialspb" + gax "github.com/googleapis/gax-go/v2" +) + +// credentialsClient wraps the IAM Credentials API client for a lazy initialization +// and expresses it in the reduced format expected by SignBytes. +// See https://cloud.google.com/iam/docs/reference/credentials/rest +type credentialsClient struct { + init sync.Once + err error + + // client as reduced surface of credentials.IamCredentialsClient + // enables us to use a mock in tests. + client interface { + SignBlob(context.Context, *credentialspb.SignBlobRequest, ...gax.CallOption) (*credentialspb.SignBlobResponse, error) + } +} + +// CreateMakeSignBytesWith produces a MakeSignBytes variant from an expanded parameter set. +// It essentially adapts a remote call to the IAM Credentials API +// to the function signature expected by storage.SignedURLOptions.SignBytes. +func (c *credentialsClient) CreateMakeSignBytesWith(lifetimeCtx context.Context, googleAccessID string) func(context.Context) SignBytesFunc { + return func(requestCtx context.Context) SignBytesFunc { + c.init.Do(func() { + if c.client != nil { + // Set previously, likely to a mock implementation for tests. + return + } + c.client, c.err = credentials.NewIamCredentialsClient(lifetimeCtx) + }) + + return func(p []byte) ([]byte, error) { + if c.err != nil { + return nil, c.err + } + + resp, err := c.client.SignBlob( + requestCtx, + &credentialspb.SignBlobRequest{ + Name: googleAccessID, + Payload: p, + }) + if err != nil { + return nil, err + } + return resp.GetSignedBlob(), nil + } + } +} diff --git a/go-cloud/blob/gcsblob/iam_test.go b/go-cloud/blob/gcsblob/iam_test.go new file mode 100644 index 000000000..76819dace --- /dev/null +++ b/go-cloud/blob/gcsblob/iam_test.go @@ -0,0 +1,97 @@ +// Copyright 2020 The Go Cloud Development Kit 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 +// +// https://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 gcsblob + +import ( + "context" + "errors" + "testing" + + "cloud.google.com/go/iam/credentials/apiv1/credentialspb" + gax "github.com/googleapis/gax-go/v2" +) + +const ( + mockKey = "key0000" + mockSignature = "signature" +) + +type mockIAMClient struct { + requestErr error +} + +func (m mockIAMClient) SignBlob(context.Context, *credentialspb.SignBlobRequest, ...gax.CallOption) (*credentialspb.SignBlobResponse, error) { + if m.requestErr != nil { + return nil, m.requestErr + } + return &credentialspb.SignBlobResponse{KeyId: mockKey, SignedBlob: []byte(mockSignature)}, nil +} + +func TestIAMCredentialsClient(t *testing.T) { + tests := []struct { + name string + connectErr error + mockClient interface { + SignBlob(context.Context, *credentialspb.SignBlobRequest, ...gax.CallOption) (*credentialspb.SignBlobResponse, error) + } + + // These are for the produced SignBytesFunc + input []byte + wantOutput []byte + requestErr error + }{ + { + "happy path: signing", nil, + mockIAMClient{}, + []byte("payload"), []byte(mockSignature), nil, + }, + { + "won't connect", errors.New("Missing role: serviceAccountTokenCreator"), + mockIAMClient{}, + []byte("payload"), nil, nil, + }, + { + "request fails", nil, + mockIAMClient{requestErr: context.Canceled}, + []byte("payload"), nil, context.Canceled, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + c := credentialsClient{err: test.connectErr, client: test.mockClient} + makeSignBytesFn := c.CreateMakeSignBytesWith(context.TODO(), serviceAccountID) + + signBytesFn := makeSignBytesFn(nil) // Our mocks don't read any context. + haveOutput, haveErr := signBytesFn(test.input) + + if len(test.wantOutput) > 0 && string(haveOutput) != string(test.wantOutput) { + t.Errorf("Unexpected output:\n -- have: %v\n -- want: %v", + string(haveOutput), string(test.wantOutput)) + return + } + + if test.connectErr == nil && test.requestErr == nil { + return + } + if test.connectErr != nil && haveErr != test.connectErr { + t.Error("The connection error, a permanent error, has not been returned but should.") + } + if test.requestErr != nil && haveErr != test.requestErr { + t.Error("The per-request error has not been returned but should.") + } + }) + } +} diff --git a/go-cloud/blob/gcsblob/testdata/TestBeforeReadNonExistentKey.replay b/go-cloud/blob/gcsblob/testdata/TestBeforeReadNonExistentKey.replay new file mode 100644 index 000000000..ed77c9a18 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestBeforeReadNonExistentKey.replay @@ -0,0 +1,92 @@ +{ + "Initial": "AQAAAA7gDLzYEuE90QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "111666906b52f468", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/nonexistent-key", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "203" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:24 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_iZboCT1fVMNpJGGfMlMtVwyur2r4vH_oWaOvBSNDbrdhA3Xf5Lu4rWDrg7Vv_5OY" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ub25leGlzdGVudC1rZXk8L0RldGFpbHM+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..2aa40ffb1 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,583 @@ +{ + "Initial": "AQAAAA7gDLzXCQxhgwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "745514db699d95ce", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=mydir%2Fas-test\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsIm5hbWUiOiJteWRpci9hcy10ZXN0In0K", + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "785" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:23 GMT" + ], + "Etag": [ + "CLC2y+q1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-wKOjGvvaWn56l3c5M5pXT7X1wcQJOmQ-VCbWzfuFOAra4iRjMGlzBdCvRUR9BpgbQE43IlQM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbXlkaXIvYXMtdGVzdC8xNzUyODc2NTAzNDU2NTYwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL215ZGlyJTJGYXMtdGVzdCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL215ZGlyJTJGYXMtdGVzdD9nZW5lcmF0aW9uPTE3NTI4NzY1MDM0NTY1NjAmYWx0PW1lZGlhIiwibmFtZSI6Im15ZGlyL2FzLXRlc3QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY1MDM0NTY1NjAiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiIxMSIsIm1kNUhhc2giOiJYclk3dStBZTd0Q1R5eUs3ajFyTnd3PT0iLCJjcmMzMmMiOiJ5WlJscWc9PSIsImV0YWciOiJDTEMyeStxMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjIzLjQ1OVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoyMy40NTlaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjIzLjQ1OVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoyMy40NTlaIn0=" + } + }, + { + "ID": "04b9bc52a783b773", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/mydir%2Fas-test?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "785" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:23 GMT" + ], + "Etag": [ + "CLC2y+q1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89M__AdRx9vz0UY22-ZdChvmjUkzd19P8Ylx1eL4PCBO9aTtz5zIjyatIp3oJgw1g8" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbXlkaXIvYXMtdGVzdC8xNzUyODc2NTAzNDU2NTYwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL215ZGlyJTJGYXMtdGVzdCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL215ZGlyJTJGYXMtdGVzdD9nZW5lcmF0aW9uPTE3NTI4NzY1MDM0NTY1NjAmYWx0PW1lZGlhIiwibmFtZSI6Im15ZGlyL2FzLXRlc3QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY1MDM0NTY1NjAiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiIxMSIsIm1kNUhhc2giOiJYclk3dStBZTd0Q1R5eUs3ajFyTnd3PT0iLCJjcmMzMmMiOiJ5WlJscWc9PSIsImV0YWciOiJDTEMyeStxMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjIzLjQ1OVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoyMy40NTlaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjIzLjQ1OVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoyMy40NTlaIn0=" + } + }, + { + "ID": "22b18f086743185c", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/mydir%2Fas-test", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:23 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:23 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876503456560" + ], + "X-Goog-Hash": [ + "crc32c=yZRlqg==", + "md5=XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_ZHvBoi6BjH6W3Hi_gQmZLUaR2VfEcRr1yymSeCmqg1exZatA5mUjrE3IQwz8tX0c" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "a5ee52a9329fb144", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=mydir\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "48" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:23 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-nY8ASJcx_cb_dkPnm3m8I3LvTHWawuo4GYUkWh1u3yBh-OFY320eSlVZPHMEtmJuL" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsibXlkaXIvIl19" + } + }, + { + "ID": "bc881d4abbdb28bf", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=mydir%2Fas-test\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "822" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:23 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_KyaFDWfp1BDPC5qUcp-An2_bdiiwCuYgDoahNwkX9R5PrtVjMsFCiAXYy1jrGoPeU" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9teWRpci9hcy10ZXN0LzE3NTI4NzY1MDM0NTY1NjAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbXlkaXIlMkZhcy10ZXN0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbXlkaXIlMkZhcy10ZXN0P2dlbmVyYXRpb249MTc1Mjg3NjUwMzQ1NjU2MCZhbHQ9bWVkaWEiLCJuYW1lIjoibXlkaXIvYXMtdGVzdCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjUwMzQ1NjU2MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjExIiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsImNyYzMyYyI6InlaUmxxZz09IiwiZXRhZyI6IkNMQzJ5K3ExeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjMuNDU5WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjIzLjQ1OVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjMuNDU5WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjIzLjQ1OVoifV19" + } + }, + { + "ID": "1888509cf8fada8d", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key-does-not-exist", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "206" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:24 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-ZxX5w4yw8DOMvIAvR0xCAWkIdw7ES7RsaJkQBg6XiV4c_b1gdkH4gptUuDWY36fU" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9rZXktZG9lcy1ub3QtZXhpc3Q8L0RldGFpbHM+PC9FcnJvcj4=" + } + }, + { + "ID": "b351fc27453d63b1", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/mydir%2Fas-test/rewriteTo/b/go-cloud-blob-test-bucket/o/mydir%2Fas-test-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "908" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:24 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH895xCmgtHbHJiB5fsUFx5ibNLXk3gUVMREs2S8GvPU3JaMgb4cf6ttVUFBF0RRNXjlgVc_S3ZM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMTEiLCJvYmplY3RTaXplIjoiMTEiLCJkb25lIjp0cnVlLCJyZXNvdXJjZSI6eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbXlkaXIvYXMtdGVzdC1jb3B5LzE3NTI4NzY1MDQxMDkxNDkiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbXlkaXIlMkZhcy10ZXN0LWNvcHkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9teWRpciUyRmFzLXRlc3QtY29weT9nZW5lcmF0aW9uPTE3NTI4NzY1MDQxMDkxNDkmYWx0PW1lZGlhIiwibmFtZSI6Im15ZGlyL2FzLXRlc3QtY29weSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjUwNDEwOTE0OSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjExIiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsImNyYzMyYyI6InlaUmxxZz09IiwiZXRhZyI6IkNOMmc4K3ExeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjQuMTExWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjI0LjExMVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjQuMTExWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjI0LjExMVoifX0=" + } + }, + { + "ID": "c46ef853ab7f2467", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/mydir%2Fas-test-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:24 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_ujF3oLCYssGQfUMIMo5PW2FHq6oZOXC2Z5JaxjH-Fl1EPEI6VKXSn7UVBCay3TnzV" + ] + }, + "Body": "" + } + }, + { + "ID": "47975b07f569601a", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/mydir%2Fas-test?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:24 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89DbUNagWAtOIVMcNkp0GOzRDw4P4i2DMz0jfqp29sWf-a_yB0cOoQWRx_2-nYJ_qtwQS7_x4E" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay new file mode 100644 index 000000000..160dcfbaa --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay @@ -0,0 +1,586 @@ +{ + "Initial": "AQAAAA7gDLzVN1nyeQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "3b00cced45374120", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=mydir%2Fas-test\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudExhbmd1YWdlIjoibmwiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJtZDVIYXNoIjoiWHJZN3UrQWU3dENUeXlLN2oxck53dz09IiwibmFtZSI6Im15ZGlyL2FzLXRlc3QifQo=", + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "808" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:22 GMT" + ], + "Etag": [ + "COLQgOq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89miyfFMSWrnKq7iQdNIGYB-nFiiu6Up1xNYHGDyRA1l7UZbsq-d9P5p9dyozD5c54hxvBB__I" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbXlkaXIvYXMtdGVzdC8xNzUyODc2NTAyMjMxMTM4Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL215ZGlyJTJGYXMtdGVzdCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL215ZGlyJTJGYXMtdGVzdD9nZW5lcmF0aW9uPTE3NTI4NzY1MDIyMzExMzgmYWx0PW1lZGlhIiwibmFtZSI6Im15ZGlyL2FzLXRlc3QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY1MDIyMzExMzgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiIxMSIsIm1kNUhhc2giOiJYclk3dStBZTd0Q1R5eUs3ajFyTnd3PT0iLCJjb250ZW50TGFuZ3VhZ2UiOiJubCIsImNyYzMyYyI6InlaUmxxZz09IiwiZXRhZyI6IkNPTFFnT3ExeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjIuMjMzWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjIyLjIzM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjIuMjMzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjIyLjIzM1oifQ==" + } + }, + { + "ID": "99aa79d2f3c61c2b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/mydir%2Fas-test?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "808" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:22 GMT" + ], + "Etag": [ + "COLQgOq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8--_3hwgkrUnkc0otUcCHoteRWvo36Ur1vJNpTpCjdugNc7Pz1Bl5E9XX3j0JcTBgI" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbXlkaXIvYXMtdGVzdC8xNzUyODc2NTAyMjMxMTM4Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL215ZGlyJTJGYXMtdGVzdCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL215ZGlyJTJGYXMtdGVzdD9nZW5lcmF0aW9uPTE3NTI4NzY1MDIyMzExMzgmYWx0PW1lZGlhIiwibmFtZSI6Im15ZGlyL2FzLXRlc3QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY1MDIyMzExMzgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiIxMSIsIm1kNUhhc2giOiJYclk3dStBZTd0Q1R5eUs3ajFyTnd3PT0iLCJjb250ZW50TGFuZ3VhZ2UiOiJubCIsImNyYzMyYyI6InlaUmxxZz09IiwiZXRhZyI6IkNPTFFnT3ExeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjIuMjMzWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjIyLjIzM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjIuMjMzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjIyLjIzM1oifQ==" + } + }, + { + "ID": "eff2affeb98b28c4", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/mydir%2Fas-test", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:22 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:22 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876502231138" + ], + "X-Goog-Hash": [ + "crc32c=yZRlqg==", + "md5=XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH88RG56W5rLe0o8MwYbL-EYmCynX_RCmKm1u-aPbyOLeSmZd266Yo8qY_c3SlWLhc7Q" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "ed7a27d9d9280692", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=mydir\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "48" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:22 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_CyX-0RgoLz2-j6rNjQGjMJ6HCstKYaNrNGNwGLinasB_aIpxWxCl2CAc094Sh0Ptb" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsibXlkaXIvIl19" + } + }, + { + "ID": "9ac1c8a63f411d46", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=mydir%2Fas-test\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "845" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:22 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-4TDnci8KDUzRaAOzBF6_DE40PKUlSiY-Ft8QxSOTaZhilt1TbBUQMYIhm-9ciDL0" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9teWRpci9hcy10ZXN0LzE3NTI4NzY1MDIyMzExMzgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbXlkaXIlMkZhcy10ZXN0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbXlkaXIlMkZhcy10ZXN0P2dlbmVyYXRpb249MTc1Mjg3NjUwMjIzMTEzOCZhbHQ9bWVkaWEiLCJuYW1lIjoibXlkaXIvYXMtdGVzdCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjUwMjIzMTEzOCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjExIiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsImNvbnRlbnRMYW5ndWFnZSI6Im5sIiwiY3JjMzJjIjoieVpSbHFnPT0iLCJldGFnIjoiQ09MUWdPcTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoyMi4yMzNaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjIuMjMzWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoyMi4yMzNaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MjIuMjMzWiJ9XX0=" + } + }, + { + "ID": "6900c9ffc6d9494a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key-does-not-exist", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "206" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:22 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH88t0x_E-g3Mimm2iJvfvYkWdyW_kFGvRijyXUthI4qb_jzOIwESKZE-Uvb7p3z61-w" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9rZXktZG9lcy1ub3QtZXhpc3Q8L0RldGFpbHM+PC9FcnJvcj4=" + } + }, + { + "ID": "359df15120a1efad", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/mydir%2Fas-test/rewriteTo/b/go-cloud-blob-test-bucket/o/mydir%2Fas-test-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "931" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:22 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89tJgSgzx2AWWV_1LiesOhBqCxV5Z1kJukxTUaBEnfb_QBmTSqlxO_mC3wmcKUcgppi71xGtw4" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMTEiLCJvYmplY3RTaXplIjoiMTEiLCJkb25lIjp0cnVlLCJyZXNvdXJjZSI6eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbXlkaXIvYXMtdGVzdC1jb3B5LzE3NTI4NzY1MDI5Mjg1NjciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbXlkaXIlMkZhcy10ZXN0LWNvcHkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9teWRpciUyRmFzLXRlc3QtY29weT9nZW5lcmF0aW9uPTE3NTI4NzY1MDI5Mjg1NjcmYWx0PW1lZGlhIiwibmFtZSI6Im15ZGlyL2FzLXRlc3QtY29weSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjUwMjkyODU2NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjExIiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsImNvbnRlbnRMYW5ndWFnZSI6Im5sIiwiY3JjMzJjIjoieVpSbHFnPT0iLCJldGFnIjoiQ0xlWnErcTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoyMi45MzBaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjIuOTMwWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoyMi45MzBaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MjIuOTMwWiJ9fQ==" + } + }, + { + "ID": "67c892f0dca11691", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/mydir%2Fas-test-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:23 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88HjJbmax2z9SMdFk1waPMfakQGigE5WHoPBQkvU1MjoWMOO3VO7tYPc4ts9qGgfDNBJbDL3_c" + ] + }, + "Body": "" + } + }, + { + "ID": "a8254a358ca4c056", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/mydir%2Fas-test?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:23 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88WeKnCFSQTFT7Ohw_IWKqH-3VVS4VPIDZrR6XyyeFutvaBy67hkQEG8gPC2rFzu28od6Jmy-Q" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestAttributes.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestAttributes.replay new file mode 100644 index 000000000..653459c24 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestAttributes.replay @@ -0,0 +1,600 @@ +{ + "Initial": "AQAAAA7gDLyrMbkPAQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "a3821b605976f5ab", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=someDir%2Fblob-for-attributes\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY2FjaGVDb250cm9sIjoibm8tY2FjaGUiLCJjb250ZW50RGlzcG9zaXRpb24iOiJpbmxpbmUiLCJjb250ZW50RW5jb2RpbmciOiJpZGVudGl0eSIsImNvbnRlbnRMYW5ndWFnZSI6ImVuIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwibWQ1SGFzaCI6IjdRZGloMU11aGpaZWhCNlN2OFVOakE9PSIsIm5hbWUiOiJzb21lRGlyL2Jsb2ItZm9yLWF0dHJpYnV0ZXMifQo=", + "SGVsbG8gV29ybGQh" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "934" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:40 GMT" + ], + "Etag": [ + "CJ+s+NW1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-S2iRYHpL5Pl-51wAHgg6ECmtD1Me_6V6QSH5PnAt5sQ8OpipJGdl6d0bu6k8Z-g3a" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvc29tZURpci9ibG9iLWZvci1hdHRyaWJ1dGVzLzE3NTI4NzY0NjAxNTIzNTEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vc29tZURpciUyRmJsb2ItZm9yLWF0dHJpYnV0ZXMiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9zb21lRGlyJTJGYmxvYi1mb3ItYXR0cmlidXRlcz9nZW5lcmF0aW9uPTE3NTI4NzY0NjAxNTIzNTEmYWx0PW1lZGlhIiwibmFtZSI6InNvbWVEaXIvYmxvYi1mb3ItYXR0cmlidXRlcyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2MDE1MjM1MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjEyIiwibWQ1SGFzaCI6IjdRZGloMU11aGpaZWhCNlN2OFVOakE9PSIsImNvbnRlbnRFbmNvZGluZyI6ImlkZW50aXR5IiwiY29udGVudERpc3Bvc2l0aW9uIjoiaW5saW5lIiwiY29udGVudExhbmd1YWdlIjoiZW4iLCJjYWNoZUNvbnRyb2wiOiJuby1jYWNoZSIsImNyYzMyYyI6Ii9tengzQT09IiwiZXRhZyI6IkNKK3MrTlcxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDAuMTU0WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQwLjE1NFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDAuMTU0WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQwLjE1NFoifQ==" + } + }, + { + "ID": "096d22845f5b29a8", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/not-found?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "201" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:40 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88PPNZBPgZv1s3jrjV7nZGoUSNerrSBQ-DV5f4xBY23kpt2I_H3Y4n3RJ8V27dKxbw" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDQsIm1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ub3QtZm91bmQiLCJlcnJvcnMiOlt7Im1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ub3QtZm91bmQiLCJkb21haW4iOiJnbG9iYWwiLCJyZWFzb24iOiJub3RGb3VuZCJ9XX19" + } + }, + { + "ID": "80ff7bd63f87782d", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/someDir?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "197" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:40 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88BOpVtkxxm4ACvHtiI8gojkKOJd3MUpX8BQkIS63TsbkSNrhpU5JSrif4ICFiQNGcM" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDQsIm1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9zb21lRGlyIiwiZXJyb3JzIjpbeyJtZXNzYWdlIjoiTm8gc3VjaCBvYmplY3Q6IGdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvc29tZURpciIsImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIn1dfX0=" + } + }, + { + "ID": "8ffd5a128194125a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/someDir%2F?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "199" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:40 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_rZ07YU3hEBVQrSuGdKFqd4Ub-HwrhvglL4NSb9DlBGUMFh6eBrLOXv8fVO7LojfY" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDQsIm1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9zb21lRGlyLyIsImVycm9ycyI6W3sibWVzc2FnZSI6Ik5vIHN1Y2ggb2JqZWN0OiBnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3NvbWVEaXIvIiwiZG9tYWluIjoiZ2xvYmFsIiwicmVhc29uIjoibm90Rm91bmQifV19fQ==" + } + }, + { + "ID": "e1f10531c75e61f8", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/someDir%2Fblob-for-attributes?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "934" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:40 GMT" + ], + "Etag": [ + "CJ+s+NW1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8865UCZ3Z-fFfWxeuTy7XUJ4b8GPmZEyXwkbeN6QvAg0AjRM2mI0-6UmWPsNKQybqI" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvc29tZURpci9ibG9iLWZvci1hdHRyaWJ1dGVzLzE3NTI4NzY0NjAxNTIzNTEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vc29tZURpciUyRmJsb2ItZm9yLWF0dHJpYnV0ZXMiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9zb21lRGlyJTJGYmxvYi1mb3ItYXR0cmlidXRlcz9nZW5lcmF0aW9uPTE3NTI4NzY0NjAxNTIzNTEmYWx0PW1lZGlhIiwibmFtZSI6InNvbWVEaXIvYmxvYi1mb3ItYXR0cmlidXRlcyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2MDE1MjM1MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjEyIiwibWQ1SGFzaCI6IjdRZGloMU11aGpaZWhCNlN2OFVOakE9PSIsImNvbnRlbnRFbmNvZGluZyI6ImlkZW50aXR5IiwiY29udGVudERpc3Bvc2l0aW9uIjoiaW5saW5lIiwiY29udGVudExhbmd1YWdlIjoiZW4iLCJjYWNoZUNvbnRyb2wiOiJuby1jYWNoZSIsImNyYzMyYyI6Ii9tengzQT09IiwiZXRhZyI6IkNKK3MrTlcxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDAuMTU0WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQwLjE1NFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDAuMTU0WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQwLjE1NFoifQ==" + } + }, + { + "ID": "0722214aa483392f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/someDir%2Fblob-for-attributes", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "12" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:40 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:40 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876460152351" + ], + "X-Goog-Hash": [ + "crc32c=/mzx3A==", + "md5=7Qdih1MuhjZehB6Sv8UNjA==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "12" + ], + "X-Guploader-Uploadid": [ + "ABgVH88x9sX016HQn_Sm7MZwoVNgwA2a1eRLVwnNzAS44Xi4FrCuQUokWvrSadbNkmEpQy9P" + ] + }, + "Body": "SGVsbG8gV29ybGQh" + } + }, + { + "ID": "e631d1291d9acce0", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=someDir%2Fblob-for-attributes\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IjdRZGloMU11aGpaZWhCNlN2OFVOakE9PSIsIm5hbWUiOiJzb21lRGlyL2Jsb2ItZm9yLWF0dHJpYnV0ZXMifQo=", + "SGVsbG8gV29ybGQh" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "841" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:40 GMT" + ], + "Etag": [ + "CIfkpda1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89vQTB_JPFWMfL032HH6WxF9X1rGloe1r4IEcH_JytqCS0-und_IggYP3YarYazSqLe" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvc29tZURpci9ibG9iLWZvci1hdHRyaWJ1dGVzLzE3NTI4NzY0NjA4OTY3NzUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vc29tZURpciUyRmJsb2ItZm9yLWF0dHJpYnV0ZXMiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9zb21lRGlyJTJGYmxvYi1mb3ItYXR0cmlidXRlcz9nZW5lcmF0aW9uPTE3NTI4NzY0NjA4OTY3NzUmYWx0PW1lZGlhIiwibmFtZSI6InNvbWVEaXIvYmxvYi1mb3ItYXR0cmlidXRlcyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2MDg5Njc3NSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjEyIiwibWQ1SGFzaCI6IjdRZGloMU11aGpaZWhCNlN2OFVOakE9PSIsImNyYzMyYyI6Ii9tengzQT09IiwiZXRhZyI6IkNJZmtwZGExeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDAuOTA0WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQwLjkwNFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDAuOTA0WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQwLjkwNFoifQ==" + } + }, + { + "ID": "1c51d5768153c06f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/someDir%2Fblob-for-attributes?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "841" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:40 GMT" + ], + "Etag": [ + "CIfkpda1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_J_u2YmIfN98xzGksd9UiqW7xXkNNH1k_YyTLoDqGIeCcZbdgwwyY2tQVOTNzn0b0" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvc29tZURpci9ibG9iLWZvci1hdHRyaWJ1dGVzLzE3NTI4NzY0NjA4OTY3NzUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vc29tZURpciUyRmJsb2ItZm9yLWF0dHJpYnV0ZXMiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9zb21lRGlyJTJGYmxvYi1mb3ItYXR0cmlidXRlcz9nZW5lcmF0aW9uPTE3NTI4NzY0NjA4OTY3NzUmYWx0PW1lZGlhIiwibmFtZSI6InNvbWVEaXIvYmxvYi1mb3ItYXR0cmlidXRlcyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2MDg5Njc3NSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjEyIiwibWQ1SGFzaCI6IjdRZGloMU11aGpaZWhCNlN2OFVOakE9PSIsImNyYzMyYyI6Ii9tengzQT09IiwiZXRhZyI6IkNJZmtwZGExeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDAuOTA0WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQwLjkwNFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDAuOTA0WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQwLjkwNFoifQ==" + } + }, + { + "ID": "73710c4dab1a4eaa", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/someDir%2Fblob-for-attributes?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:41 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_E1-B0Je5ADDY9qXX1vz6a1Yc3eElKB8z9KEQV7nTOO3dJeBy6r_-4I2Ashh4VI8EW" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay new file mode 100644 index 000000000..036e8dd70 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay @@ -0,0 +1,319 @@ +{ + "Initial": "AQAAAA7gDLy1BQWCJwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "639d746dcbbcbcc3", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-canceled-write\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsIm5hbWUiOiJibG9iLWZvci1jYW5jZWxlZC13cml0ZSJ9Cg==", + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "821" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:49 GMT" + ], + "Etag": [ + "CNHmrNq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89WrVM00-QcJuIynfT1zCsr5A_8BgFLtg8ShIDqf5PMPf3MW28cYE9R2pYJJHWpCTM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItY2FuY2VsZWQtd3JpdGUvMTc1Mjg3NjQ2OTQwMDQwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1jYW5jZWxlZC13cml0ZSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWNhbmNlbGVkLXdyaXRlP2dlbmVyYXRpb249MTc1Mjg3NjQ2OTQwMDQwMSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItY2FuY2VsZWQtd3JpdGUiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0Njk0MDA0MDEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiIxMSIsIm1kNUhhc2giOiJYclk3dStBZTd0Q1R5eUs3ajFyTnd3PT0iLCJjcmMzMmMiOiJ5WlJscWc9PSIsImV0YWciOiJDTkhtck5xMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ5LjQwNFoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0OS40MDRaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ5LjQwNFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo0OS40MDRaIn0=" + } + }, + { + "ID": "4b824bbaecaf95b4", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-canceled-write", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:49 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:49 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876469400401" + ], + "X-Goog-Hash": [ + "crc32c=yZRlqg==", + "md5=XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH887Wx1lW1mZ9aGxFxNIaZ6fZoZZyNdwBuf-wzKWn29DVVApaot4ZpZmsFMcqcddQsq3" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "42f7dfcfd3043113", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-canceled-write", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:49 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:49 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876469400401" + ], + "X-Goog-Hash": [ + "crc32c=yZRlqg==", + "md5=XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH89q7auLkAxKnk59UJ9fXpYyOy1570TmtVjIm-cDXB83tjt_82ngHz2HZJjhzi9AOTg" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "0590db6b6b3e296f", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-canceled-write?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:49 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Ok06xbTDjfxLQard-dxvBlXe6NIxtO_lovgog3Mz0B1WJPHHMcwEBGvDSZAE5VkE" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay new file mode 100644 index 000000000..856aaa438 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay @@ -0,0 +1,144 @@ +{ + "Initial": "AQAAAA7gDLy0F8Ga6AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "33789ec6f7c813c1", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-canceled-write", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "211" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:48 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH89SgXv-D1gjAv7z8JIqoDg3OJmW0rfYQaXhdmidP4-VAep0B_X8lhYCMSuUxjelPVO8" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvRGV0YWlscz48L0Vycm9yPg==" + } + }, + { + "ID": "847e1193eba91b57", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-canceled-write", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "211" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:48 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH897zE8fiTWhHstpZpo_YTh9JnSKiYVtULAXQW_sBuxJY3DPpPp2yITnegzEpxfJ9JZ2" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvRGV0YWlscz48L0Vycm9yPg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay new file mode 100644 index 000000000..d423e96ab --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay @@ -0,0 +1,144 @@ +{ + "Initial": "AQAAAA7gDLy0KnS0wQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "6cdd791adedccdd2", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-canceled-write", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "211" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:49 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_S0W0nMpohYmsVgCo6ISMQO3TIhXzpWlCeKx0LwXT0Fg8lSLG3XWWe9rhSr_lqs9yE" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvRGV0YWlscz48L0Vycm9yPg==" + } + }, + { + "ID": "c227b09fa53e1864", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-canceled-write", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "211" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:49 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH88dQhlQ0fBFR1MpUujKVFMNn6bwF3PkQOOLZV1ItKUYqn4Tl4FMHIYVXU3_TDqnTPbg" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvRGV0YWlscz48L0Vycm9yPg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestConcurrentWriteAndRead.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestConcurrentWriteAndRead.replay new file mode 100644 index 000000000..79692ad1c --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestConcurrentWriteAndRead.replay @@ -0,0 +1,4020 @@ +{ + "Initial": "AQAAAA7gDLy1K5jqvQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "7b71df440f57e98b", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key19\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoiMnc5UzRhUnFLQUJIb2VBaHlpQUpNQT09IiwibmFtZSI6ImtleTE5In0K", + "ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEw==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "750" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CILh1dq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88aJb_0STFYmz9WT3jnydpKf3VTVH1Jb7tlcdUo2PgeSX7hQ-ANoAIrzlRx6xtg6Hg" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MTkvMTc1Mjg3NjQ3MDA3MTQyNiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkxOSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTE5P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA3MTQyNiZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MTkiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzAwNzE0MjYiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjQwOTYiLCJtZDVIYXNoIjoiMnc5UzRhUnFLQUJIb2VBaHlpQUpNQT09IiwiY3JjMzJjIjoiWVJyOXZ3PT0iLCJldGFnIjoiQ0lMaDFkcTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNzRaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDc0WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNzRaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDc0WiJ9" + } + }, + { + "ID": "b081b01482ac50cd", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key0\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoiWWc4TFo2a2ZmM1FWRzhXK2RGdHhFQT09IiwibmFtZSI6ImtleTAifQo=", + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "746" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CJOO09q1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89D7B-QpgnfFueMOGiEe-TNx7QHAYdGbJ736aKKKFvw2VuH829wuaxwxzYWVQKjrdM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MC8xNzUyODc2NDcwMDI4MDUxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkwP2dlbmVyYXRpb249MTc1Mjg3NjQ3MDAyODA1MSZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3MDAyODA1MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNDA5NiIsIm1kNUhhc2giOiJZZzhMWjZrZmYzUVZHOFcrZEZ0eEVBPT0iLCJjcmMzMmMiOiJtUGxCaVE9PSIsImV0YWciOiJDSk9PMDlxMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjAzMVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wMzFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjAzMVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wMzFaIn0=" + } + }, + { + "ID": "f4604690f7cbf3e4", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key15\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoicUhxeTNUT0NQTFdBQlovWVRFZWlBZz09IiwibmFtZSI6ImtleTE1In0K", + "Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "750" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CMSE1dq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8841DEoPAZxYXdoxdtpQAl0CumkfZ1NOe7s-avB_40Mssim8LG4ueJicGGVOXTu5pM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MTUvMTc1Mjg3NjQ3MDA1OTU4OCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkxNSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTE1P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA1OTU4OCZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MTUiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzAwNTk1ODgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjQwOTYiLCJtZDVIYXNoIjoicUhxeTNUT0NQTFdBQlovWVRFZWlBZz09IiwiY3JjMzJjIjoiWE9ZWlB3PT0iLCJldGFnIjoiQ01TRTFkcTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNjdaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDY3WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNjdaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDY3WiJ9" + } + }, + { + "ID": "26c3076ff5ba13a5", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key1\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoicW84NWxuM3JSQnB1ZElTV09VV3BZQT09IiwibmFtZSI6ImtleTEifQo=", + "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "746" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CN2M0tq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89HcsXF_y1Z1bjomS5ml5Xpvrxws8NjUYPpQ_2EU2cPlvWQOeCgPP9vQ-ib9RJc5sE" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MS8xNzUyODc2NDcwMDExNDg1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkxP2dlbmVyYXRpb249MTc1Mjg3NjQ3MDAxMTQ4NSZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3MDAxMTQ4NSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNDA5NiIsIm1kNUhhc2giOiJxbzg1bG4zclJCcHVkSVNXT1VXcFlBPT0iLCJjcmMzMmMiOiJRaGhyZnc9PSIsImV0YWciOiJDTjJNMHRxMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjAxNVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wMTVaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjAxNVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wMTVaIn0=" + } + }, + { + "ID": "cda328bc67c46000", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key5\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoiWWZSYUtRa0cwV3YxVWVlTXNEMWYrUT09IiwibmFtZSI6ImtleTUifQo=", + "BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "746" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CIDF1Nq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_timxZszS2HR7JiOLB_A4JIO-Sja1waD_wA-YhSLiPmoVBwTqyNl0JD-P4hUq-y8s" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5NS8xNzUyODc2NDcwMDUxNDU2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTUiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXk1P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA1MTQ1NiZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5NSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3MDA1MTQ1NiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNDA5NiIsIm1kNUhhc2giOiJZZlJhS1FrRzBXdjFVZWVNc0QxZitRPT0iLCJjcmMzMmMiOiJKNmhidEE9PSIsImV0YWciOiJDSURGMU5xMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA1M1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNTNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA1M1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNTNaIn0=" + } + }, + { + "ID": "cb267f4fef6fa7d3", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key11\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoiQWJEbVdSOTZmMVZJRm5XNEpRNS9TQT09IiwibmFtZSI6ImtleTExIn0K", + "CwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCw==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "750" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CMfb1tq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Oz6pNzcec8N4zJUYOIhS1_3i8V2kvVEodHUeHx9gpLQs05GOeDhkrf-obkuR1Kqo" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MTEvMTc1Mjg3NjQ3MDA4NzExMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkxMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTExP2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA4NzExMSZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzAwODcxMTEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjQwOTYiLCJtZDVIYXNoIjoiQWJEbVdSOTZmMVZJRm5XNEpRNS9TQT09IiwiY3JjMzJjIjoiT1ZZcDlBPT0iLCJldGFnIjoiQ01mYjF0cTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wODlaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDg5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wODlaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDg5WiJ9" + } + }, + { + "ID": "88ec6cf990bb8bdc", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key17\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoiMzJlZVhzajdaeWhDbDBvMjB3UFEvdz09IiwibmFtZSI6ImtleTE3In0K", + "EREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "750" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CL/+09q1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89vJ8dN9G2qfcEkncJ7WbUu2ZfcGJiyemrVqC-XDU9eJ6VOHCfcV_eHwHXXvzBNz_gF" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MTcvMTc1Mjg3NjQ3MDA0MjQzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkxNyIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTE3P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA0MjQzMSZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MTciLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzAwNDI0MzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjQwOTYiLCJtZDVIYXNoIjoiMzJlZVhzajdaeWhDbDBvMjB3UFEvdz09IiwiY3JjMzJjIjoiMFRUZW9nPT0iLCJldGFnIjoiQ0wvKzA5cTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNDVaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDQ1WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNDVaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDQ1WiJ9" + } + }, + { + "ID": "1f44773310cc2ef0", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key13\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlNzVHpGWjNtN1IxTnJJYzQyVUtXK1E9PSIsIm5hbWUiOiJrZXkxMyJ9Cg==", + "DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "751" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CIHH1Nq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89kTP1jdd-YXtVoN51fhD-VNjdUIpysIB9Z8Njw8TBmM2B7mf8l-xEyFfCcbaHwIRA" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MTMvMTc1Mjg3NjQ3MDA1MTcxMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkxMyIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTEzP2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA1MTcxMyZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MTMiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzAwNTE3MTMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI0MDk2IiwibWQ1SGFzaCI6IlNzVHpGWjNtN1IxTnJJYzQyVUtXK1E9PSIsImNyYzMyYyI6IjdNZzZJZz09IiwiZXRhZyI6IkNJSEgxTnExeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDY3WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA2N1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDY3WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA2N1oifQ==" + } + }, + { + "ID": "94cbdd31950adeba", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key12\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlZrR1ErM0xKc2VIQUZvcGJiK0JZdmc9PSIsIm5hbWUiOiJrZXkxMiJ9Cg==", + "DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "751" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CJGa1tq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Np3-hnWyV6Bbfv-GKYonBlcjPXqkl3pebjgU2REv9-NZZrwOmbSRRHflGGBezOUA0" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MTIvMTc1Mjg3NjQ3MDA3ODczNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkxMiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTEyP2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA3ODczNyZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzAwNzg3MzciLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI0MDk2IiwibWQ1SGFzaCI6IlZrR1ErM0xKc2VIQUZvcGJiK0JZdmc9PSIsImNyYzMyYyI6Ik5pa1ExQT09IiwiZXRhZyI6IkNKR2ExdHExeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA4MVoifQ==" + } + }, + { + "ID": "181773f74ea0f2a6", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key14\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoiTmxGRFVGTTBUcEYxUytNWEUxUHhEZz09IiwibmFtZSI6ImtleTE0In0K", + "Dg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "750" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CKy71Nq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-zvPRUjo-1LUz3ExwzjUlcqkm5ZzakPFoDPQPgJVLcdFoOv2B-y0rJjru-X4V4dcA" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MTQvMTc1Mjg3NjQ3MDA1MDIyMCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkxNCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTE0P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA1MDIyMCZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MTQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzAwNTAyMjAiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjQwOTYiLCJtZDVIYXNoIjoiTmxGRFVGTTBUcEYxUytNWEUxUHhEZz09IiwiY3JjMzJjIjoiaGdjenlRPT0iLCJldGFnIjoiQ0t5NzFOcTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNTNaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDUzWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNTNaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDUzWiJ9" + } + }, + { + "ID": "7bca47153ee78345", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key18\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoid1p2STFNdE9nQU5HUUQwZ3paNE5VZz09IiwibmFtZSI6ImtleTE4In0K", + "EhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "750" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CKnl1dq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Xpk3_liH9Z5Y1Ew3ZKf6K5Ryy--HYzr1q-AuGmfdUHUM6ZtRNMd8nw-I0Z63xnLdM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MTgvMTc1Mjg3NjQ3MDA3MTk3NyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkxOCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTE4P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA3MTk3NyZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MTgiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzAwNzE5NzciLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjQwOTYiLCJtZDVIYXNoIjoid1p2STFNdE9nQU5HUUQwZ3paNE5VZz09IiwiY3JjMzJjIjoidS92WFNRPT0iLCJldGFnIjoiQ0tubDFkcTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wODBaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDgwWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wODBaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDgwWiJ9" + } + }, + { + "ID": "a7d6dd4018ae631a", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key2\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoiWlVIbi9VaG9DNXRnN0FWZXY2TWNBZz09IiwibmFtZSI6ImtleTIifQo=", + "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "746" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:49 GMT" + ], + "Etag": [ + "CI23zdq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-pc69zlgOCxrdGt-xdV0dSqc7NFxkm16lZ-dr-Gt2WcoczClwPB1dZO8N6MgRn3dXR" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5Mi8xNzUyODc2NDY5OTM0OTg5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkyP2dlbmVyYXRpb249MTc1Mjg3NjQ2OTkzNDk4OSZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2OTkzNDk4OSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNDA5NiIsIm1kNUhhc2giOiJaVUhuL1Vob0M1dGc3QVZldjZNY0FnPT0iLCJjcmMzMmMiOiJLTmRpbEE9PSIsImV0YWciOiJDSTIzemRxMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ5LjkzOFoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0OS45MzhaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ5LjkzOFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo0OS45MzhaIn0=" + } + }, + { + "ID": "7adb96f0fc781e2d", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key16\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoiNjVuOUNqZHJKa05RRWFHNGZGV01nUT09IiwibmFtZSI6ImtleTE2In0K", + "EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "750" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CMv009q1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH893khtwD_KGhFqjyV9Hv4wC-oELRk8B0qcBYJGjc_v3jqfb1o71cZF3OuZsSJ4EwNU" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MTYvMTc1Mjg3NjQ3MDA0MTE2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkxNiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTE2P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA0MTE2MyZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MTYiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzAwNDExNjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6ImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjQwOTYiLCJtZDVIYXNoIjoiNjVuOUNqZHJKa05RRWFHNGZGV01nUT09IiwiY3JjMzJjIjoiQzlYMFZBPT0iLCJldGFnIjoiQ012MDA5cTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNDNaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDQzWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNDNaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDQzWiJ9" + } + }, + { + "ID": "9360df8d2dd03aaf", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key9\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6Imtmc2l1S1JaNzNEN0N6YXVLb2RBaGc9PSIsIm5hbWUiOiJrZXk5In0K", + "CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "747" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CLPk1dq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-XvEb6V7v2YDAyb80K1JwdxAPyLXUMFLUAUT8re9DikLPiebTc28EoizL11gVpEJo" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5OS8xNzUyODc2NDcwMDcxODU5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXk5P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA3MTg1OSZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5OSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3MDA3MTg1OSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjQwOTYiLCJtZDVIYXNoIjoia2ZzaXVLUlo3M0Q3Q3phdUtvZEFoZz09IiwiY3JjMzJjIjoiaVhnSzZRPT0iLCJldGFnIjoiQ0xQazFkcTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wODBaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDgwWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wODBaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDgwWiJ9" + } + }, + { + "ID": "ec7577006a552c00", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key10\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IkFYS0sxSlZjWjc5MUt4Y2hJWFlOTmc9PSIsIm5hbWUiOiJrZXkxMCJ9Cg==", + "CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "751" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "COmo19q1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-cxZY_QUXA2vHkqlkHX7qyASUXv9_FH2-8w4AVWqR-wLodbIE6BSWRy2POaJohgIqn" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5MTAvMTc1Mjg3NjQ3MDA5NzAwMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkxMCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTEwP2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA5NzAwMSZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MTAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzAwOTcwMDEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI0MDk2IiwibWQ1SGFzaCI6IkFYS0sxSlZjWjc5MUt4Y2hJWFlOTmc9PSIsImNyYzMyYyI6IjQ3Y0RBZz09IiwiZXRhZyI6IkNPbW8xOXExeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDk5WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA5OVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTAuMDk5WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA5OVoifQ==" + } + }, + { + "ID": "75b03f4ffd53bf6d", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key7\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoia2J1aVRwNUpFdWdqd0FrZ3p0UG9YQT09IiwibmFtZSI6ImtleTcifQo=", + "BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "746" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CKqo1dq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_Im2Xp0RHmGuQukFuQwoA0bGdtruYt7u_dHoU9D9F_qwHXgKJ-z4KjqGr9d1-IjCE" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5Ny8xNzUyODc2NDcwMDY0MTcwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXk3P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA2NDE3MCZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5NyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3MDA2NDE3MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNDA5NiIsIm1kNUhhc2giOiJrYnVpVHA1SkV1Z2p3QWtnenRQb1hBPT0iLCJjcmMzMmMiOiJsNFo0cVE9PSIsImV0YWciOiJDS3FvMWRxMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA2N1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNjdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA2N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNjdaIn0=" + } + }, + { + "ID": "f8857be122d1018a", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key6\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoibGtvMnVEcW9KcmdFeVlObnZjSjZ2dz09IiwibmFtZSI6ImtleTYifQo=", + "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "746" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "COve1tq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_M1Y0Ri25r8mT4Ihw95LhmN0rHCj5jEzTyEP0yeDORk-qVbviz4R2hY9ITrqA2reE" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5Ni8xNzUyODc2NDcwMDg3NTMxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTYiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXk2P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA4NzUzMSZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5NiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3MDA4NzUzMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNDA5NiIsIm1kNUhhc2giOiJsa28ydURxb0pyZ0V5WU5udmNKNnZ3PT0iLCJjcmMzMmMiOiJUV2RTWHc9PSIsImV0YWciOiJDT3ZlMXRxMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA5MFoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wOTBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA5MFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wOTBaIn0=" + } + }, + { + "ID": "ee0a43383864ed3a", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key8\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoicVBaUEUwdUFHQk5LRTZMaEVRVEE4UT09IiwibmFtZSI6ImtleTgifQo=", + "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "746" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CJnJ1dq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_dL2DB3MTY5k81ZMJADk21eYhCWYHXALi392Mewom4k535yu_qShI7Lk9QKPFf7b0" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5OC8xNzUyODc2NDcwMDY4Mzc3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTgiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXk4P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA2ODM3NyZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5OCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3MDA2ODM3NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNDA5NiIsIm1kNUhhc2giOiJxUFpQRTB1QUdCTktFNkxoRVFUQThRPT0iLCJjcmMzMmMiOiJVNWtnSHc9PSIsImV0YWciOiJDSm5KMWRxMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA3MFoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNzBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA3MFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNzBaIn0=" + } + }, + { + "ID": "f04d3c69417429b7", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key3\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoiN3RCUE95S0lvMG9tWU9tYk4zSHQ3dz09IiwibmFtZSI6ImtleTMifQo=", + "AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "746" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CIaO1tq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-UiRe8Ksb5eUhzSN93lDb1qIiC35NUtrn_K0FU8Lq7GIO9hNEI1t4XQI3D3J2Ub3OL" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5My8xNzUyODc2NDcwMDc3MTkwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTMiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXkzP2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA3NzE5MCZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5MyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3MDA3NzE5MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNDA5NiIsIm1kNUhhc2giOiI3dEJQT3lLSW8wb21ZT21iTjNIdDd3PT0iLCJjcmMzMmMiOiI4alpJWWc9PSIsImV0YWciOiJDSWFPMXRxMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA4MFoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wODBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA4MFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wODBaIn0=" + } + }, + { + "ID": "b223fbdc02f0dc26", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=key4\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0iLCJtZDVIYXNoIjoiSDA2anlGM1pzSkRPY3d5QjVnZyt6dz09IiwibmFtZSI6ImtleTQifQo=", + "BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "746" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "CNLT1Nq1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_EWL_GcpasMG4-yzwElObNHFHW_pG3OLyNKKWu0-LADuGjkJHhTyo4QZFkg2vgYsK8" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQva2V5NC8xNzUyODc2NDcwMDUzMzMwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2tleTQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9rZXk0P2dlbmVyYXRpb249MTc1Mjg3NjQ3MDA1MzMzMCZhbHQ9bWVkaWEiLCJuYW1lIjoia2V5NCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3MDA1MzMzMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNDA5NiIsIm1kNUhhc2giOiJIMDZqeUYzWnNKRE9jd3lCNWdnK3p3PT0iLCJjcmMzMmMiOiIvVWx4UWc9PSIsImV0YWciOiJDTkxUMU5xMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA2N1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNjdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUwLjA2N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1MC4wNjdaIn0=" + } + }, + { + "ID": "657a51c6ecf12616", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key6", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"964a36b83aa826b804c98367bdc27abf\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470087531" + ], + "X-Goog-Hash": [ + "crc32c=TWdSXw==", + "md5=lko2uDqoJrgEyYNnvcJ6vw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_NjDqtTNrZYhx-NTtnFAMoJTJcFU-8DmqGd2RuR-pG7Y2z8Wfs22RkmpK0IXE-b_Ko" + ] + }, + "Body": "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg==" + } + }, + { + "ID": "16e3994508fd6fcd", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key5", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"61f45a290906d16bf551e78cb03d5ff9\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470051456" + ], + "X-Goog-Hash": [ + "crc32c=J6hbtA==", + "md5=YfRaKQkG0Wv1UeeMsD1f+Q==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH89bd5Q8ZdY0_3BKe8jDX6-yPXW-1MgHgVR37NWwyGQHNeNi5504tKM4kgY2N44K4bI" + ] + }, + "Body": "BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ==" + } + }, + { + "ID": "4f5888b544ab752b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key14", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"3651435053344e91754be3171353f10e\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470050220" + ], + "X-Goog-Hash": [ + "crc32c=hgczyQ==", + "md5=NlFDUFM0TpF1S+MXE1PxDg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Rk0WXVK7BF31T_bbO1OZO9wO3pzFHffPqxxW_Ct3tow3c7QfD6m9CEg9E_hlAI07s" + ] + }, + "Body": "Dg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg==" + } + }, + { + "ID": "d5cfdfee717ef020", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key11", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"01b0e6591f7a7f55481675b8250e7f48\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470087111" + ], + "X-Goog-Hash": [ + "crc32c=OVYp9A==", + "md5=AbDmWR96f1VIFnW4JQ5/SA==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH88BGTQ2kkrqDj4Ja7y2jooUT1YSY2Dz8-e3UGCsZxS4KG4_ECsqzXj_HJPJjRVWco53" + ] + }, + "Body": "CwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCw==" + } + }, + { + "ID": "5e54e14266fcb741", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key3", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"eed04f3b2288a34a2660e99b3771edef\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470077190" + ], + "X-Goog-Hash": [ + "crc32c=8jZIYg==", + "md5=7tBPOyKIo0omYOmbN3Ht7w==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH882dT1hsDWiwS1kHYqxvaZ_AwMxYPDpzxowfo-tMGUktTvSduQzvcNu5WEaZ5AFLNw" + ] + }, + "Body": "AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw==" + } + }, + { + "ID": "4a57d003c15b2893", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key9", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"91fb22b8a459ef70fb0b36ae2a874086\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470071859" + ], + "X-Goog-Hash": [ + "crc32c=iXgK6Q==", + "md5=kfsiuKRZ73D7CzauKodAhg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH89hLhe5CurUvzbNF9MCUaLKktCBrS0kqXeOmggkny4DuCZ_U1XDBzs0B9wDYTwF5Mw" + ] + }, + "Body": "CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQ==" + } + }, + { + "ID": "adda3a031cc24cfa", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key18", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"c19bc8d4cb4e800346403d20cd9e0d52\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470071977" + ], + "X-Goog-Hash": [ + "crc32c=u/vXSQ==", + "md5=wZvI1MtOgANGQD0gzZ4NUg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH88fMyU4_tHRnNht6FgQseICa1K0q7RHt6d20j2zqCyGqz0CK-L86OidlmHxMXeHcls" + ] + }, + "Body": "EhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEg==" + } + }, + { + "ID": "fcfc189cfedf4f3b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key15", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"a87ab2dd33823cb580059fd84c47a202\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470059588" + ], + "X-Goog-Hash": [ + "crc32c=XOYZPw==", + "md5=qHqy3TOCPLWABZ/YTEeiAg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-wEbjY0TQKWum9uVBumYSE7CAQh6TfqkzW_HZcK72a_coXo7_zFCevMGL2Uk1jpMse" + ] + }, + "Body": "Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw==" + } + }, + { + "ID": "2029a61e816a0fa4", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key8", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"a8f64f134b8018134a13a2e11104c0f1\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470068377" + ], + "X-Goog-Hash": [ + "crc32c=U5kgHw==", + "md5=qPZPE0uAGBNKE6LhEQTA8Q==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-VoLh8KDVXrMhDTssspLsytDt9BJKvnqa9l3bxHWx0q-PRhqCm0HsJxfUjMRc3Tws" + ] + }, + "Body": "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA==" + } + }, + { + "ID": "a6753d22d57e32e2", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key16", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"eb99fd0a376b26435011a1b87c558c81\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470041163" + ], + "X-Goog-Hash": [ + "crc32c=C9X0VA==", + "md5=65n9CjdrJkNQEaG4fFWMgQ==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-L18pMyMF2CodeMhkpJc0UAKyvV9NBsqV_MDud0z7g6kLk_UrEehSj-1v3qukxW84" + ] + }, + "Body": "EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEA==" + } + }, + { + "ID": "353604e33874ab68", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key17", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"df679e5ec8fb672842974a36d303d0ff\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470042431" + ], + "X-Goog-Hash": [ + "crc32c=0TTeog==", + "md5=32eeXsj7ZyhCl0o20wPQ/w==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Og68EKxyoVc_FdJYMN92LH4fmCF5wKfITtDABz68fHti-sJJzn7HIky56MWV3s-Q" + ] + }, + "Body": "EREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQ==" + } + }, + { + "ID": "a4368a75f3fe745d", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key7", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"91bba24e9e4912e823c00920ced3e85c\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470064170" + ], + "X-Goog-Hash": [ + "crc32c=l4Z4qQ==", + "md5=kbuiTp5JEugjwAkgztPoXA==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH89g4_ZjADQFSDpfFgNn7SZcuqVzg-EQ1Kz3Ec4JxjUfRaJyq1QPU3Gwl1UlEqF1B-k" + ] + }, + "Body": "BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw==" + } + }, + { + "ID": "ce25e135b03fb296", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key19", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"db0f52e1a46a280047a1e021ca200930\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470071426" + ], + "X-Goog-Hash": [ + "crc32c=YRr9vw==", + "md5=2w9S4aRqKABHoeAhyiAJMA==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-vQP82kPCaG2U2DlzHD42JbIM_6XhKWa1Bg7K5nyFO3_f11jvz0v8BLkJ4AhFXHQY" + ] + }, + "Body": "ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEw==" + } + }, + { + "ID": "ed704274018dd027", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key10", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"01728ad4955c67bf752b172121760d36\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470097001" + ], + "X-Goog-Hash": [ + "crc32c=47cDAg==", + "md5=AXKK1JVcZ791KxchIXYNNg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_HXoSIhFmGOJOxVMbC_zd90f-P9G5EQqm3nUnZca3JT5FCz4Mk9K03gbGaWrvRuy7A" + ] + }, + "Body": "CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg==" + } + }, + { + "ID": "1202048921ac29a4", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key0", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"620f0b67a91f7f74151bc5be745b7110\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470028051" + ], + "X-Goog-Hash": [ + "crc32c=mPlBiQ==", + "md5=Yg8LZ6kff3QVG8W+dFtxEA==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH89FBS8qatyrVQTp2vnTZzq5yVyOW5WiMlODYN46Rn2q4xl0MXylTl-y-McPy2Z631g" + ] + }, + "Body": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" + } + }, + { + "ID": "f43179aef5d82016", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key12", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"564190fb72c9b1e1c0168a5b6fe058be\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470078737" + ], + "X-Goog-Hash": [ + "crc32c=NikQ1A==", + "md5=VkGQ+3LJseHAFopbb+BYvg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH89ERoDnb9UNTLFMXp4oBYzmG3oiAnoaNuEsGR9YRWbUcXE4jNSkBLiPTlS-QyZMcrU" + ] + }, + "Body": "DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA==" + } + }, + { + "ID": "da2ef942c8f7833a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key2", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"6541e7fd48680b9b60ec055ebfa31c02\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:49 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876469934989" + ], + "X-Goog-Hash": [ + "crc32c=KNdilA==", + "md5=ZUHn/UhoC5tg7AVev6McAg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH89X5Ij07KVY65tgXrdByMF3mnZl-kainjSUz8hgE0zooL3yHFSQ_5bT-e0YucyuAlk" + ] + }, + "Body": "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg==" + } + }, + { + "ID": "0fa86923f763334b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key13", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"4ac4f3159de6ed1d4dac8738d94296f9\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470051713" + ], + "X-Goog-Hash": [ + "crc32c=7Mg6Ig==", + "md5=SsTzFZ3m7R1NrIc42UKW+Q==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_pxymqZlMaXngoUxOe5V6BGfsITtyx6se2m3h3Fh5GraOiqiWe0OrE18IF_2JS7u0" + ] + }, + "Body": "DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ==" + } + }, + { + "ID": "ca5a301a8b3e1af3", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key4", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"1f4ea3c85dd9b090ce730c81e6083ecf\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470053330" + ], + "X-Goog-Hash": [ + "crc32c=/UlxQg==", + "md5=H06jyF3ZsJDOcwyB5gg+zw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH88ofg4NKX5Kl8ZWyR8EK0Ej5nNFgiBsDR6_RE-qXy1QXlxXZi3o2mRH8yVC2zqdTr4" + ] + }, + "Body": "BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA==" + } + }, + { + "ID": "db1857cd3a17fc2a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key1", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Etag": [ + "\"aa8f39967deb441a6e7484963945a960\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876470011485" + ], + "X-Goog-Hash": [ + "crc32c=Qhhrfw==", + "md5=qo85ln3rRBpudISWOUWpYA==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "4096" + ], + "X-Guploader-Uploadid": [ + "ABgVH89znytrYsoBkacQuV0bUf41RvuBqRpobA66HIGSEBY2szFmAWwMOKopMdl2zmKb4HQ" + ] + }, + "Body": "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ==" + } + }, + { + "ID": "a6c5fedfa8aca9be", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key19?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH881qGajgEFir3vW6jkrHv7y4sfgPPEx9unhKNM8byMtR_R7r0mQJ9Nktai9keGc2rY" + ] + }, + "Body": "" + } + }, + { + "ID": "53449ebb02f322b3", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key18?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-l7eBBP_dbzYqe_bJMmkYrxWnAOmFyKpfry4yJMCyp9uVy-8nktPiGiCEL_4o3CAo" + ] + }, + "Body": "" + } + }, + { + "ID": "13c908e875e6d50a", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key17?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_uTu1etg0KQU9mFVkjB7CQAWZUoYzx0yIqhxuEajtRBeNxfJMawVucvQwBD9GuCniZ" + ] + }, + "Body": "" + } + }, + { + "ID": "fc837752b2883037", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key16?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:50 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-jGm7KwZcyzdhQy0SGP4cdMXKrdx8o6ssLqW0Wa0MGvTwZ1dJNI5m2UR6-F3xK324L" + ] + }, + "Body": "" + } + }, + { + "ID": "d5e66a3ccc7872f6", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key15?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:51 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89B8iW2FT-feWkm4Afjimoleq8y5nOBDwDNazzwWi0uZQF2s7hlOyAfkLsvRqTgCh8" + ] + }, + "Body": "" + } + }, + { + "ID": "0a04b94056eea766", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key14?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:51 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_3avdiwNZpHcY9rr6iSe89rc-CQnpAHUl8I0w9Id-8QdP5wwowLdpxZr2w6udlF5A" + ] + }, + "Body": "" + } + }, + { + "ID": "c7be257fd45f6242", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key13?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:51 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_eCeeYbzzWPow71WBXyk7wPgzzAcHAYKbOH02Lj-zyeeKshMEwhRRxsQHTNrvMGaS2" + ] + }, + "Body": "" + } + }, + { + "ID": "4847f71230eb4438", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key12?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:51 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_TyzN4P5O2c04C_geGm5uabpXD_T5V9K6G3frdwVMBr22LvTBZFRqPX_ovEDXg_Gs" + ] + }, + "Body": "" + } + }, + { + "ID": "f6eee67599376fcc", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key11?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:51 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88PShgS1Iw6Mf6RJ-ltoTsoBCuLFp9Y5Fjf391llBlznCfX9aN5E4rpaXkIOOMVA6A" + ] + }, + "Body": "" + } + }, + { + "ID": "3ff0062213acc3d2", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key10?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:51 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_2EA0-3rooWVzm_bXpR5Vdg5AYalvRq1oil7ApwR0ZOCRn82oXr0wnNOzAfWCs9k0" + ] + }, + "Body": "" + } + }, + { + "ID": "c28d8b73a4d938a0", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key9?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:51 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_fYJT4E8RyiCf7OStcHcKEpEOZ6XCvMKgWthbUi1C_W9a96cawgVUhfDlzyP5lgQ4" + ] + }, + "Body": "" + } + }, + { + "ID": "8e1cbb76d94f9fb8", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key8?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:51 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89kUOFWs_DaBNYQq8YVfGnr09SkfWMUWOKYn_XJffARdKsdvkvpjnGqne10LqkfeZM" + ] + }, + "Body": "" + } + }, + { + "ID": "264188123ead3b62", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key7?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:51 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-ziJZJcyu_mFltcpniNXvktdc5kZICcUehASdLehNG5jIYWbAtx4ltKFh22CNr5V_R" + ] + }, + "Body": "" + } + }, + { + "ID": "eac7640ac1e54a1a", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key6?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:51 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89HqSFoH5sQN--vUXqzu5M_X1vpMerpd3RfEBS0biHsJLbcIAk7uX9wDSHDTfnnJa7x" + ] + }, + "Body": "" + } + }, + { + "ID": "e423c4dde2db127b", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key5?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:52 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89PSCzigLpU61CGqaR0lscumpG5yhckEONv597CTw4SqxEiYxnF5LTXUsBBr7PhZTos" + ] + }, + "Body": "" + } + }, + { + "ID": "945c1a561ef9566f", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key4?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:52 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_N7D4aNRd__xbVUCbXE1YIzP62CY8LCO2W_xSq0oua0dFQTzFIS-5oHbRCAy3hfKQ" + ] + }, + "Body": "" + } + }, + { + "ID": "88911ae9698bab3e", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key3?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:52 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88dw0nrcH6VRshhtOUq8xTTqISalQ8zSccmzeON2BlGobeKpOgs1Wa66llyjqaBslo3" + ] + }, + "Body": "" + } + }, + { + "ID": "a0a749fbabf277f2", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key2?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:52 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88gnZXGcVLxmgzMJo4p_v-hkZD_hVsm6gS-xru_9Wd8Yd-Zaoid5ASA9aT2L1SX2LE" + ] + }, + "Body": "" + } + }, + { + "ID": "fd5b22618a9f2b2b", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key1?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:52 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-Hbuz7i4DduvCm-BxLLPelxGxQwnWnojudhaWLvSmQEJoHTCbgDVzkc2oMlHuyIfY" + ] + }, + "Body": "" + } + }, + { + "ID": "d0ae46f32a9f4569", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/key0?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:52 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-WFQkeFlBvFXD8DtQD_3IlHXEkNcvFrYxWceJwsmjCNhOMMnH-C2ISqesLbdiDRCI" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestCopy/NonExistentSourceFails.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestCopy/NonExistentSourceFails.replay new file mode 100644 index 000000000..455bcbb53 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestCopy/NonExistentSourceFails.replay @@ -0,0 +1,102 @@ +{ + "Initial": "AQAAAA7gDLy9HCVSpgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "b45918112c725a0c", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/does-not-exist/rewriteTo/b/go-cloud-blob-test-bucket/o/blob-for-copying-dest?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "211" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:57 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_y1qpJwnPpktK9IqCDinKKgylKBQYNWeYmELDCxWVkYEpOTPaBQVfnkqnGUQPii92H" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDQsIm1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9kb2VzLW5vdC1leGlzdCIsImVycm9ycyI6W3sibWVzc2FnZSI6Ik5vIHN1Y2ggb2JqZWN0OiBnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2RvZXMtbm90LWV4aXN0IiwiZG9tYWluIjoiZ2xvYmFsIiwicmVhc29uIjoibm90Rm91bmQifV19fQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestCopy/Works.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestCopy/Works.replay new file mode 100644 index 000000000..749ef4b8c --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestCopy/Works.replay @@ -0,0 +1,639 @@ +{ + "Initial": "AQAAAA7gDLy9L2aa5QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "765c0a3bb4492e25", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-copying-src\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY2FjaGVDb250cm9sIjoibm8tY2FjaGUiLCJjb250ZW50RGlzcG9zaXRpb24iOiJpbmxpbmUiLCJjb250ZW50RW5jb2RpbmciOiJpZGVudGl0eSIsImNvbnRlbnRMYW5ndWFnZSI6ImVuIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwibWQ1SGFzaCI6InNRcU5zV1RnZFVFRnQ2bWI1eTQvNVE9PSIsIm1ldGFkYXRhIjp7ImZvbyI6ImJhciJ9LCJuYW1lIjoiYmxvYi1mb3ItY29weWluZy1zcmMifQo=", + "SGVsbG8gV29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "927" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:58 GMT" + ], + "Etag": [ + "CJqFwN61x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89sFObXuAKv_-8-r1j_w644iELTAC05u23Jt5HIipMMX9CLnAaNV8QafvVToZ46VPE" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItY29weWluZy1zcmMvMTc1Mjg3NjQ3ODEwNDIxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1jb3B5aW5nLXNyYyIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWNvcHlpbmctc3JjP2dlbmVyYXRpb249MTc1Mjg3NjQ3ODEwNDIxOCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItY29weWluZy1zcmMiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzgxMDQyMTgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiIxMSIsIm1kNUhhc2giOiJzUXFOc1dUZ2RVRUZ0Nm1iNXk0LzVRPT0iLCJjb250ZW50RW5jb2RpbmciOiJpZGVudGl0eSIsImNvbnRlbnREaXNwb3NpdGlvbiI6ImlubGluZSIsImNvbnRlbnRMYW5ndWFnZSI6ImVuIiwiY2FjaGVDb250cm9sIjoibm8tY2FjaGUiLCJjcmMzMmMiOiJhUjJxTHc9PSIsImV0YWciOiJDSnFGd042MXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU4LjExN1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1OC4xMTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU4LjExN1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1OC4xMTdaIiwibWV0YWRhdGEiOnsiZm9vIjoiYmFyIn19" + } + }, + { + "ID": "911fe96023bb5d05", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-copying-src?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "927" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:58 GMT" + ], + "Etag": [ + "CJqFwN61x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88a4cXjvZTyXUZ9ROI7S6t5p3B91RPeLqsOXF0YQmFfCqc_56nqM8j0g0mrZfKVyXI" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItY29weWluZy1zcmMvMTc1Mjg3NjQ3ODEwNDIxOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1jb3B5aW5nLXNyYyIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWNvcHlpbmctc3JjP2dlbmVyYXRpb249MTc1Mjg3NjQ3ODEwNDIxOCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItY29weWluZy1zcmMiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzgxMDQyMTgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiIxMSIsIm1kNUhhc2giOiJzUXFOc1dUZ2RVRUZ0Nm1iNXk0LzVRPT0iLCJjb250ZW50RW5jb2RpbmciOiJpZGVudGl0eSIsImNvbnRlbnREaXNwb3NpdGlvbiI6ImlubGluZSIsImNvbnRlbnRMYW5ndWFnZSI6ImVuIiwiY2FjaGVDb250cm9sIjoibm8tY2FjaGUiLCJjcmMzMmMiOiJhUjJxTHc9PSIsImV0YWciOiJDSnFGd042MXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU4LjExN1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1OC4xMTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU4LjExN1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1OC4xMTdaIiwibWV0YWRhdGEiOnsiZm9vIjoiYmFyIn19" + } + }, + { + "ID": "c87fa61959d08344", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-copying-dest-exists\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6Im9QcWFmWEpBMWNYdXZYQ0psRERGbHc9PSIsIm5hbWUiOiJibG9iLWZvci1jb3B5aW5nLWRlc3QtZXhpc3RzIn0K", + "Y2xvYmJlciBtZQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "841" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:58 GMT" + ], + "Etag": [ + "CJul0d61x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89uqDb99eT_bhrvNbZCo15MLSoJDTmEPXZMmZYlSSXrnHQRCMELd-I1TlgaN7IAr14" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItY29weWluZy1kZXN0LWV4aXN0cy8xNzUyODc2NDc4Mzg2ODQzIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWNvcHlpbmctZGVzdC1leGlzdHMiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1jb3B5aW5nLWRlc3QtZXhpc3RzP2dlbmVyYXRpb249MTc1Mjg3NjQ3ODM4Njg0MyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItY29weWluZy1kZXN0LWV4aXN0cyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3ODM4Njg0MyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjEwIiwibWQ1SGFzaCI6Im9QcWFmWEpBMWNYdXZYQ0psRERGbHc9PSIsImNyYzMyYyI6ImhpQmdkQT09IiwiZXRhZyI6IkNKdWwwZDYxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTguMzk0WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU4LjM5NFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTguMzk0WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU4LjM5NFoifQ==" + } + }, + { + "ID": "47fb0762c75ee1d3", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-copying-src/rewriteTo/b/go-cloud-blob-test-bucket/o/blob-for-copying-dest?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "1034" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:58 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-1ZiIibYglh4yPUPVWFWP5rEjiCh-WkpCbF3_5ScN4YKUwz8GDy4z_8Fy2YOh0cic" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMTEiLCJvYmplY3RTaXplIjoiMTEiLCJkb25lIjp0cnVlLCJyZXNvdXJjZSI6eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItY29weWluZy1kZXN0LzE3NTI4NzY0Nzg1MjQ0NTYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItY29weWluZy1kZXN0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItY29weWluZy1kZXN0P2dlbmVyYXRpb249MTc1Mjg3NjQ3ODUyNDQ1NiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItY29weWluZy1kZXN0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDc4NTI0NDU2IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoic1FxTnNXVGdkVUVGdDZtYjV5NC81UT09IiwiY29udGVudEVuY29kaW5nIjoiaWRlbnRpdHkiLCJjb250ZW50RGlzcG9zaXRpb24iOiJpbmxpbmUiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiIsImNhY2hlQ29udHJvbCI6Im5vLWNhY2hlIiwiY3JjMzJjIjoiYVIycUx3PT0iLCJldGFnIjoiQ0tqWTJkNjF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1OC41MzJaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTguNTMyWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1OC41MzJaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTguNTMyWiIsIm1ldGFkYXRhIjp7ImZvbyI6ImJhciJ9fX0=" + } + }, + { + "ID": "7ab17b8a13abb75b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-copying-dest", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:58 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:58 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876478524456" + ], + "X-Goog-Hash": [ + "crc32c=aR2qLw==", + "md5=sQqNsWTgdUEFt6mb5y4/5Q==" + ], + "X-Goog-Meta-Foo": [ + "bar" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-JKtC4R-3_iDFwPFGjrGFTBAKn6OYIThxotAkDDEudnBYJnmKjJ9qy2clDi1eo9Lk" + ] + }, + "Body": "SGVsbG8gV29ybGQ=" + } + }, + { + "ID": "5240f2b313d9dbdf", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-copying-dest?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "931" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:58 GMT" + ], + "Etag": [ + "CKjY2d61x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89DOOgP06L30HLdyWQmySUTdyhLvlfmou3YL1XhpuzUANVAwd9NtaSh_7uHOl6UivB6" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItY29weWluZy1kZXN0LzE3NTI4NzY0Nzg1MjQ0NTYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItY29weWluZy1kZXN0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItY29weWluZy1kZXN0P2dlbmVyYXRpb249MTc1Mjg3NjQ3ODUyNDQ1NiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItY29weWluZy1kZXN0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDc4NTI0NDU2IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoic1FxTnNXVGdkVUVGdDZtYjV5NC81UT09IiwiY29udGVudEVuY29kaW5nIjoiaWRlbnRpdHkiLCJjb250ZW50RGlzcG9zaXRpb24iOiJpbmxpbmUiLCJjb250ZW50TGFuZ3VhZ2UiOiJlbiIsImNhY2hlQ29udHJvbCI6Im5vLWNhY2hlIiwiY3JjMzJjIjoiYVIycUx3PT0iLCJldGFnIjoiQ0tqWTJkNjF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1OC41MzJaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTguNTMyWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1OC41MzJaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTguNTMyWiIsIm1ldGFkYXRhIjp7ImZvbyI6ImJhciJ9fQ==" + } + }, + { + "ID": "698f8e371de42a1f", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-copying-src/rewriteTo/b/go-cloud-blob-test-bucket/o/blob-for-copying-dest-exists?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "1062" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:58 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-LOFG3vU2VnNT2-Hnn8UXu36AvLonYwl1UMTJHOkITb8CqwK_xwPR9r6RglrhOXIc" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMTEiLCJvYmplY3RTaXplIjoiMTEiLCJkb25lIjp0cnVlLCJyZXNvdXJjZSI6eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItY29weWluZy1kZXN0LWV4aXN0cy8xNzUyODc2NDc4ODQwMTA3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWNvcHlpbmctZGVzdC1leGlzdHMiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1jb3B5aW5nLWRlc3QtZXhpc3RzP2dlbmVyYXRpb249MTc1Mjg3NjQ3ODg0MDEwNyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItY29weWluZy1kZXN0LWV4aXN0cyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3ODg0MDEwNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjExIiwibWQ1SGFzaCI6InNRcU5zV1RnZFVFRnQ2bWI1eTQvNVE9PSIsImNvbnRlbnRFbmNvZGluZyI6ImlkZW50aXR5IiwiY29udGVudERpc3Bvc2l0aW9uIjoiaW5saW5lIiwiY29udGVudExhbmd1YWdlIjoiZW4iLCJjYWNoZUNvbnRyb2wiOiJuby1jYWNoZSIsImNyYzMyYyI6ImFSMnFMdz09IiwiZXRhZyI6IkNLdjY3TjYxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTguODQ2WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU4Ljg0NloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTguODQ2WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU4Ljg0NloiLCJtZXRhZGF0YSI6eyJmb28iOiJiYXIifX19" + } + }, + { + "ID": "55373615782ed322", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-copying-dest-exists", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:58 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:58 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876478840107" + ], + "X-Goog-Hash": [ + "crc32c=aR2qLw==", + "md5=sQqNsWTgdUEFt6mb5y4/5Q==" + ], + "X-Goog-Meta-Foo": [ + "bar" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH88eEaOJQQiO8KbKwE6EjE5UlBP_NKkCwN0rnyuDrir4lh0rLreL8Frvj9V8SLCh30U" + ] + }, + "Body": "SGVsbG8gV29ybGQ=" + } + }, + { + "ID": "3bd7e5420dbebb16", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-copying-dest-exists?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "959" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:59 GMT" + ], + "Etag": [ + "CKv67N61x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_zzgCeTNJqWyIi6sEJAYe3eSrT1yhWHJIOxbPY4fGd93vywJ44qYSNyXsJk-JGUwkK" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItY29weWluZy1kZXN0LWV4aXN0cy8xNzUyODc2NDc4ODQwMTA3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWNvcHlpbmctZGVzdC1leGlzdHMiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1jb3B5aW5nLWRlc3QtZXhpc3RzP2dlbmVyYXRpb249MTc1Mjg3NjQ3ODg0MDEwNyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItY29weWluZy1kZXN0LWV4aXN0cyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3ODg0MDEwNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbiIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjExIiwibWQ1SGFzaCI6InNRcU5zV1RnZFVFRnQ2bWI1eTQvNVE9PSIsImNvbnRlbnRFbmNvZGluZyI6ImlkZW50aXR5IiwiY29udGVudERpc3Bvc2l0aW9uIjoiaW5saW5lIiwiY29udGVudExhbmd1YWdlIjoiZW4iLCJjYWNoZUNvbnRyb2wiOiJuby1jYWNoZSIsImNyYzMyYyI6ImFSMnFMdz09IiwiZXRhZyI6IkNLdjY3TjYxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTguODQ2WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU4Ljg0NloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTguODQ2WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU4Ljg0NloiLCJtZXRhZGF0YSI6eyJmb28iOiJiYXIifX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestDelete/NonExistentFails.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestDelete/NonExistentFails.replay new file mode 100644 index 000000000..00f44100a --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestDelete/NonExistentFails.replay @@ -0,0 +1,99 @@ +{ + "Initial": "AQAAAA7gDLy/BQrxfgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "b91aa044afd87302", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/does-not-exist?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "211" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:59 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_SbxrhJ_UvSkw0tq_rBOyYKAEqG3pDOu-mEZJNb1zU_LiH5Du7i1ibCZyBBO9mdzE" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDQsIm1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9kb2VzLW5vdC1leGlzdCIsImVycm9ycyI6W3sibWVzc2FnZSI6Ik5vIHN1Y2ggb2JqZWN0OiBnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2RvZXMtbm90LWV4aXN0IiwiZG9tYWluIjoiZ2xvYmFsIiwicmVhc29uIjoibm90Rm91bmQifV19fQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestDelete/Works.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestDelete/Works.replay new file mode 100644 index 000000000..1f974d54e --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestDelete/Works.replay @@ -0,0 +1,270 @@ +{ + "Initial": "AQAAAA7gDLy/FPR9vAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "011b16243fe30ae4", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-deleting\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlBpV1dDbm5ieHB0blROVHNaNmNzWWc9PSIsIm5hbWUiOiJibG9iLWZvci1kZWxldGluZyJ9Cg==", + "SGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "797" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:59 GMT" + ], + "Etag": [ + "CN7jnd+1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_sw8zC8Zl-ZiUjdBWeWbVG-XmTNS8_1iw7ZUAkSjm_dxlgA2U_uxHolsMPwoMmBP4" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsZXRpbmcvMTc1Mjg3NjQ3OTY0MDAzMCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxldGluZyIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGV0aW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ3OTY0MDAzMCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsZXRpbmciLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0Nzk2NDAwMzAiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiIxMSIsIm1kNUhhc2giOiJQaVdXQ25uYnhwdG5UTlRzWjZjc1lnPT0iLCJjcmMzMmMiOiJjclVmZUE9PSIsImV0YWciOiJDTjdqbmQrMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU5LjY0MloiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1OS42NDJaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU5LjY0MloiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1OS42NDJaIn0=" + } + }, + { + "ID": "f3006518fe25b747", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-deleting?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:59 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88H94Li60Q5znPGi2zTSA9fn7zlzL_dqXBuU0nf_0MXewY-mKnWlqsUynW3npWJy9bz" + ] + }, + "Body": "" + } + }, + { + "ID": "c7aea6d552fb16b7", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-deleting", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "205" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:59 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH89turirxS94GWteUSQMmmNWFkRwdnulYL1KFfngsO2ojcq7zBRc_WYYKPauXSxzxWw" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxldGluZzwvRGV0YWlscz48L0Vycm9yPg==" + } + }, + { + "ID": "e421d9e9b641ca89", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-deleting?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "217" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:59 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-fCU4xhnl6sH9UcJTQPTFfHOqo6mkQ5WVgPNgJColf0i60MBanrX3Z0LjBXmDTS8c" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDQsIm1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxldGluZyIsImVycm9ycyI6W3sibWVzc2FnZSI6Ik5vIHN1Y2ggb2JqZWN0OiBnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGV0aW5nIiwiZG9tYWluIjoiZ2xvYmFsIiwicmVhc29uIjoibm90Rm91bmQifV19fQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestDirsWithCharactersBeforeDelimiter.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestDirsWithCharactersBeforeDelimiter.replay new file mode 100644 index 000000000..b37b55c62 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestDirsWithCharactersBeforeDelimiter.replay @@ -0,0 +1,1216 @@ +{ + "Initial": "AQAAAA7gDLykDTPCwQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "839adf0b77ac0eae", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "5686" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:32 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-QbT_eMFuCcdjcxN25awdISd4Rs1QmzWA6ARozLjVvXfLouPC98lxwyzposSMSGbbP" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kLzE2NDQzNjc0MDYzMjA5OTYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIlMkZkIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIlMkZkP2dlbmVyYXRpb249MTY0NDM2NzQwNjMyMDk5NiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTY0NDM2NzQwNjMyMDk5NiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ09TYWlmbXg4ZlVDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNi4zMjNaIiwidXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNi4zMjNaIiwidGltZUZpbmFsaXplZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjEvdGVzdEZpbGUxZGlyMS8xNjQ0MzY3NDA2MDY0MTE1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZGlyMSUyRnRlc3RGaWxlMWRpcjEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRmRpcjElMkZ0ZXN0RmlsZTFkaXIxP2dlbmVyYXRpb249MTY0NDM2NzQwNjA2NDExNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS90ZXN0RmlsZTFkaXIxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA2MDY0MTE1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDUFBEK2ZpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjA2NVoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNi4wNjVaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjA2NVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNi4wNjVaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi90ZXN0RmlsZTFkaXIyLzE2NDQzNjc0MDYxNDU5MTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIlMkZkaXIyJTJGdGVzdEZpbGUxZGlyMiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZGlyMiUyRnRlc3RGaWxlMWRpcjI/Z2VuZXJhdGlvbj0xNjQ0MzY3NDA2MTQ1OTE4JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyL3Rlc3RGaWxlMWRpcjIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE2NDQzNjc0MDYxNDU5MTgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNQN0Mvdml4OGZVQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMTQ3WiIsInVwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjE0N1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMTQ3WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjE0N1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS90Li8xNjQ0MzY3NDA1OTcxMzMyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdC0lMkZ0LiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdC0lMkZ0Lj9nZW5lcmF0aW9uPTE2NDQzNjc0MDU5NzEzMzImYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtL3QuIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1OTcxMzMyIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSVR2OC9peDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1Ljk3NFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS45NzRaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1Ljk3NFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS45NzRaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC90L3QvMTY0NDM2NzQwNTg1NjU2MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnQlMkZ0JTJGdCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdCUyRnQlMkZ0P2dlbmVyYXRpb249MTY0NDM2NzQwNTg1NjU2MSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC90L3QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE2NDQzNjc0MDU4NTY1NjEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNMSHU3UGl4OGZVQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjUuODU4WiIsInVwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1Ljg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjUuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1Ljg1OFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTEvMTY0NDM2NzQwNTcxOTEzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnRlc3RGaWxlMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdGVzdEZpbGUxP2dlbmVyYXRpb249MTY0NDM2NzQwNTcxOTEzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1NzE5MTM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTis4NVBpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIn1dfQ==" + } + }, + { + "ID": "d6f754a4b684d258", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=10\u0026pageToken=\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2086" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:32 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_Bc_W9XiQpC--anPQDxvfmHKiagAv4b761GTlBQD6XKMaIKhI-8qSvJ8z92heMEzw" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS8iLCJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvIl0sIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZC8xNjQ0MzY3NDA2MzIwOTk2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZD9nZW5lcmF0aW9uPTE2NDQzNjc0MDYzMjA5OTYmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE2NDQzNjc0MDYzMjA5OTYiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPU2FpZm14OGZVQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInVwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTEvMTY0NDM2NzQwNTcxOTEzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnRlc3RGaWxlMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdGVzdEZpbGUxP2dlbmVyYXRpb249MTY0NDM2NzQwNTcxOTEzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1NzE5MTM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTis4NVBpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIn1dfQ==" + } + }, + { + "ID": "eab026f9d7ce90b8", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=9\u0026pageToken=\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2086" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:32 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-BqKkKP9oSlqmcJ3TcnE3o9j3epaB-BrFMpru35a-n3qLX7dEfO8m-42dBmJ8VWbko" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS8iLCJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvIl0sIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZC8xNjQ0MzY3NDA2MzIwOTk2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZD9nZW5lcmF0aW9uPTE2NDQzNjc0MDYzMjA5OTYmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE2NDQzNjc0MDYzMjA5OTYiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPU2FpZm14OGZVQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInVwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTEvMTY0NDM2NzQwNTcxOTEzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnRlc3RGaWxlMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdGVzdEZpbGUxP2dlbmVyYXRpb249MTY0NDM2NzQwNTcxOTEzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1NzE5MTM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTis4NVBpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIn1dfQ==" + } + }, + { + "ID": "b82905f6c3dddf37", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=8\u0026pageToken=\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2086" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:32 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_8tlXiFR5oG24-9aE_wAJETIl2scGqLJF9YUqFVROhu-A8dOA0apIHteVg-6MoNsoT" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS8iLCJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvIl0sIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZC8xNjQ0MzY3NDA2MzIwOTk2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZD9nZW5lcmF0aW9uPTE2NDQzNjc0MDYzMjA5OTYmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE2NDQzNjc0MDYzMjA5OTYiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPU2FpZm14OGZVQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInVwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTEvMTY0NDM2NzQwNTcxOTEzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnRlc3RGaWxlMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdGVzdEZpbGUxP2dlbmVyYXRpb249MTY0NDM2NzQwNTcxOTEzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1NzE5MTM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTis4NVBpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIn1dfQ==" + } + }, + { + "ID": "7f1c70e22c4cdff8", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=7\u0026pageToken=\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2086" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:32 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88pvtahQrFurTsFFwk05XjmNwpbwmL2MJY7jpY9M5aQ4zZlk7dcLMaybxifAfNBUFU" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS8iLCJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvIl0sIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZC8xNjQ0MzY3NDA2MzIwOTk2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZD9nZW5lcmF0aW9uPTE2NDQzNjc0MDYzMjA5OTYmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE2NDQzNjc0MDYzMjA5OTYiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPU2FpZm14OGZVQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInVwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTEvMTY0NDM2NzQwNTcxOTEzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnRlc3RGaWxlMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdGVzdEZpbGUxP2dlbmVyYXRpb249MTY0NDM2NzQwNTcxOTEzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1NzE5MTM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTis4NVBpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIn1dfQ==" + } + }, + { + "ID": "57757edcf2a65acf", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=6\u0026pageToken=\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2086" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:32 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-XxKkXrRb4SE3qOXP-mxet5gdf2-OwfDxC8Vmu2ZUxU2GD9e2-vznUVhZQoWEu-S8" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS8iLCJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvIl0sIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZC8xNjQ0MzY3NDA2MzIwOTk2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZD9nZW5lcmF0aW9uPTE2NDQzNjc0MDYzMjA5OTYmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE2NDQzNjc0MDYzMjA5OTYiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPU2FpZm14OGZVQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInVwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTEvMTY0NDM2NzQwNTcxOTEzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnRlc3RGaWxlMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdGVzdEZpbGUxP2dlbmVyYXRpb249MTY0NDM2NzQwNTcxOTEzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1NzE5MTM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTis4NVBpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIn1dfQ==" + } + }, + { + "ID": "2c7d8b719c70d2f5", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=5\u0026pageToken=\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1232" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:33 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88-bGVHcDN4jKliMIE1dJmfBrNpQZiDNHITer8aJl6PVGUgd2T1blhn8UhnF473Ddo" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNpeGliRzlpTFdadmNpMWthWEp6TFhkcGRHZ3RZMmhoY25NdFltVm1iM0psTFdSbGJHbHRhWFJsY2k5MEx3PT0iLCJwcmVmaXhlcyI6WyJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvIiwiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC0vIiwiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC8iXSwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kLzE2NDQzNjc0MDYzMjA5OTYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIlMkZkIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIlMkZkP2dlbmVyYXRpb249MTY0NDM2NzQwNjMyMDk5NiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTY0NDM2NzQwNjMyMDk5NiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ09TYWlmbXg4ZlVDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNi4zMjNaIiwidXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNi4zMjNaIiwidGltZUZpbmFsaXplZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiJ9XX0=" + } + }, + { + "ID": "ec17781f925440fa", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=5\u0026pageToken=CixibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90Lw%3D%3D\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "973" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:33 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_r4nqG07dsdIALTz3-B_Ilu9t-QliHdDf0kE7dMc0Zxsj15E0DJ7LXu1TY-32WUnmk" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTEvMTY0NDM2NzQwNTcxOTEzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnRlc3RGaWxlMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdGVzdEZpbGUxP2dlbmVyYXRpb249MTY0NDM2NzQwNTcxOTEzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1NzE5MTM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTis4NVBpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIn1dfQ==" + } + }, + { + "ID": "60192ab2ac50e720", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=4\u0026pageToken=\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1185" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:33 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-PCnAvTFrCz-B4_6sXPKTdmBe5thBNdg_QUZSy_-acWSJv73jFXVp7zvRgHzaVKMnE" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNpMWliRzlpTFdadmNpMWthWEp6TFhkcGRHZ3RZMmhoY25NdFltVm1iM0psTFdSbGJHbHRhWFJsY2k5MExTOD0iLCJwcmVmaXhlcyI6WyJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvIiwiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC0vIl0sIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZC8xNjQ0MzY3NDA2MzIwOTk2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZD9nZW5lcmF0aW9uPTE2NDQzNjc0MDYzMjA5OTYmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE2NDQzNjc0MDYzMjA5OTYiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPU2FpZm14OGZVQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInVwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oifV19" + } + }, + { + "ID": "bc6e099c56d4dd92", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=4\u0026pageToken=Ci1ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS8%3D\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1033" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:33 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-Oanmtt6RITWmrkCsLXK72oqeHY02RWJhZN6IVbVoIUt428nCX7D7jfdnwJIhnM7c" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC8iXSwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTEvMTY0NDM2NzQwNTcxOTEzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnRlc3RGaWxlMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdGVzdEZpbGUxP2dlbmVyYXRpb249MTY0NDM2NzQwNTcxOTEzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1NzE5MTM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTis4NVBpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIn1dfQ==" + } + }, + { + "ID": "b16bceecad3d95b7", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=3\u0026pageToken=\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1141" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:33 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH881wY_Q1gFKyVB-6xbZLQSslCM5Wir6dTrzglUZ9Qj82kN2oQrwg3cgbZniI4kr_Xk" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNpOWliRzlpTFdadmNpMWthWEp6TFhkcGRHZ3RZMmhoY25NdFltVm1iM0psTFdSbGJHbHRhWFJsY2k5a2FYSXlMdz09IiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS8iLCJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLyJdLCJpdGVtcyI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2QvMTY0NDM2NzQwNjMyMDk5NiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRmQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRmQ/Z2VuZXJhdGlvbj0xNjQ0MzY3NDA2MzIwOTk2JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA2MzIwOTk2IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDT1NhaWZteDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNi4zMjNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNi4zMjNaIn1dfQ==" + } + }, + { + "ID": "57bddabca287ee35", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=3\u0026pageToken=Ci9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLw%3D%3D\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1081" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:33 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-wXMMlUtRz-yPCjumUkbVD5B4IRwyHRzfx9tposMLickqP0k3tDChpq2TqzhBqWjI6" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC0vIiwiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC8iXSwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTEvMTY0NDM2NzQwNTcxOTEzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnRlc3RGaWxlMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdGVzdEZpbGUxP2dlbmVyYXRpb249MTY0NDM2NzQwNTcxOTEzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1NzE5MTM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTis4NVBpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIn1dfQ==" + } + }, + { + "ID": "b121e509bf5c9c1d", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=2\u0026pageToken=\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1091" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:33 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88JbbMOHNiRjNmn0XMKUR3BHrN8EN2s8fxFMQfg5W_ZckDsJTt4gPTGv7khc1xBVMkw" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNpOWliRzlpTFdadmNpMWthWEp6TFhkcGRHZ3RZMmhoY25NdFltVm1iM0psTFdSbGJHbHRhWFJsY2k5a2FYSXhMdz09IiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS8iXSwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kLzE2NDQzNjc0MDYzMjA5OTYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIlMkZkIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIlMkZkP2dlbmVyYXRpb249MTY0NDM2NzQwNjMyMDk5NiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTY0NDM2NzQwNjMyMDk5NiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ09TYWlmbXg4ZlVDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNi4zMjNaIiwidXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNi4zMjNaIiwidGltZUZpbmFsaXplZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiJ9XX0=" + } + }, + { + "ID": "b8e509ef930665b8", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=2\u0026pageToken=Ci9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLw%3D%3D\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "220" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:33 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_HUruSo9UK2rMVOn95NK_x-MtxaGPIC5BnJiCitmDQBrF65_himrrSKH2e8lN3ynJ8" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNpMWliRzlpTFdadmNpMWthWEp6TFhkcGRHZ3RZMmhoY25NdFltVm1iM0psTFdSbGJHbHRhWFJsY2k5MExTOD0iLCJwcmVmaXhlcyI6WyJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLyIsImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLyJdfQ==" + } + }, + { + "ID": "e603192dddb3e4ab", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=2\u0026pageToken=Ci1ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS8%3D\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1033" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:33 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88ZW2CyVMEfCfl69d3xMSj9k4ynVZ7vjsE_uE_s2_voJZY8bDxRJ5DaDo3_IwKT4kI" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC8iXSwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTEvMTY0NDM2NzQwNTcxOTEzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnRlc3RGaWxlMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdGVzdEZpbGUxP2dlbmVyYXRpb249MTY0NDM2NzQwNTcxOTEzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1NzE5MTM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTis4NVBpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIn1dfQ==" + } + }, + { + "ID": "396249a252ba206c", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1020" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:33 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_RODITM2RWMOmjhbULt6SetPP4w4m-fvLLoHi0gtSwdqkJhNPNHKph35x0LZ6mPZ4" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNpdGliRzlpTFdadmNpMWthWEp6TFhkcGRHZ3RZMmhoY25NdFltVm1iM0psTFdSbGJHbHRhWFJsY2k5ayIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZC8xNjQ0MzY3NDA2MzIwOTk2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGZD9nZW5lcmF0aW9uPTE2NDQzNjc0MDYzMjA5OTYmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE2NDQzNjc0MDYzMjA5OTYiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPU2FpZm14OGZVQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInVwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjItMDItMDlUMDA6NDM6MjYuMzIzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI2LjMyM1oifV19" + } + }, + { + "ID": "d5f6304cf0c86a6a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=CitibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9k\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "176" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:34 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89nUDI9gHS2ssRjWyKgcHOeVv_elmh5sxzSCyQtNk-MR7aP4MXqnVKZsQHLeQN0g698" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNpOWliRzlpTFdadmNpMWthWEp6TFhkcGRHZ3RZMmhoY25NdFltVm1iM0psTFdSbGJHbHRhWFJsY2k5a2FYSXhMdz09IiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS8iXX0=" + } + }, + { + "ID": "3e13f109666bea03", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=Ci9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLw%3D%3D\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "176" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:34 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_pLwCYa2DNl_Toav5sth-L98jtWXh2j-8USxUS8boWm0A1xGKbg88n9d1Pv8R3jFA" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNpOWliRzlpTFdadmNpMWthWEp6TFhkcGRHZ3RZMmhoY25NdFltVm1iM0psTFdSbGJHbHRhWFJsY2k5a2FYSXlMdz09IiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi8iXX0=" + } + }, + { + "ID": "1dd0e0ffea069166", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=Ci9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLw%3D%3D\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "170" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:34 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88jioGlsu2-OEgf6E55og8cZ2Sm_mvs7b8vLZBiIw_DJ-wmNB9H5fEZPiKlp4UhlhU" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNpMWliRzlpTFdadmNpMWthWEp6TFhkcGRHZ3RZMmhoY25NdFltVm1iM0psTFdSbGJHbHRhWFJsY2k5MExTOD0iLCJwcmVmaXhlcyI6WyJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS8iXX0=" + } + }, + { + "ID": "a90e411e740dad47", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=Ci1ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS8%3D\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "169" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:34 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_Qsw1jLI44WCoJFyCVN_y4Q-BpUsoztezzCdV_pABhfaMKZOxwr7BCuBOVKrvhXQG-" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNpeGliRzlpTFdadmNpMWthWEp6TFhkcGRHZ3RZMmhoY25NdFltVm1iM0psTFdSbGJHbHRhWFJsY2k5MEx3PT0iLCJwcmVmaXhlcyI6WyJibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LyJdfQ==" + } + }, + { + "ID": "7f91a65ac0641fa2", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=CixibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90Lw%3D%3D\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "973" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:34 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89wukvpF7DbjFcOv9Lpka0Kh8WydEN0L1Xr4KLQ9jKd1WyYJL38k0EVVdivFx2UETg" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTEvMTY0NDM2NzQwNTcxOTEzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlciUyRnRlc3RGaWxlMSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyJTJGdGVzdEZpbGUxP2dlbmVyYXRpb249MTY0NDM2NzQwNTcxOTEzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNjQ0MzY3NDA1NzE5MTM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTis4NVBpeDhmVUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ1cGRhdGVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDIyLTAyLTA5VDAwOjQzOjI1LjcyMFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyMi0wMi0wOVQwMDo0MzoyNS43MjBaIn1dfQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestIfNotExist.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestIfNotExist.replay new file mode 100644 index 000000000..43ebdb627 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestIfNotExist.replay @@ -0,0 +1,222 @@ +{ + "Initial": "AQAAAA7gDLzVFoiBXQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "8ad745e5677125d0", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026ifGenerationMatch=0\u0026name=blob-for-if-not-exist\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0IiwibmFtZSI6ImJsb2ItZm9yLWlmLW5vdC1leGlzdCJ9Cg==", + "dXAgYW5kIGRvd24=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "792" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:21 GMT" + ], + "Etag": [ + "COHQ3+m1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88E0CCdQb5EHj9LP6A9xEkuhA-ZqbXTmHMhEox6fyD2yl2ud6WOf8ltpZxJkAG-VFfCq-QDVaQ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItaWYtbm90LWV4aXN0LzE3NTI4NzY1MDE2OTA0NjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItaWYtbm90LWV4aXN0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItaWYtbm90LWV4aXN0P2dlbmVyYXRpb249MTc1Mjg3NjUwMTY5MDQ2NSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItaWYtbm90LWV4aXN0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NTAxNjkwNDY1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoiRzNWVFB0V29hZjl2T3VBemJRd3pJQT09IiwiY3JjMzJjIjoiMzVjNnJnPT0iLCJldGFnIjoiQ09IUTMrbTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoyMS42OTJaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjEuNjkyWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoyMS42OTJaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MjEuNjkyWiJ9" + } + }, + { + "ID": "11eb3467ae45ba53", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026ifGenerationMatch=0\u0026name=blob-for-if-not-exist\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0IiwibmFtZSI6ImJsb2ItZm9yLWlmLW5vdC1leGlzdCJ9Cg==", + "dXAgYW5kIGRvd24=" + ] + }, + "Response": { + "StatusCode": 412, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "276" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:21 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_Y4fUL8P0TJ-1SBPck0n2mgRKgJvYQdti8FDWmYIhR6DmlePxOHkBFjpPCdk_Uo7bqrY0syX0" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MTIsIm1lc3NhZ2UiOiJBdCBsZWFzdCBvbmUgb2YgdGhlIHByZS1jb25kaXRpb25zIHlvdSBzcGVjaWZpZWQgZGlkIG5vdCBob2xkLiIsImVycm9ycyI6W3sibWVzc2FnZSI6IkF0IGxlYXN0IG9uZSBvZiB0aGUgcHJlLWNvbmRpdGlvbnMgeW91IHNwZWNpZmllZCBkaWQgbm90IGhvbGQuIiwiZG9tYWluIjoiZ2xvYmFsIiwicmVhc29uIjoiY29uZGl0aW9uTm90TWV0IiwibG9jYXRpb25UeXBlIjoiaGVhZGVyIiwibG9jYXRpb24iOiJJZi1NYXRjaCJ9XX19" + } + }, + { + "ID": "7f51172e8ad893ca", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-if-not-exist?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:21 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88PVOwJP0x0Wta0SoRcf3ZcBJAPpOjc8SDV4X8FiNLXB7dELSoIWNllZKdX9q53z6gAGPwjSFk" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-1.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-1.replay new file mode 100644 index 000000000..8b273e531 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-1.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzGGdc7ZAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "8bf23970035c1f34", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys%00%01%02%03%04%05%06%07%08%09__0xa__%0B%0C__0xd__%0E%0F\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzXHUwMDAwXHUwMDAxXHUwMDAyXHUwMDAzXHUwMDA0XHUwMDA1XHUwMDA2XHUwMDA3XGJcdF9fMHhhX19cdTAwMGJcZl9fMHhkX19cdTAwMGVcdTAwMGYifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "1052" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:06 GMT" + ], + "Etag": [ + "CITFzuK1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-1hmoppb8u6fHEvSJIIv2en9hUV4PPcCJY1lTNwWDHdhxDdhW0bpRs5_Mu9Y9-oNs" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c1x1MDAwMFx1MDAwMVx1MDAwMlx1MDAwM1x1MDAwNFx1MDAwNVx1MDAwNlx1MDAwN1xiXHRfXzB4YV9fXHUwMDBiXGZfXzB4ZF9fXHUwMDBlXHUwMDBmLzE3NTI4NzY0ODY3MzAzNzIiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyUwMCUwMSUwMiUwMyUwNCUwNSUwNiUwNyUwOCUwOV9fMHhhX18lMEIlMENfXzB4ZF9fJTBFJTBGIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyUwMCUwMSUwMiUwMyUwNCUwNSUwNiUwNyUwOCUwOV9fMHhhX18lMEIlMENfXzB4ZF9fJTBFJTBGP2dlbmVyYXRpb249MTc1Mjg3NjQ4NjczMDM3MiZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c1x1MDAwMFx1MDAwMVx1MDAwMlx1MDAwM1x1MDAwNFx1MDAwNVx1MDAwNlx1MDAwN1xiXHRfXzB4YV9fXHUwMDBiXGZfXzB4ZF9fXHUwMDBlXHUwMDBmIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDg2NzMwMzcyIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSVRGenVLMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA2LjczM1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowNi43MzNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA2LjczM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowNi43MzNaIn0=" + } + }, + { + "ID": "52f3fa6b27cc2246", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%00%01%02%03%04%05%06%07%08%09__0xa__%0B%0C__0xd__%0E%0F", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:06 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876486730372" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_LKeAICQchSXvYREm4f8wDfSKyN8D1AcD-Y5h2bDLnqwu4HAEzOb3pF2A-jFUqZZY" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "1f8c1f1333185e99", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%00%01%02%03%04%05%06%07%08%09__0xa__%0B%0C__0xd__%0E%0F?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1052" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:06 GMT" + ], + "Etag": [ + "CITFzuK1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-7hTHetNpWjVk2uiGJIQT3YKh8j0NMtxBvYttVns2_Ty1GTjrAAOfiSGnMNYM_-ko" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c1x1MDAwMFx1MDAwMVx1MDAwMlx1MDAwM1x1MDAwNFx1MDAwNVx1MDAwNlx1MDAwN1xiXHRfXzB4YV9fXHUwMDBiXGZfXzB4ZF9fXHUwMDBlXHUwMDBmLzE3NTI4NzY0ODY3MzAzNzIiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyUwMCUwMSUwMiUwMyUwNCUwNSUwNiUwNyUwOCUwOV9fMHhhX18lMEIlMENfXzB4ZF9fJTBFJTBGIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyUwMCUwMSUwMiUwMyUwNCUwNSUwNiUwNyUwOCUwOV9fMHhhX18lMEIlMENfXzB4ZF9fJTBFJTBGP2dlbmVyYXRpb249MTc1Mjg3NjQ4NjczMDM3MiZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c1x1MDAwMFx1MDAwMVx1MDAwMlx1MDAwM1x1MDAwNFx1MDAwNVx1MDAwNlx1MDAwN1xiXHRfXzB4YV9fXHUwMDBiXGZfXzB4ZF9fXHUwMDBlXHUwMDBmIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDg2NzMwMzcyIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSVRGenVLMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA2LjczM1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowNi43MzNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA2LjczM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowNi43MzNaIn0=" + } + }, + { + "ID": "88f14ce2c02b0af6", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%00%01%02%03%04%05%06%07%08%09__0xa__%0B%0C__0xd__%0E%0F?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:06 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876486730372" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89hi3zA2xUbwsArJEo2plfIBCacucaJTitfjE7xXBseWXxsagAFPxtrG3j_EaCysQ4" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6c6b266b5082c0dc", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%00%01%02%03%04%05%06%07%08%09__0xa__%0B%0C__0xd__%0E%0F/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys%00%01%02%03%04%05%06%07%08%09__0xa__%0B%0C__0xd__%0E%0F-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "1173" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:07 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH896Bg1Dfcgp1iYnfER_GYkS8t3joRTM8iNlOqjryIkmYR5Shl8vZr_n_QwUleY5cU3z" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXNcdTAwMDBcdTAwMDFcdTAwMDJcdTAwMDNcdTAwMDRcdTAwMDVcdTAwMDZcdTAwMDdcYlx0X18weGFfX1x1MDAwYlxmX18weGRfX1x1MDAwZVx1MDAwZi1jb3B5LzE3NTI4NzY0ODcxMDQ4MzUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyUwMCUwMSUwMiUwMyUwNCUwNSUwNiUwNyUwOCUwOV9fMHhhX18lMEIlMENfXzB4ZF9fJTBFJTBGLWNvcHkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTAwJTAxJTAyJTAzJTA0JTA1JTA2JTA3JTA4JTA5X18weGFfXyUwQiUwQ19fMHhkX18lMEUlMEYtY29weT9nZW5lcmF0aW9uPTE3NTI4NzY0ODcxMDQ4MzUmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXNcdTAwMDBcdTAwMDFcdTAwMDJcdTAwMDNcdTAwMDRcdTAwMDVcdTAwMDZcdTAwMDdcYlx0X18weGFfX1x1MDAwYlxmX18weGRfX1x1MDAwZVx1MDAwZi1jb3B5IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDg3MTA0ODM1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTU95NWVLMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA3LjEwNloiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowNy4xMDZaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA3LjEwNloiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowNy4xMDZaIn19" + } + }, + { + "ID": "e248536fa7320d7b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%00%01%02%03%04%05%06%07%08%09__0xa__%0B%0C__0xd__%0E%0F-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:07 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876487104835" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89pu9jUXckegbDu1kOMqa-RUVJBkLvskMV8A9W00sLx9cTXwDroEBs06r5HlrJEKiUw" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "c835b52a9b59fda2", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%00%01%02%03%04%05%06%07%08%09__0xa__%0B%0C__0xd__%0E%0F-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:07 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_Dr1IPByhotNSFcXkjTIHv-vx1yE7EdM9UyRhRAHMRxmz9Qv99QziezkESind5bcU8" + ] + }, + "Body": "" + } + }, + { + "ID": "215b9fd75deeefcc", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%00%01%02%03%04%05%06%07%08%09__0xa__%0B%0C__0xd__%0E%0F?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:07 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89n4Jb7xblrrwyKNuyhKKX9AFHM9FyESdqd18vZQdUI0vCM8vGppoBD5Uvdq9Ft-3w" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-2.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-2.replay new file mode 100644 index 000000000..81bdf9f1e --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-2.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzMOGlD0AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "0d268bd1e3b68601", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzXHUwMDEwXHUwMDExXHUwMDEyXHUwMDEzXHUwMDE0XHUwMDE1XHUwMDE2XHUwMDE3XHUwMDE4XHUwMDE5XHUwMDFhXHUwMDFiXHUwMDFjXHUwMDFkXHUwMDFlXHUwMDFmIn0K", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "1056" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:13 GMT" + ], + "Etag": [ + "CMDo2+W1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89NrkgCd9YfPanKDf0A0mGHI0C_lBtcb4DWQdJPiRzXPC2cziBa0NryzJDCiWLHqPN0a3v7-30" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c1x1MDAxMFx1MDAxMVx1MDAxMlx1MDAxM1x1MDAxNFx1MDAxNVx1MDAxNlx1MDAxN1x1MDAxOFx1MDAxOVx1MDAxYVx1MDAxYlx1MDAxY1x1MDAxZFx1MDAxZVx1MDAxZi8xNzUyODc2NDkzMjM5MzYwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlMTAlMTElMTIlMTMlMTQlMTUlMTYlMTclMTglMTklMUElMUIlMUMlMUQlMUUlMUYiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTEwJTExJTEyJTEzJTE0JTE1JTE2JTE3JTE4JTE5JTFBJTFCJTFDJTFEJTFFJTFGP2dlbmVyYXRpb249MTc1Mjg3NjQ5MzIzOTM2MCZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c1x1MDAxMFx1MDAxMVx1MDAxMlx1MDAxM1x1MDAxNFx1MDAxNVx1MDAxNlx1MDAxN1x1MDAxOFx1MDAxOVx1MDAxYVx1MDAxYlx1MDAxY1x1MDAxZFx1MDAxZVx1MDAxZiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ5MzIzOTM2MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ01EbzIrVzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMy4yNDFaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTMuMjQxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMy4yNDFaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MTMuMjQxWiJ9" + } + }, + { + "ID": "251e62963b119231", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:13 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:13 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876493239360" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH88PB0dpPrZ_8mAZMlK8zk1fWBwVdJx90UiuVvZ72gcmcrJ8mtLlzWj55QzvQj3VNM0" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "e351d5251027391f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1056" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:13 GMT" + ], + "Etag": [ + "CMDo2+W1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89p4S1pLNdSHIJjmJxQROCs8slVjSCq27-GfCbGcyt0zE0eYLszvEfYHBA6ch13XmgU" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c1x1MDAxMFx1MDAxMVx1MDAxMlx1MDAxM1x1MDAxNFx1MDAxNVx1MDAxNlx1MDAxN1x1MDAxOFx1MDAxOVx1MDAxYVx1MDAxYlx1MDAxY1x1MDAxZFx1MDAxZVx1MDAxZi8xNzUyODc2NDkzMjM5MzYwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlMTAlMTElMTIlMTMlMTQlMTUlMTYlMTclMTglMTklMUElMUIlMUMlMUQlMUUlMUYiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTEwJTExJTEyJTEzJTE0JTE1JTE2JTE3JTE4JTE5JTFBJTFCJTFDJTFEJTFFJTFGP2dlbmVyYXRpb249MTc1Mjg3NjQ5MzIzOTM2MCZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c1x1MDAxMFx1MDAxMVx1MDAxMlx1MDAxM1x1MDAxNFx1MDAxNVx1MDAxNlx1MDAxN1x1MDAxOFx1MDAxOVx1MDAxYVx1MDAxYlx1MDAxY1x1MDAxZFx1MDAxZVx1MDAxZiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ5MzIzOTM2MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ01EbzIrVzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMy4yNDFaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTMuMjQxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMy4yNDFaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MTMuMjQxWiJ9" + } + }, + { + "ID": "2b707d7499b7387b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:13 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:13 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876493239360" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-qc2RC6ni__ApJGoVwEdB-0cCeGdDPpCOijpLGLco-uZKcvAjXB6rUYltsrW1lr6Q" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "2839a97d7afc2f96", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "1177" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:13 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-JKqeQvEAr6FqebjIulgaRwQOtegopDQ_IpdLLd7CyNRIn8Jd5b1HtglKFNA7tzxaSYn9NPXM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXNcdTAwMTBcdTAwMTFcdTAwMTJcdTAwMTNcdTAwMTRcdTAwMTVcdTAwMTZcdTAwMTdcdTAwMThcdTAwMTlcdTAwMWFcdTAwMWJcdTAwMWNcdTAwMWRcdTAwMWVcdTAwMWYtY29weS8xNzUyODc2NDkzNzYyNTYwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlMTAlMTElMTIlMTMlMTQlMTUlMTYlMTclMTglMTklMUElMUIlMUMlMUQlMUUlMUYtY29weSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlMTAlMTElMTIlMTMlMTQlMTUlMTYlMTclMTglMTklMUElMUIlMUMlMUQlMUUlMUYtY29weT9nZW5lcmF0aW9uPTE3NTI4NzY0OTM3NjI1NjAmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXNcdTAwMTBcdTAwMTFcdTAwMTJcdTAwMTNcdTAwMTRcdTAwMTVcdTAwMTZcdTAwMTdcdTAwMThcdTAwMTlcdTAwMWFcdTAwMWJcdTAwMWNcdTAwMWRcdTAwMWVcdTAwMWYtY29weSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ5Mzc2MjU2MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0lEZysrVzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMy43NjRaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTMuNzY0WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMy43NjRaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MTMuNzY0WiJ9fQ==" + } + }, + { + "ID": "946db7af1a8ec978", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:13 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:13 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876493762560" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-FyJ3epK0AEg_lsIIpN1TmdW4IoJFvs-ktutPxifav28azo36IpMK4emZiaHDB3bc" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "754ac1c03a1e56aa", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:13 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89WQjDsNvOmA9SfAyIev8l1Zsd9g3aHPsP5PeVvwzbwkWlzJz5rAiQqVJcuTj5ssJPNZ6jyxHs" + ] + }, + "Body": "" + } + }, + { + "ID": "fbf886c26d75ca7c", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:14 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_Jbjy3FUjQJQukEtgfs5yHemOrykfhNpfz7mMkW6d1r2G_1qdIsM6cPxaA95skEsuPJWn-byM" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-3.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-3.replay new file mode 100644 index 000000000..af7e76856 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-3.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzHGbyEbQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "fcbc93cf6efc9ec6", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys+%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzICFcIiMkJVx1MDAyNicoKSorLC0uLyJ9Cg==", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "858" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:07 GMT" + ], + "Etag": [ + "CLarjeO1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_Tzbh5AoBa_XoOPIx1N8PXGCMyrdcl_mfZ_U8sdZlKEoWgftrzwk7wl70Aef2Vj3g" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5cyAhXCIjJCUmJygpKissLS4vLzE3NTI4NzY0ODc3NTkyODYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyUyMCElMjIlMjMkJTI1JicoKSolMkIsLS4lMkYiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTIwISUyMiUyMyQlMjUmJygpKiUyQiwtLiUyRj9nZW5lcmF0aW9uPTE3NTI4NzY0ODc3NTkyODYmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXMgIVwiIyQlJicoKSorLC0uLyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ4Nzc1OTI4NiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0xhcmplTzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowNy43NjFaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDcuNzYxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowNy43NjFaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MDcuNzYxWiJ9" + } + }, + { + "ID": "65cd17e6a59cc888", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%20%21%22%23$%25\u0026%27%28%29%2A+%2C-.%2F", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:07 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876487759286" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89zAODb7jth225Tgpl2iW7Shf5n4K4Y2IWLeeY9iKwSiJ5y_xaTElrM7y2Inm5lsrFH" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "7e7e043c4144fe76", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "858" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:08 GMT" + ], + "Etag": [ + "CLarjeO1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-ICzuvQndONkQ-kAdGbY9SIucopsacqj8qT8kyv-BHjAfS2BJbEpI6063NgEe4PyQ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5cyAhXCIjJCUmJygpKissLS4vLzE3NTI4NzY0ODc3NTkyODYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyUyMCElMjIlMjMkJTI1JicoKSolMkIsLS4lMkYiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTIwISUyMiUyMyQlMjUmJygpKiUyQiwtLiUyRj9nZW5lcmF0aW9uPTE3NTI4NzY0ODc3NTkyODYmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXMgIVwiIyQlJicoKSorLC0uLyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ4Nzc1OTI4NiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0xhcmplTzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowNy43NjFaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDcuNzYxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowNy43NjFaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MDcuNzYxWiJ9" + } + }, + { + "ID": "1abfea35faf0dd91", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%20%21%22%23$%25\u0026%27%28%29%2A+,-./?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:07 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876487759286" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89gkE78tHZghMWvuXzwK9u92b-UEWvoyPcEYriJ1rlrZncXSI0sfnpemSTZ4QVU5WfY" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "e2d671e3db47e262", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "979" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:08 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88XHP4vRNrnkSvH9CX_iXXaXI2iZEFARiIi2PJdiaIbm49S9HQemcsI_F_PydikRno" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXMgIVwiIyQlJicoKSorLC0uLy1jb3B5LzE3NTI4NzY0ODgyNTM0NDkiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyUyMCElMjIlMjMkJTI1JicoKSolMkIsLS4lMkYtY29weSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlMjAhJTIyJTIzJCUyNSYnKCkqJTJCLC0uJTJGLWNvcHk/Z2VuZXJhdGlvbj0xNzUyODc2NDg4MjUzNDQ5JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzICFcIiMkJSYnKCkqKywtLi8tY29weSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ4ODI1MzQ0OSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0luQXErTzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowOC4yNTZaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDguMjU2WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowOC4yNTZaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MDguMjU2WiJ9fQ==" + } + }, + { + "ID": "8d68b19a4235e7c5", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%20%21%22%23$%25\u0026%27%28%29%2A+%2C-.%2F-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:08 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876488253449" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH88oi7Yi-MqzukaIEdNpUWiDhdGHfgxD4t1MMR2rNxivIlfNDIkdu2brTV08R4LmEPQ" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "e56091e3d61901e2", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:08 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88-uTvY6csftKmHrN3018gZx2djqQhnH2nNKv4jMNqiMucbvoACPtoImcvQj2gHC6ul" + ] + }, + "Body": "" + } + }, + { + "ID": "296499a638173317", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:08 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89CA-r2hXC0edXsrNeI0aTiPK97JNHtrcwZXmMlTYldxX0wABq4yL16mqr5vLm13Zg" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-4.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-4.replay new file mode 100644 index 000000000..28e5b497d --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-4.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzOAmfKwwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "ec97da0c3ec946b8", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys%3A%3B%3C%3D%3E%3F\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzOjtcdTAwM2M9XHUwMDNlPyJ9Cg==", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "824" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:14 GMT" + ], + "Etag": [ + "COG2nua1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_0EJSOv7x_pU4ExMPn4fywbNyxi7HppD6nk__p4SvRuci1JNDW0GZ6wtDPgvEIlghdgoDO018" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5czo7XHUwMDNjPVx1MDAzZT8vMTc1Mjg3NjQ5NDMzMDcyMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzOjslM0M9JTNFJTNGIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5czo7JTNDPSUzRSUzRj9nZW5lcmF0aW9uPTE3NTI4NzY0OTQzMzA3MjEmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXM6O1x1MDAzYz1cdTAwM2U/IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDk0MzMwNzIxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDT0cybnVhMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE0LjMzM1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxNC4zMzNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE0LjMzM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxNC4zMzNaIn0=" + } + }, + { + "ID": "8c9558f324ff124f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys:%3B%3C=%3E%3F", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:14 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:14 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876494330721" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_juF5YLnOGdiGDGbUq5FQOVbNOvxKJARRg5tH5mJFt-1lf0yvB0ncvYt_2iKV5ljc" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "8c70457e2463f027", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%3A%3B%3C%3D%3E%3F?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "824" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:14 GMT" + ], + "Etag": [ + "COG2nua1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-3k9dX5lS4sw_os6n1dQFSfQMZ5yTs3EWu1ZvFuGm8_4nhPNrXATOb2EWGOTgJ-0U" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5czo7XHUwMDNjPVx1MDAzZT8vMTc1Mjg3NjQ5NDMzMDcyMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzOjslM0M9JTNFJTNGIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5czo7JTNDPSUzRSUzRj9nZW5lcmF0aW9uPTE3NTI4NzY0OTQzMzA3MjEmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXM6O1x1MDAzYz1cdTAwM2U/IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDk0MzMwNzIxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDT0cybnVhMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE0LjMzM1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxNC4zMzNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE0LjMzM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxNC4zMzNaIn0=" + } + }, + { + "ID": "51baa28280ada918", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys:;%3C=%3E%3F?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:14 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:14 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876494330721" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH88bicXT8QVqTaZH_5_YPyOfg5qXsZ5mk_5Im25BEdGI1s_tVuFJHcOD12XUIzzQuVlb" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "118354c4c1701f9d", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%3A%3B%3C%3D%3E%3F/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys%3A%3B%3C%3D%3E%3F-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "945" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:14 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_rwAE4ybL40bbYnire18eQP5oHZQok-kA-2B-jowwzpIGh_4J2mvovCEqONk80Bz9R4TwHqXM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXM6O1x1MDAzYz1cdTAwM2U/LWNvcHkvMTc1Mjg3NjQ5NDg0ODI2NSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzOjslM0M9JTNFJTNGLWNvcHkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzOjslM0M9JTNFJTNGLWNvcHk/Z2VuZXJhdGlvbj0xNzUyODc2NDk0ODQ4MjY1JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzOjtcdTAwM2M9XHUwMDNlPy1jb3B5IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDk0ODQ4MjY1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSW1DdnVhMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE0Ljg1MVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxNC44NTFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE0Ljg1MVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxNC44NTFaIn19" + } + }, + { + "ID": "2f726b9c2d6e6d5d", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys:%3B%3C=%3E%3F-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:14 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:14 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876494848265" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_hOd1vNPtuVxMeRZiZaPGrXpTztfNevsWZMYPQdBxBWSIIgfbW5IXy1hr1QmOUB8z0" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "a232bd959003badd", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%3A%3B%3C%3D%3E%3F-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:14 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88cMcteei6GFDJ8RebhsxyXcxnVXwI6_ApddQ_TBQzfDEVtdyJAdPkQgnt09hzOtYWBCIxfVvE" + ] + }, + "Body": "" + } + }, + { + "ID": "3068343d80f94201", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%3A%3B%3C%3D%3E%3F?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:15 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Rd8M3zgzC4iGPbiqNqUlpaDw1DEy4oz1yatTDHBiymnrgZ1UAxvZx2Xdd3L6ktQe2mBqWxgc" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-5.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-5.replay new file mode 100644 index 000000000..eb56c6334 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-5.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzDElSv1wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "a8cb2f64bb6e6ce3", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys%40\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzQCJ9Cg==", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "772" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:03 GMT" + ], + "Etag": [ + "CNnmk+G1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88K48HIuGWKRWzLBXiruurjESyTr8hoBkA9TuKQqIV7HLO7ZYuOKiPSqqErvVYcefM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c0AvMTc1Mjg3NjQ4MzY3MDg3MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzQCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXNAP2dlbmVyYXRpb249MTc1Mjg3NjQ4MzY3MDg3MyZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c0AiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0ODM2NzA4NzMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNObm1rK0cxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDMuNjcyWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAzLjY3MloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDMuNjcyWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAzLjY3MloifQ==" + } + }, + { + "ID": "130e5cf61107f940", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys@", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:03 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:03 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876483670873" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8996VJtpnDWvrr_95vAgOQGbwhJx73kGdeRTG1sEIUAciWbXboCTAfW1DGUrmGLeYQf" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "2a9460ad8102700c", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%40?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "772" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:03 GMT" + ], + "Etag": [ + "CNnmk+G1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89PtjxZM9L8rMUr-wztBZQip2hIs_u6wuAVS94gI28Fn1_dbr3McoqrrIktGM7GO3E" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c0AvMTc1Mjg3NjQ4MzY3MDg3MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzQCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXNAP2dlbmVyYXRpb249MTc1Mjg3NjQ4MzY3MDg3MyZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c0AiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0ODM2NzA4NzMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNObm1rK0cxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDMuNjcyWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAzLjY3MloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDMuNjcyWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAzLjY3MloifQ==" + } + }, + { + "ID": "7fd400780d4ac697", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys@?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:03 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876483670873" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH88yhrvV9qMFWBSGybuqomk-M4PMMEEkKNAHIOcjhFyaVg205L0A-_s8VcanDMxai00" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "17fed4dfb8a61e52", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%40/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys%40-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "893" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:04 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-T8bV9tVAh94wHfqO8fLOCMWcp9odTJKRblp-7vI35bFJFVqsq2hOpMnI6molYP8eE" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXNALWNvcHkvMTc1Mjg3NjQ4NDIxMDM0OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzQC1jb3B5IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c0AtY29weT9nZW5lcmF0aW9uPTE3NTI4NzY0ODQyMTAzNDkmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXNALWNvcHkiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0ODQyMTAzNDkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLM2R0T0cxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDQuMjEyWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA0LjIxMloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDQuMjEyWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA0LjIxMloifX0=" + } + }, + { + "ID": "0f1dafac266c740c", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys@-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:04 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876484210349" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH88npagbUtKxQJ83AgsCFWmdLbSzmGgxCDQSPoLVJ56R8CGpUokI0AFrj4oYCHSzQjg" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "c063ae36a7413301", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%40-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:04 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-ITB2uYd4ls-fE9N2umtZH3Q-5BXXCJsUgUo_3tVBf_uL3W9CU3Uyo1S_8JsQ5Yxo" + ] + }, + "Body": "" + } + }, + { + "ID": "5b9ebc3f5466a659", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%40?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:04 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_UwLw-1slQhwE6hrLLXG7ywUZi1RH92Gh6V7hYfgxLks9vt9IMCofjwsj6R52tbyQ" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-6.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-6.replay new file mode 100644 index 000000000..76733fbf8 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-6.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzPBtH5xgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "9ec971085d1684b7", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys%5B%5C%5D%5E_\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzW1xcXV5fIn0K", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "806" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:15 GMT" + ], + "Etag": [ + "CN2N6ea1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_hROn5UGg3hYp6_qoU5oKB_SwRO4bXmCxQAGA14JJ-C7N6tXP0XOu5OEoIV2L-aZg6Lfe8PL0" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c1tcXF1eXy8xNzUyODc2NDk1NTU0MjY5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlNUIlNUMlNUQlNUVfIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyU1QiU1QyU1RCU1RV8/Z2VuZXJhdGlvbj0xNzUyODc2NDk1NTU0MjY5JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzW1xcXV5fIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDk1NTU0MjY5IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTjJONmVhMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE1LjU1N1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxNS41NTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE1LjU1N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxNS41NTdaIn0=" + } + }, + { + "ID": "20c49b2dfb63b1f9", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%5B%5C%5D%5E_", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:15 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:15 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876495554269" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH88kme0VODHcshn-aogMRDMXByS7_HRnaG1LCUNEuvbhzozJ55iA3QDMd5ugD3Jete8" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "b63875667a2af4c3", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%5B%5C%5D%5E_?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "806" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:15 GMT" + ], + "Etag": [ + "CN2N6ea1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_YAlEdF5t5yzSjNn8d8JigVaxXnispgJhqiz29-yxYX6m6TyMMYFG8le7vScq43D8" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c1tcXF1eXy8xNzUyODc2NDk1NTU0MjY5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlNUIlNUMlNUQlNUVfIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyU1QiU1QyU1RCU1RV8/Z2VuZXJhdGlvbj0xNzUyODc2NDk1NTU0MjY5JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzW1xcXV5fIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDk1NTU0MjY5IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTjJONmVhMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE1LjU1N1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxNS41NTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE1LjU1N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxNS41NTdaIn0=" + } + }, + { + "ID": "0d1c3a1bafec333e", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%5B%5C%5D%5E_?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:16 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:15 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876495554269" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-zGquhF9IyZYmdrYiD0-oyKmcfA4J7TeZnb-Mu9QKln5bhkZGJBIFU9FnJhwEA28Ll" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "3f5e772bf1757078", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%5B%5C%5D%5E_/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys%5B%5C%5D%5E_-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "927" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:16 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Jt964VF8bM4natx2Eqw-XqhuNydcj6UMAQJ3p7ZiRaZZP5yPWaPqk9NicSss688jc" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXNbXFxdXl8tY29weS8xNzUyODc2NDk2MTAwNjY0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlNUIlNUMlNUQlNUVfLWNvcHkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTVCJTVDJTVEJTVFXy1jb3B5P2dlbmVyYXRpb249MTc1Mjg3NjQ5NjEwMDY2NCZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c1tcXF1eXy1jb3B5IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDk2MTAwNjY0IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTGk2aXVlMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE2LjEwM1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxNi4xMDNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE2LjEwM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxNi4xMDNaIn19" + } + }, + { + "ID": "6b4fe9344a32803c", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%5B%5C%5D%5E_-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:16 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:16 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876496100664" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-PgzkUcYa-zvGNKbFtkP8_DjOifvCAr8W7KKnFw4sx4nECMa9C8dUaH2y3TevSmIQ" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "3eeeafaf68541ff2", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%5B%5C%5D%5E_-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:16 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88sX4L8iWFRvXdfIgXQu4XGp4giuGuWNM47fZd4brWRP7xKsf1GTWHS6UFIYmIjxJYvRYH7ftI" + ] + }, + "Body": "" + } + }, + { + "ID": "2e569d8a32a87142", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%5B%5C%5D%5E_?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:16 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_dtdoLfu6rTdAo9J3GjWYM0_1Eo7UAeSCpzcJbGHHsdF9ySkdNy0mAFM9qLfh2A1cFK2AC48o" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-7.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-7.replay new file mode 100644 index 000000000..c658f2afb --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-7.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzSH8SLRQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "3f75b47d1e933df3", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys%60\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzYCJ9Cg==", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "776" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:18 GMT" + ], + "Etag": [ + "CIeosui1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89cBKK-y3-2nTjFy1bea71mf5nq_2Ob1A9_pjplQSsdIWTxuHwHY0eo6qCaHcZNlicNnognCKQ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2AvMTc1Mjg3NjQ5ODg1MDgyMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTYwIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyU2MD9nZW5lcmF0aW9uPTE3NTI4NzY0OTg4NTA4MjMmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXNgIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDk4ODUwODIzIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSWVvc3VpMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE4Ljg1M1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxOC44NTNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE4Ljg1M1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxOC44NTNaIn0=" + } + }, + { + "ID": "311db5115accdfe9", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%60", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:19 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:18 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876498850823" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-DwIJvZXIPpZte-VbHsneZ3HB2s8ZWTle-jfT-hIiCRUT5PWq6x6BAPaQj8Gwspavg" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "188ace0ff612a6f5", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%60?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "776" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:19 GMT" + ], + "Etag": [ + "CIeosui1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_ZG8WtqLEwGLXOXdAju-4GuUuwLHRjFgm_35QuNf0OtmVQw0MPXX_ipgQDOq1GrnA" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2AvMTc1Mjg3NjQ5ODg1MDgyMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTYwIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyU2MD9nZW5lcmF0aW9uPTE3NTI4NzY0OTg4NTA4MjMmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXNgIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDk4ODUwODIzIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSWVvc3VpMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE4Ljg1M1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxOC44NTNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE4Ljg1M1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxOC44NTNaIn0=" + } + }, + { + "ID": "beda80d1a9601109", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%60?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:19 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:18 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876498850823" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-p-5OcSBb3S4ymqv-DYrOIaNWAJ7h9QGHpY9hHaz6POZ-1b9JrngRkReuhh0LDuno" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "62a4b81d9a165cfb", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%60/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys%60-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "897" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:19 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_1ny6ZEUMAiYW9VnbQWJYWZD2Qggxhelw8uIMGK5nAJ3ImNRn9LeiXKTUNXCcLAfuBWCRfNq4" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXNgLWNvcHkvMTc1Mjg3NjQ5OTM1MzkzMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTYwLWNvcHkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTYwLWNvcHk/Z2VuZXJhdGlvbj0xNzUyODc2NDk5MzUzOTMzJmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzYC1jb3B5IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDk5MzUzOTMzIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTTJDMGVpMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE5LjM1NloiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxOS4zNTZaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE5LjM1NloiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxOS4zNTZaIn19" + } + }, + { + "ID": "7863f7977690d282", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%60-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:19 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:19 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876499353933" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH892PKbHERFdnHIC50EHs6-p6DYj1GAidzKbAFMkXt2DhmdFKBVa6eL8HNR3nUhQ20g" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "168ea66b3cd9cff3", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%60-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:19 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88VQePjNl5qKwxbmLQEx8GytTPo1enzO0_igLsh1mkSHlwv3dX9QlPQIPPNj7ba09hSXpUXB7E" + ] + }, + "Body": "" + } + }, + { + "ID": "f03217e8737591ff", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%60?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:19 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-CvwwVMfHJ62oZnoXAPz_fbXRrDtVajs-3d5YyTnkg8bvmSKyUp8BokofUpZppZnVAZ1e1LoQ" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-8.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-8.replay new file mode 100644 index 000000000..428594795 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/ascii-8.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzQF30H3AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "74144978af1ec97b", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys%7B%7C%7D~%7F\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlze3x9fn8ifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "814" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:16 GMT" + ], + "Etag": [ + "CLGAsee1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_fvWhieBKiSukesbDrI0I8q5B0kS8HvgCqsR_oMVigFmvGlMeP6iHkHhVHPcv8nYnNe1XpifU" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c3t8fX5cdTAwN2YvMTc1Mjg3NjQ5NjczMjIwOSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTdCJTdDJTdEfiU3RiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlN0IlN0MlN0R+JTdGP2dlbmVyYXRpb249MTc1Mjg3NjQ5NjczMjIwOSZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c3t8fX5cdTAwN2YiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0OTY3MzIyMDkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNMR0FzZWUxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTYuNzM2WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE2LjczNloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTYuNzM2WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE2LjczNloifQ==" + } + }, + { + "ID": "03e1a8758088a889", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%7B%7C%7D~%7F", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:16 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:16 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876496732209" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89AlqpUF0nZ2k6IfcV-IJQBz9tW-cXcC9ZxN7w83nXcuMSNpHX6mNGOvWRcZAgoGOM" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6b5a3d012404ad6e", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%7B%7C%7D~%7F?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "814" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:16 GMT" + ], + "Etag": [ + "CLGAsee1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_Xou_ul53un8SKW5JKfovGdoHrHjPW-gUbWtD9smAX2pUulIug1mtokeT-s4taEkU" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c3t8fX5cdTAwN2YvMTc1Mjg3NjQ5NjczMjIwOSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTdCJTdDJTdEfiU3RiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlN0IlN0MlN0R+JTdGP2dlbmVyYXRpb249MTc1Mjg3NjQ5NjczMjIwOSZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c3t8fX5cdTAwN2YiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0OTY3MzIyMDkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNMR0FzZWUxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTYuNzM2WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE2LjczNloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTYuNzM2WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE2LjczNloifQ==" + } + }, + { + "ID": "657621b62550a7eb", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%7B%7C%7D~%7F?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:17 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:16 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876496732209" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH88hrkYOxRWTJhinbF5OuiZlED-yxm8UzC-sBj2KwIihO7VyXSUhNyDxPvYozMxDgUY" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "b13a8237e5245d99", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%7B%7C%7D~%7F/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys%7B%7C%7D~%7F-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "935" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:17 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-JDTsd5o3o_TaNlX1ZOK9OqmBmg4H5iaV_E6KvlmzsfylmRVfBEY48PRzGd-dY1OBFkI2aPnc" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXN7fH1+XHUwMDdmLWNvcHkvMTc1Mjg3NjQ5NzE1NDYyMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJTdCJTdDJTdEfiU3Ri1jb3B5IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cyU3QiU3QyU3RH4lN0YtY29weT9nZW5lcmF0aW9uPTE3NTI4NzY0OTcxNTQ2MjImYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXN7fH1+XHUwMDdmLWNvcHkiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0OTcxNTQ2MjIiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNMN2t5dWUxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTcuMTU3WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE3LjE1N1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTcuMTU3WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE3LjE1N1oifX0=" + } + }, + { + "ID": "2778081ed8211144", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%7B%7C%7D~%7F-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:17 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:17 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876497154622" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89ZdebRHtuocpnyCwvesDNufvwnQrABA_r_-88UVfflKP1Grx--TNv1ujftjNe-kr5Y" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "08a0808d3b9072f7", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%7B%7C%7D~%7F-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:17 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_OdSpGlu58OHuDsAsuWCS82abuWtgojX8LR__BH8kOJ6OYvRMKkTOraPCthIlmmo1r2DarVbw" + ] + }, + "Body": "" + } + }, + { + "ID": "21684e5a523776b4", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%7B%7C%7D~%7F?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:17 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89iD2M4oAdlnu4SABsFt_UHx_BQOnnsxbxq_jeeqAhUzvJiUxG0P3eL5PhmLdU6ofeKiXkhHsw" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/backslashes.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/backslashes.replay new file mode 100644 index 000000000..d9ed8db16 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/backslashes.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzJJbFulgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "f7002777923eec26", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keysfoo%5Cbar%5Cbaz\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vXFxiYXJcXGJheiJ9Cg==", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "824" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:09 GMT" + ], + "Etag": [ + "CO/kkuS1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Z3xA8IX3ovaUpMatRmv8avHCYcinELiqlFuo02su06_coSSqnKl2tcwZnJ8H57aA" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2Zvb1xcYmFyXFxiYXovMTc1Mjg3NjQ4OTk0NTcxMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzZm9vJTVDYmFyJTVDYmF6IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyU1Q2JhciU1Q2Jhej9nZW5lcmF0aW9uPTE3NTI4NzY0ODk5NDU3MTEmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXNmb29cXGJhclxcYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDg5OTQ1NzExIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTy9ra3VTMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA5Ljk0N1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowOS45NDdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA5Ljk0N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowOS45NDdaIn0=" + } + }, + { + "ID": "d0b04c20e4f66179", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%5Cbar%5Cbaz", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:09 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876489945711" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH88AanM79MmPtsMlz9iVtGUbZBq7PQpgUBsc0vnYE5_FBs1kehqPvARdJ2GraYJtrK4" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "0eca23405074235a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%5Cbar%5Cbaz?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "824" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:10 GMT" + ], + "Etag": [ + "CO/kkuS1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88wgmtJp-9nG63ck6GPKCU4KVymCgv9D2AzKZjEpXvng31SixZu_Yt0gdgYYhka-R4" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2Zvb1xcYmFyXFxiYXovMTc1Mjg3NjQ4OTk0NTcxMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzZm9vJTVDYmFyJTVDYmF6IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyU1Q2JhciU1Q2Jhej9nZW5lcmF0aW9uPTE3NTI4NzY0ODk5NDU3MTEmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXNmb29cXGJhclxcYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDg5OTQ1NzExIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTy9ra3VTMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA5Ljk0N1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowOS45NDdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA5Ljk0N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowOS45NDdaIn0=" + } + }, + { + "ID": "53531b084f54dae7", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%5Cbar%5Cbaz?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:09 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876489945711" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_UKz_FHpcwIQw0D4d7NStIyMzr6u1qHtod4gy-uvn7S4_O-L4zKWHT7A3uW85FFKc" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "c6875f7987e307a1", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%5Cbar%5Cbaz/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keysfoo%5Cbar%5Cbaz-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "945" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:10 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-4v7RiU1sbBkcl5C0krVGAhu9l_Lp8fo9_oZ6r4BflHDSpg_3SXRnjJSb5xlwVmijJ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXNmb29cXGJhclxcYmF6LWNvcHkvMTc1Mjg3NjQ5MDQzMTM4MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzZm9vJTVDYmFyJTVDYmF6LWNvcHkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzZm9vJTVDYmFyJTVDYmF6LWNvcHk/Z2VuZXJhdGlvbj0xNzUyODc2NDkwNDMxMzgxJmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vXFxiYXJcXGJhei1jb3B5IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDkwNDMxMzgxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSlczc09TMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjEwLjQzM1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMC40MzNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjEwLjQzM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxMC40MzNaIn19" + } + }, + { + "ID": "d1d5ca788a03d6d8", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%5Cbar%5Cbaz-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:10 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876490431381" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH892pS_gk1tFKDP1DZwuUFW-q4ixdAX8wkTFLhyMoFzru72eB9aPd_kC8ow78xOEWfU" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "56c4e715410c58f7", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%5Cbar%5Cbaz-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:10 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-S-FxRZFGEaZQUARpJ82gPrqfDy2cz2g_4ufve5TYhiNfxUL1euom-VaOHrkXYrIE" + ] + }, + "Body": "" + } + }, + { + "ID": "81eaa9debdd2d108", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%5Cbar%5Cbaz?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:10 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_3yF21OqbCTTngk1hOtYtZtL0vJ1G1HzJglJWx63SIgeoTc7snFps5apCVgOMiNHU" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/dotdotbackslash.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/dotdotbackslash.replay new file mode 100644 index 000000000..c7d8ce9d7 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/dotdotbackslash.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzCDTdr0wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "f9d3d0ccd5fbd994", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzLi5cXGZvb1xcLi5cXGJhclxcLi5cXC4uXFxiYXouLlxcIn0K", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "914" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:02 GMT" + ], + "Etag": [ + "CIOy0uC1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_LbdoYtVFyfuS72aE8Afy2GWrExNwtDSBGzrww2QahEMXkRtULNF0U-G7-JIoBmiDN" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5cy4uXFxmb29cXC4uXFxiYXJcXC4uXFwuLlxcYmF6Li5cXC8xNzUyODc2NDgyNTk5MTcxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMuLiU1Q2ZvbyU1Qy4uJTVDYmFyJTVDLi4lNUMuLiU1Q2Jhei4uJTVDIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cy4uJTVDZm9vJTVDLi4lNUNiYXIlNUMuLiU1Qy4uJTVDYmF6Li4lNUM/Z2VuZXJhdGlvbj0xNzUyODc2NDgyNTk5MTcxJmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzLi5cXGZvb1xcLi5cXGJhclxcLi5cXC4uXFxiYXouLlxcIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDgyNTk5MTcxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSU95MHVDMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAyLjYwMVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMi42MDFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAyLjYwMVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowMi42MDFaIn0=" + } + }, + { + "ID": "b72ac86e1508482f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:02 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:02 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876482599171" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-kWH3FOaGeXmvINg1ZntQpmmKzkXjl50zwDPJ4v9S-9qgBBrLOZUZyP1-2jO7imog" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "b8330bff2bbf5578", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "914" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:02 GMT" + ], + "Etag": [ + "CIOy0uC1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-_XzKmeg3783jR4cpZZ-PJIPEqSOEfnObiJQK7zLFnZnSQRCaSjfNQA2AiclSM94M" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5cy4uXFxmb29cXC4uXFxiYXJcXC4uXFwuLlxcYmF6Li5cXC8xNzUyODc2NDgyNTk5MTcxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMuLiU1Q2ZvbyU1Qy4uJTVDYmFyJTVDLi4lNUMuLiU1Q2Jhei4uJTVDIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cy4uJTVDZm9vJTVDLi4lNUNiYXIlNUMuLiU1Qy4uJTVDYmF6Li4lNUM/Z2VuZXJhdGlvbj0xNzUyODc2NDgyNTk5MTcxJmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzLi5cXGZvb1xcLi5cXGJhclxcLi5cXC4uXFxiYXouLlxcIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDgyNTk5MTcxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSU95MHVDMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAyLjYwMVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMi42MDFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAyLjYwMVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowMi42MDFaIn0=" + } + }, + { + "ID": "f214d4f476b6506b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:02 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:02 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876482599171" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_RrIyhTMbkmycrPBcm7N7vhCfot_HjasxWtQ-F0hJJiew0tiEoj20GygEksihM844" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "1eff4914eb067744", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "1035" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:03 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89qc2cqn8xWgzuKMS7JL4MQ5qdaVV6uBNzrDhYILx634K3hzD1X2tW09jjUra2hZA0" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXMuLlxcZm9vXFwuLlxcYmFyXFwuLlxcLi5cXGJhei4uXFwtY29weS8xNzUyODc2NDgzMDA0OTA3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMuLiU1Q2ZvbyU1Qy4uJTVDYmFyJTVDLi4lNUMuLiU1Q2Jhei4uJTVDLWNvcHkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzLi4lNUNmb28lNUMuLiU1Q2JhciU1Qy4uJTVDLi4lNUNiYXouLiU1Qy1jb3B5P2dlbmVyYXRpb249MTc1Mjg3NjQ4MzAwNDkwNyZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5cy4uXFxmb29cXC4uXFxiYXJcXC4uXFwuLlxcYmF6Li5cXC1jb3B5IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDgzMDA0OTA3IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDT3VUNitDMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAzLjAwN1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMy4wMDdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAzLjAwN1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowMy4wMDdaIn19" + } + }, + { + "ID": "6a4061c3836bffb5", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:03 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:03 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876483004907" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_nlslz4eP7OiepMuu8W9XooUhj8Yg3crUkeupWC0xbLQ_jN3JCWPp-QAO2TKu_uio" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "e1c21b9cfa1383d3", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:03 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89gFiwcIQTgE8irD5HlE2IRk8EQIN0fHUjNZrgihIQY31-Cvt3DV8yTVAF8P4o-ob0t" + ] + }, + "Body": "" + } + }, + { + "ID": "ffd12304f90b8d71", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:03 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-cztxr5S3hLsBCF9GQjMsfN0HbQyBazUoFTRjVQxyjJmfCmpapyeu0pnYuAdWo-MWl" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/dotdotslash.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/dotdotslash.replay new file mode 100644 index 000000000..672321628 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/dotdotslash.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLy/OuwSiwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "31c3fcbd05ec0b88", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzLi5fXzB4MmZfX2Zvby8uLl9fMHgyZl9fYmFyLy4uX18weDJmX18uLl9fMHgyZl9fYmF6Li5fXzB4MmZfXyJ9Cg==", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "1020" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:00 GMT" + ], + "Etag": [ + "CLSzxd+1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Wv868zXVu9YaUQoT_nxS0zyBOwMBqwZcp8JnLzm95FKnS5DkvpP-oRXwTsKEVfck1" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5cy4uX18weDJmX19mb28vLi5fXzB4MmZfX2Jhci8uLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18vMTc1Mjg3NjQ4MDI4OTIwNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzLi5fXzB4MmZfX2ZvbyUyRi4uX18weDJmX19iYXIlMkYuLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18iLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzLi5fXzB4MmZfX2ZvbyUyRi4uX18weDJmX19iYXIlMkYuLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18/Z2VuZXJhdGlvbj0xNzUyODc2NDgwMjg5MjA0JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzLi5fXzB4MmZfX2Zvby8uLl9fMHgyZl9fYmFyLy4uX18weDJmX18uLl9fMHgyZl9fYmF6Li5fXzB4MmZfXyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ4MDI4OTIwNCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0xTenhkKzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMC4yOTFaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDAuMjkxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMC4yOTFaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MDAuMjkxWiJ9" + } + }, + { + "ID": "a42770c43835dc3e", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:00 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:00 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876480289204" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89b6Yl698m2-mggo3UuRza9zmxikHJjTBc6WJqbLkLtv6bVa8BPjrtWd9pLRSgy4yrD" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "fa4e01ec05405d60", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1020" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:00 GMT" + ], + "Etag": [ + "CLSzxd+1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_XjGHWdXy308pdtB0hBtcZDpgTAmk3Uk5PBkd5_QLKzHrWwegf_CKhFOyg7MNJVIWd" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5cy4uX18weDJmX19mb28vLi5fXzB4MmZfX2Jhci8uLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18vMTc1Mjg3NjQ4MDI4OTIwNCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzLi5fXzB4MmZfX2ZvbyUyRi4uX18weDJmX19iYXIlMkYuLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18iLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzLi5fXzB4MmZfX2ZvbyUyRi4uX18weDJmX19iYXIlMkYuLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18/Z2VuZXJhdGlvbj0xNzUyODc2NDgwMjg5MjA0JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzLi5fXzB4MmZfX2Zvby8uLl9fMHgyZl9fYmFyLy4uX18weDJmX18uLl9fMHgyZl9fYmF6Li5fXzB4MmZfXyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ4MDI4OTIwNCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0xTenhkKzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMC4yOTFaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDAuMjkxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMC4yOTFaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MDAuMjkxWiJ9" + } + }, + { + "ID": "40749bfa3d926872", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:00 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:00 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876480289204" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_pou4uOTG10KXnugYEQS0aEH91lGa2elFxc6AOjgp1DrNC_t20GN_4M4s2JZdhhok" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "efef00d4f5dc6b52", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "1141" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:00 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89EW3Fr4TrjlMSh3Dd6Vr7uZ8plTwrlTx5rT0oRoOiP2lPFR6936JWgR4gl2PxO1xI" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXMuLl9fMHgyZl9fZm9vLy4uX18weDJmX19iYXIvLi5fXzB4MmZfXy4uX18weDJmX19iYXouLl9fMHgyZl9fLWNvcHkvMTc1Mjg3NjQ4MDc4NDMzOSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzLi5fXzB4MmZfX2ZvbyUyRi4uX18weDJmX19iYXIlMkYuLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18tY29weSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMuLl9fMHgyZl9fZm9vJTJGLi5fXzB4MmZfX2JhciUyRi4uX18weDJmX18uLl9fMHgyZl9fYmF6Li5fXzB4MmZfXy1jb3B5P2dlbmVyYXRpb249MTc1Mjg3NjQ4MDc4NDMzOSZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5cy4uX18weDJmX19mb28vLi5fXzB4MmZfX2Jhci8uLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18tY29weSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ4MDc4NDMzOSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ05QUDQ5KzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMC43ODZaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDAuNzg2WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMC43ODZaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MDAuNzg2WiJ9fQ==" + } + }, + { + "ID": "857a2b34cd1bee7d", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:00 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:00 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876480784339" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_CIX7E6PkA8hNrri5hdgpE6YGRkVfC1CTsjG-w3mGtF31j6juTxdGvRzeNEXQBxUJR" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "cb81ef683e2255a0", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:00 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_i_KS5AIqgazk0XLQmTcdwqeo_0nsD9yQkF5jniW7CEhcE-trUzv_XnjOKJTCXgSw" + ] + }, + "Body": "" + } + }, + { + "ID": "4d566841300d07d8", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:01 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89TT8foOrCfNjL7ChY2-dIbdXe3dNiQ8lOkFHvFHUb2YQmu7u-UbfJQd7TRQ6JsDbk" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/fwdslashes.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/fwdslashes.replay new file mode 100644 index 000000000..b2d81f59d --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/fwdslashes.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzIITWNggAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "dff36f4bc9795c4d", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keysfoo%2Fbar%2Fbaz\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vL2Jhci9iYXoifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "820" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:08 GMT" + ], + "Etag": [ + "CMm70eO1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88svGUIREbM4QNYsTRu5rN_tXm-Dl8jRbNHrBELG44bLQtYw8BoyBWsBGmMeoY2Ld_B" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2Zvby9iYXIvYmF6LzE3NTI4NzY0ODg4NzU0NjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyRmJhciUyRmJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXNmb28lMkZiYXIlMkZiYXo/Z2VuZXJhdGlvbj0xNzUyODc2NDg4ODc1NDY1JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vL2Jhci9iYXoiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0ODg4NzU0NjUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNNbTcwZU8xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDguODc4WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA4Ljg3OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDguODc4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA4Ljg3OFoifQ==" + } + }, + { + "ID": "f00abcff3b506d46", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%2Fbar%2Fbaz", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:08 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876488875465" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH88-RGklMsovImufXBkMOM7wnVO_dJQDs4Q4rvo-i8Y4kpxDaEqDWoIFtsv4Plm_t0o" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "2dcb32e3158e7844", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%2Fbar%2Fbaz?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "820" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:09 GMT" + ], + "Etag": [ + "CMm70eO1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_64trMKc8mVzFjoATGSP8gMfEbS7Qc7cPLziXQuO6g967lIOePW7XdOUZnQB4H2lg" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2Zvby9iYXIvYmF6LzE3NTI4NzY0ODg4NzU0NjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyRmJhciUyRmJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXNmb28lMkZiYXIlMkZiYXo/Z2VuZXJhdGlvbj0xNzUyODc2NDg4ODc1NDY1JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vL2Jhci9iYXoiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0ODg4NzU0NjUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNNbTcwZU8xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDguODc4WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA4Ljg3OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDguODc4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA4Ljg3OFoifQ==" + } + }, + { + "ID": "bc7a2eae5e98d87f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo/bar/baz?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:08 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876488875465" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH882hKVG1-xfaj4je28vZhWkzg-NK4yBrdi-wRxE51hFRimLk3ErwaJ6qhuWtUFOhdg" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "c8c9682880c2a042", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%2Fbar%2Fbaz/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keysfoo%2Fbar%2Fbaz-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "941" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:09 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89S_uEGpryRB54ad72TElpWtBZC1UTtGGioLlzj9rdL0khWcy9x-CVftMnVMtuOJnk" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXNmb28vYmFyL2Jhei1jb3B5LzE3NTI4NzY0ODkzNDc1MDEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyRmJhciUyRmJhei1jb3B5IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyRmJhciUyRmJhei1jb3B5P2dlbmVyYXRpb249MTc1Mjg3NjQ4OTM0NzUwMSZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c2Zvby9iYXIvYmF6LWNvcHkiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0ODkzNDc1MDEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLMmo3dU8xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDkuMzUwWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA5LjM1MFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDkuMzUwWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA5LjM1MFoifX0=" + } + }, + { + "ID": "664e6a4b74042a85", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%2Fbar%2Fbaz-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:09 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876489347501" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_1TdYjxdMqpS0Ky1E0Err_udc7ceQLF7c-X4EompNj08zgkzsbLVt2csHPk3g3nwc" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6bd8aedb05cf2149", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%2Fbar%2Fbaz-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:09 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_hS3l71Jmimyx6zdG2Y5E-bFJ2wxrrvsUWYSagNrW8o6lBHoHGaBK_FKdcT5_O8zI" + ] + }, + "Body": "" + } + }, + { + "ID": "e63413540b829342", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%2Fbar%2Fbaz?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:09 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Q_JBLIi9Vf9pAFQSsvDh8e27x3OiWKC9CLjfrnfp49qzE99EdcEaeZYh5VfMJVeg" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/non-UTF8_fails.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/non-UTF8_fails.replay new file mode 100644 index 000000000..e309f9865 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/non-UTF8_fails.replay @@ -0,0 +1,39 @@ +{ + "Initial": "AQAAAA7gDLy/OtihtQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/quote.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/quote.replay new file mode 100644 index 000000000..3da8e1c71 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/quote.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzFEjLgtgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "caf5a65025c4a30b", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keysfoo%22bar%22baz\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vXCJiYXJcImJheiJ9Cg==", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "824" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:05 GMT" + ], + "Etag": [ + "CKnii+K1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-m4Dk10q2MYZWIEBFfp8WjI2p-L3x7Hc5txM0Pbm7oQ4_tR-cAlrp6ZZP6icM2Rco" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2Zvb1wiYmFyXCJiYXovMTc1Mjg3NjQ4NTYzNjM5MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzZm9vJTIyYmFyJTIyYmF6IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyMmJhciUyMmJhej9nZW5lcmF0aW9uPTE3NTI4NzY0ODU2MzYzOTMmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXNmb29cImJhclwiYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDg1NjM2MzkzIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS25paStLMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA1LjYzOFoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowNS42MzhaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA1LjYzOFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowNS42MzhaIn0=" + } + }, + { + "ID": "fe631c3685cf2e29", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%22bar%22baz", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:05 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:05 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876485636393" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_moIfSAc9WYAsermPXeDZW3y4rORuFkv_eXfW5GQYVxeQc3XspyBXBrbaY-UDgnMM" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "c712b53a21f2a688", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%22bar%22baz?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "824" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:05 GMT" + ], + "Etag": [ + "CKnii+K1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_kGdwv6I8cHZDLhwxaq_fDYA8Fp8a_9Nhr5IPyTqjAYSpf0kc6ApQAkOkah4lVGW8" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2Zvb1wiYmFyXCJiYXovMTc1Mjg3NjQ4NTYzNjM5MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzZm9vJTIyYmFyJTIyYmF6IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyMmJhciUyMmJhej9nZW5lcmF0aW9uPTE3NTI4NzY0ODU2MzYzOTMmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXNmb29cImJhclwiYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDg1NjM2MzkzIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS25paStLMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA1LjYzOFoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowNS42MzhaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA1LjYzOFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowNS42MzhaIn0=" + } + }, + { + "ID": "dcdd0ac854b0f1f0", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%22bar%22baz?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:05 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876485636393" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_GaYk9vWoqKvsoVGbtwtzPMNL2u82bmaEL0eedC760iLKIh6biEUYWQpa8XhOEAvc" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "e48391248602490b", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%22bar%22baz/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keysfoo%22bar%22baz-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "945" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:06 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-9Lkg-pOv63UaUmmUTQdm5v-hxq5h_d54hzqoCBFy7omU5EtLcv0qSoMzkxgsCyiRg" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXNmb29cImJhclwiYmF6LWNvcHkvMTc1Mjg3NjQ4NjE0MTI0MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzZm9vJTIyYmFyJTIyYmF6LWNvcHkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzZm9vJTIyYmFyJTIyYmF6LWNvcHk/Z2VuZXJhdGlvbj0xNzUyODc2NDg2MTQxMjQxJmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vXCJiYXJcImJhei1jb3B5IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDg2MTQxMjQxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTG5LcXVLMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA2LjE0M1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowNi4xNDNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA2LjE0M1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowNi4xNDNaIn19" + } + }, + { + "ID": "7fa4029c0d520f1a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%22bar%22baz-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:06 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876486141241" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89TP1KAPcqNLDI8vmtUS2sMa2XeT0Nuv0dv91JIvsS1hHozbQaPbgKU9GoTedq9NAg" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "f07cacb0fa4f0844", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%22bar%22baz-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:06 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH888g_9tY0pQ5aCHX1JOlsseKsPOjfASSRYVTIjDf8z7OOWi69sKAo6wk-4G-E2aumGm" + ] + }, + "Body": "" + } + }, + { + "ID": "c87cf550a6afc4d9", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%22bar%22baz?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:06 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-KVSZ_vJ2Jdg7DzdTwYddlMLF2aIqGoiF3EUV-LXtjett2EwSWCKCwCJ_sfJI3R1Y" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/repeatedbackslashes.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/repeatedbackslashes.replay new file mode 100644 index 000000000..1626a1f74 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/repeatedbackslashes.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzBBUh6YwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "e18d4e114d291c01", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzLi5cXGZvb1xcXFxiYXJcXFxcXFxiYXoifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "872" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:01 GMT" + ], + "Etag": [ + "CKCViuC1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-h3M1QmJ9sww3stj5p_kBCqZmbAgFznPKOf-YSP8OIJvMmDoI-dKijrqQXZ-Dj6DWC" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5cy4uXFxmb29cXFxcYmFyXFxcXFxcYmF6LzE3NTI4NzY0ODE0MTU4NDAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cy4uJTVDZm9vJTVDJTVDYmFyJTVDJTVDJTVDYmF6IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cy4uJTVDZm9vJTVDJTVDYmFyJTVDJTVDJTVDYmF6P2dlbmVyYXRpb249MTc1Mjg3NjQ4MTQxNTg0MCZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5cy4uXFxmb29cXFxcYmFyXFxcXFxcYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDgxNDE1ODQwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS0NWaXVDMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAxLjQxOFoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMS40MThaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAxLjQxOFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowMS40MThaIn0=" + } + }, + { + "ID": "07828b76833b0829", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:01 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:01 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876481415840" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_Kwrs5EMVX4bLI3rGB9QYXFajCq7AXxigHma8gfa7CQYEgHRhhWEdiIJVXMFsvqt8" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "9b905e824e592a8f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "872" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:01 GMT" + ], + "Etag": [ + "CKCViuC1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88qEXxRffvfu4bQJZknxdBner1Ru6z1vevDhOYJgJPmkp2BXoMRlQKdvlHe1pU3TJY" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5cy4uXFxmb29cXFxcYmFyXFxcXFxcYmF6LzE3NTI4NzY0ODE0MTU4NDAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cy4uJTVDZm9vJTVDJTVDYmFyJTVDJTVDJTVDYmF6IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cy4uJTVDZm9vJTVDJTVDYmFyJTVDJTVDJTVDYmF6P2dlbmVyYXRpb249MTc1Mjg3NjQ4MTQxNTg0MCZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5cy4uXFxmb29cXFxcYmFyXFxcXFxcYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDgxNDE1ODQwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS0NWaXVDMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAxLjQxOFoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMS40MThaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAxLjQxOFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowMS40MThaIn0=" + } + }, + { + "ID": "2d1149e49a8f8629", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:01 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:01 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876481415840" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH884n61K--VydM31ayIjutWYdX4Wzb0IDInpA6Cvmp2c7p6lFvlU3iR7U87xGWR5e1A" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "589553987c63acde", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "993" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:01 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-cfnfw1G7bgTLxi30oUhlQwNBUNg6SvmRiYIIqNn3o_CyZl672yR52Vo4F4EJQmHI" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXMuLlxcZm9vXFxcXGJhclxcXFxcXGJhei1jb3B5LzE3NTI4NzY0ODE5MjEwNzciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5cy4uJTVDZm9vJTVDJTVDYmFyJTVDJTVDJTVDYmF6LWNvcHkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzLi4lNUNmb28lNUMlNUNiYXIlNUMlNUMlNUNiYXotY29weT9nZW5lcmF0aW9uPTE3NTI4NzY0ODE5MjEwNzcmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXMuLlxcZm9vXFxcXGJhclxcXFxcXGJhei1jb3B5IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDgxOTIxMDc3IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTFdBcWVDMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAxLjkyM1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODowMS45MjNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjAxLjkyM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODowMS45MjNaIn19" + } + }, + { + "ID": "7f53c5c1abc58ecb", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:01 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:01 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876481921077" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-VdHRc2bFO7vR5dGvWvO89tfYq1zn9ghA-zo1dhnEdw0Qqp2VdQZKbknYBUWGsAa59" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "326b578243785de4", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:02 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88xccwopJ47Cly1EbxhuaZkWi7Iu_WN9nX0HJLzxLk_xhGIqDdog5zpds8Xc6btmCg" + ] + }, + "Body": "" + } + }, + { + "ID": "1a14c6327b5780a4", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:02 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH892ldjHKTi6qr4mwrTS1QcDauMdrVm5o4GU_HVwE_-I-uJh9HXXXqopRE8icvlKwswhpLS31bM" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/repeatedfwdslashes.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/repeatedfwdslashes.replay new file mode 100644 index 000000000..b676496bb --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/repeatedfwdslashes.replay @@ -0,0 +1,375 @@ +{ + "Initial": "AQAAAA7gDLzEHWgFkwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "2c0d714dc36c3757", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keysfoo%2F%2Fbar%2F%2F%2Fbaz\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vLy9iYXIvLy9iYXoifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "844" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:04 GMT" + ], + "Etag": [ + "CJeu2eG1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89a39m017YTLA9cT6l6tSOEELIOvYJ8_Uus-O82rj3EHvXdo0SaKXyj6wFG76Lp8Fi_" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2Zvby8vYmFyLy8vYmF6LzE3NTI4NzY0ODQ4MTA1MTkiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyRiUyRmJhciUyRiUyRiUyRmJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXNmb28lMkYlMkZiYXIlMkYlMkYlMkZiYXo/Z2VuZXJhdGlvbj0xNzUyODc2NDg0ODEwNTE5JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vLy9iYXIvLy9iYXoiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0ODQ4MTA1MTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKZXUyZUcxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDQuODEzWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA0LjgxM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDQuODEzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA0LjgxM1oifQ==" + } + }, + { + "ID": "cd3ef2f5b000ef07", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%2F%2Fbar%2F%2F%2Fbaz", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:05 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:04 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876484810519" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-v_m0Fyxl2canHEfCr_V0ipEj6BBrYEbKRnL9r9fV2vIjE7D7ML8GHuz2gwJXIQMo" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "042a350ab3c1235b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%2F%2Fbar%2F%2F%2Fbaz?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "844" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:05 GMT" + ], + "Etag": [ + "CJeu2eG1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-HAeoyn0IVCi7zngoXGXlQp-6kH-vzVB6Pyc_v2mr0YW1IABCfKivQXG7FRrdYN1A" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2Zvby8vYmFyLy8vYmF6LzE3NTI4NzY0ODQ4MTA1MTkiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyRiUyRmJhciUyRiUyRiUyRmJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXNmb28lMkYlMkZiYXIlMkYlMkYlMkZiYXo/Z2VuZXJhdGlvbj0xNzUyODc2NDg0ODEwNTE5JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vLy9iYXIvLy9iYXoiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0ODQ4MTA1MTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKZXUyZUcxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDQuODEzWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA0LjgxM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MDQuODEzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjA0LjgxM1oifQ==" + } + }, + { + "ID": "bbde9800860ed317", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo//bar///baz?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:05 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:04 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876484810519" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_ftIcDcCFLE4fCpIwCyQT520go7c_md_-pBs1cRJMj1fkOTHyIuoAAdKrIa3Zaf1M" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6879ac1db38c678f", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%2F%2Fbar%2F%2F%2Fbaz?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:05 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Bpo13ZSqKdECNycYDUyEsVxsT_lpDmIivSiJBjbYdowIdqhZpk8L0TFmOfSVmmc0" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/spaces.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/spaces.replay new file mode 100644 index 000000000..51128b1ac --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/spaces.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzRG0irxwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "6dcd1fa0603e00a7", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keysfoo+bar+baz\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vIGJhciBiYXoifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "820" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:17 GMT" + ], + "Etag": [ + "CJHo7+e1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88th2ur3-TnNSlC-H4kwUHq-_aWq7VASKeEHrK8x25ZA_KPXTyweugj236zagrlTCrViSgU-ro" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2ZvbyBiYXIgYmF6LzE3NTI4NzY0OTc3NjEyOTciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyMGJhciUyMGJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXNmb28lMjBiYXIlMjBiYXo/Z2VuZXJhdGlvbj0xNzUyODc2NDk3NzYxMjk3JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vIGJhciBiYXoiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0OTc3NjEyOTciLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKSG83K2UxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTcuNzYzWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE3Ljc2M1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTcuNzYzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE3Ljc2M1oifQ==" + } + }, + { + "ID": "922f91a21290a368", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%20bar%20baz", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:17 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:17 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876497761297" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89KAbrkfsJWBkaVUhCFS31lCDww_NlZF86WjNxpQ_GV3mfokFtH2ssI2WVo9Ru8At0" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "9966755f77c587c1", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%20bar%20baz?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "820" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:18 GMT" + ], + "Etag": [ + "CJHo7+e1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_bYs8QCO8fn_QomLS1o-ENRfXN1I6uZLuWBNeBMjIDDT0cgHvBr5Q6kIwHCwFVtqc" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c2ZvbyBiYXIgYmF6LzE3NTI4NzY0OTc3NjEyOTciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyMGJhciUyMGJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXNmb28lMjBiYXIlMjBiYXo/Z2VuZXJhdGlvbj0xNzUyODc2NDk3NzYxMjk3JmFsdD1tZWRpYSIsIm5hbWUiOiJ3ZWlyZC1rZXlzZm9vIGJhciBiYXoiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0OTc3NjEyOTciLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKSG83K2UxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTcuNzYzWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE3Ljc2M1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTcuNzYzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE3Ljc2M1oifQ==" + } + }, + { + "ID": "c33e1eaf20138f2f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%20bar%20baz?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:18 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:17 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876497761297" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH889irCcSs0UFE-1fOXgXpFD1-RY4FXIqMFdiEg4FbFQtpWhlkPBPswZ-61vqfKeQiw" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "51df14166c817b35", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%20bar%20baz/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keysfoo%20bar%20baz-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "941" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:18 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88xJibCbzYlFVGWZ5W8_y9M1v4xSYTcJ_re2Pv1xj8qGH_XZgJbdQ07Lv1TyFuRH_X-GTn89E8" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXNmb28gYmFyIGJhei1jb3B5LzE3NTI4NzY0OTgyNTMwMjAiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyMGJhciUyMGJhei1jb3B5IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5c2ZvbyUyMGJhciUyMGJhei1jb3B5P2dlbmVyYXRpb249MTc1Mjg3NjQ5ODI1MzAyMCZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c2ZvbyBiYXIgYmF6LWNvcHkiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0OTgyNTMwMjAiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOenBqZWkxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTguMjU1WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE4LjI1NVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTguMjU1WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjE4LjI1NVoifX0=" + } + }, + { + "ID": "c5e75a9a7e20556c", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keysfoo%20bar%20baz-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:18 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:18 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876498253020" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-2uMfB3Zp6Q6IbPMJg73CvDp-ci1Ji1RkLXbkcDkfOpr-0wEjWSFb4sPhBzZs-B5k" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "d554a5a339d78f14", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%20bar%20baz-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:18 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_cUNKUObSeipD11t-hrnAIJ0T5SM9UsGsyRptt4Hj9DgytwqVqtMHvbH5yj-60Xfn-Ak2qiFs" + ] + }, + "Body": "" + } + }, + { + "ID": "60327387cae45f72", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keysfoo%20bar%20baz?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:18 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-P5nXGxDcDtRhzAw-QOwbbdE6o6tJC5uxBzw4sWhfbOHxJCqHWTi0OblXelf5CRP36E_LTO2U" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/startwithdigit.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/startwithdigit.replay new file mode 100644 index 000000000..1a69389af --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/startwithdigit.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzKLtmBUAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "20f908399a9290d6", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys12345\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlzMTIzNDUifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "788" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:11 GMT" + ], + "Etag": [ + "COeM2uS1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH887ZbZ0Nm3QdWrBn0h6X4XafPb2d733L5MbT8JHMyXsPlcd-hnZj8Tj6a0lwt2eAjk" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5czEyMzQ1LzE3NTI4NzY0OTExMTQwODciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5czEyMzQ1IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5czEyMzQ1P2dlbmVyYXRpb249MTc1Mjg3NjQ5MTExNDA4NyZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5czEyMzQ1IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDkxMTE0MDg3IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDT2VNMnVTMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjExLjExNloiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMS4xMTZaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjExLjExNloiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxMS4xMTZaIn0=" + } + }, + { + "ID": "50ae6c79827f5f80", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys12345", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:11 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876491114087" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_Zk5Rmbx43OXgi9SMgXJTUr-fZY5uL2LSRiPIxqLgwMaHXjpoSZFqW1_oTgZ1BxKk" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "8cf81373f6d04c0f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys12345?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "788" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:11 GMT" + ], + "Etag": [ + "COeM2uS1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89qm5Lvx08C5n3YHpivjFaXEQtvQKzmXf-hlme1FZn9h5P_k7F-2KZ4UyyTbzOFxSs" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5czEyMzQ1LzE3NTI4NzY0OTExMTQwODciLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5czEyMzQ1IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5czEyMzQ1P2dlbmVyYXRpb249MTc1Mjg3NjQ5MTExNDA4NyZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5czEyMzQ1IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDkxMTE0MDg3IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDT2VNMnVTMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjExLjExNloiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMS4xMTZaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjExLjExNloiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxMS4xMTZaIn0=" + } + }, + { + "ID": "388dcc053d28f835", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys12345?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:11 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876491114087" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Q-qN7pq2eyYM18E1XDPh0PKu3tlQ_AeK8_HHfRJkggz-D6kcBQRIX4kcy8hf9-0oB" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "7fa723790d870bf5", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys12345/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys12345-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "909" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:11 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_X8KKrpGWGwq5SnkvBMpvDfILce7NZiTrDw2NfJMaxnAsOpJ3SE35gIUi_LyAByaw" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXMxMjM0NS1jb3B5LzE3NTI4NzY0OTE1ODE3MTQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vd2VpcmQta2V5czEyMzQ1LWNvcHkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzMTIzNDUtY29weT9nZW5lcmF0aW9uPTE3NTI4NzY0OTE1ODE3MTQmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXMxMjM0NS1jb3B5IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDkxNTgxNzE0IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSkxTOXVTMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjExLjU4M1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMS41ODNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjExLjU4M1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoxMS41ODNaIn19" + } + }, + { + "ID": "36bc9d9d7c37ea71", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys12345-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:11 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876491581714" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_BlLgD1G8S5Pz6lqS16yT_BHfJmWyTzERdmOYED3tUYroaHNg8fEN96by1lWLW0BIw" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6cafb0bc089409e6", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys12345-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:11 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-WsMcv8JAavCVvYoMlQ05k08nQay2f17YorZAjoaCD6vzGpqC8zyhXJUxbI9IYfxk" + ] + }, + "Body": "" + } + }, + { + "ID": "3c1016827862faeb", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys12345?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:11 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Uida7ZqQ62DbxkLwxiHmGuVPU7S4TIZdcTr_65PLjTOMCqW3iTECWOspLt-wborM" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/unicode.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/unicode.replay new file mode 100644 index 000000000..fab4d0141 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestKeys/unicode.replay @@ -0,0 +1,576 @@ +{ + "Initial": "AQAAAA7gDLzLM2lAfAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "b72d935f0916252c", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=weird-keys%E2%98%BA%E2%98%BA%E2%98%BA\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJ3ZWlyZC1rZXlz4pi64pi64pi6In0K", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "840" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:12 GMT" + ], + "Etag": [ + "CLSwmuW1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88X9unFdt4ngZ55g19-wEN7-XX2YSn4N2XhIoqgFH2DOJfPZjwFUtAFVg7Nf3qnbGA" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c+KYuuKYuuKYui8xNzUyODc2NDkyMTY3MjIwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlRTIlOTglQkElRTIlOTglQkElRTIlOTglQkEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJUUyJTk4JUJBJUUyJTk4JUJBJUUyJTk4JUJBP2dlbmVyYXRpb249MTc1Mjg3NjQ5MjE2NzIyMCZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c+KYuuKYuuKYuiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ5MjE2NzIyMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0xTd211VzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMi4xNjlaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTIuMTY5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMi4xNjlaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MTIuMTY5WiJ9" + } + }, + { + "ID": "8675876e733667f3", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:12 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:12 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876492167220" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89eDHIbZu45FvlFvgPaS_AbmYBYg7cPIlj9mNNXAMURPLO6fLGQOTcAF2LD00kPEJ0" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "b1dc94bc080a227a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "840" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:12 GMT" + ], + "Etag": [ + "CLSwmuW1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-or7SzO2AZ7NSSctj7VoLD4PnXg7-9MTxTB7ybauEl3WyvOLfVPrfbNlEuBvUfun6r" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvd2VpcmQta2V5c+KYuuKYuuKYui8xNzUyODc2NDkyMTY3MjIwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlRTIlOTglQkElRTIlOTglQkElRTIlOTglQkEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby93ZWlyZC1rZXlzJUUyJTk4JUJBJUUyJTk4JUJBJUUyJTk4JUJBP2dlbmVyYXRpb249MTc1Mjg3NjQ5MjE2NzIyMCZhbHQ9bWVkaWEiLCJuYW1lIjoid2VpcmQta2V5c+KYuuKYuuKYuiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ5MjE2NzIyMCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0xTd211VzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMi4xNjlaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTIuMTY5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMi4xNjlaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MTIuMTY5WiJ9" + } + }, + { + "ID": "9d2f683b3f124cf4", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:12 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:12 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876492167220" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH89DuXrJ3WlZMORmZ9dukbZ-FT3YuhVrknOxtZm0Wr76ywrT4yfy6xnI0bnDnEcjIYo" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "638328912532f6ed", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA/rewriteTo/b/go-cloud-blob-test-bucket/o/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "961" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:12 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_R_sfPNFKYXXXxg6rhwzuvdCgcvv462dIOqEZq6NQTBF6GTaWTjTYrX8ami3TMF6jn" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiNSIsIm9iamVjdFNpemUiOiI1IiwiZG9uZSI6dHJ1ZSwicmVzb3VyY2UiOnsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L3dlaXJkLWtleXPimLrimLrimLotY29weS8xNzUyODc2NDkyNjQwODYzIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlRTIlOTglQkElRTIlOTglQkElRTIlOTglQkEtY29weSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3dlaXJkLWtleXMlRTIlOTglQkElRTIlOTglQkElRTIlOTglQkEtY29weT9nZW5lcmF0aW9uPTE3NTI4NzY0OTI2NDA4NjMmYWx0PW1lZGlhIiwibmFtZSI6IndlaXJkLWtleXPimLrimLrimLotY29weSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ5MjY0MDg2MyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ04ra3QrVzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMi42NDJaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MTIuNjQyWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoxMi42NDJaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDg6MTIuNjQyWiJ9fQ==" + } + }, + { + "ID": "9aeadb62319c3fb9", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:12 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:12 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876492640863" + ], + "X-Goog-Hash": [ + "crc32c=mnG7TA==", + "md5=XUFAKrxLKna5cZ2REBfFkg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "5" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_rrIrvZhigfYQWopdD0WVyiPA2pOn10U5gDbJkwmMJYC8oILxbw_yrU9kCdzoi9ME" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "7a391e2e4ebc37e0", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:12 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-HKcqQ_El19WBByMsqNmK8vN1pLoDpg4mSvYNidhp8cdqyvDWJVC1NIIYv-mngsPI" + ] + }, + "Body": "" + } + }, + { + "ID": "7567a37357aa4870", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:12 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_MaoF_XauxTpJ-_UL1h6Oh7Z-wyvS_w4KUqMolNyVWloMKQ_OExo50fL54XD5GD4U" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/PaginationConsistencyAfterDelete.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/PaginationConsistencyAfterDelete.replay new file mode 100644 index 000000000..a48c60e7c --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/PaginationConsistencyAfterDelete.replay @@ -0,0 +1,327 @@ +{ + "Initial": "AQAAAA7gDLyeMQXMuAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "9d96eba410193dd7", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2403" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:27 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88oqWliR9t4XXm6_uufcL-QzXmx9YlCFlJFI8wTsYOxAshjGPBhLfcr4LVUPWH1inI" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTAvMTU0OTY2MDkyMTY5OTM2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTA/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIxNjk5MzYzJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjE2OTkzNjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLTzRpdWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTEvMTc1Mjg3NTg1MTc3OTAzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTE/Z2VuZXJhdGlvbj0xNzUyODc1ODUxNzc5MDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTE3NzkwMzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOZVg3TE96eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + }, + { + "ID": "54fd004f0b18f7a4", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=2\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1657" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:27 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-j0hcRJYMTIqobUH-ehfe7TrtocJI9nFq7DzXsQFP91veC6OhK_Y2g1Zo8509pH3g" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNnOWliRzlpTFdadmNpMXNhWE4wTFRFPSIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbGlzdC0wLzE1NDk2NjA5MjE2OTkzNjMiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0wIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0wP2dlbmVyYXRpb249MTU0OTY2MDkyMTY5OTM2MyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbGlzdC0wIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTIxNjk5MzYzIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS080aXVhSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjowMS42OThaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjowMS42OThaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbGlzdC0xLzE3NTI4NzU4NTE3NzkwMzEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0xIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0xP2dlbmVyYXRpb249MTc1Mjg3NTg1MTc3OTAzMSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbGlzdC0xIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc1ODUxNzc5MDMxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTmVYN0xPeng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMS43ODFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMS43ODFaIn1dfQ==" + } + }, + { + "ID": "ca384c4a3b191495", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-list-1?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:27 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88OU2Nc_vY84OoTBN73_3BJcNjZzXlseqtYfhqHTPxgcWfzKWH92jia_hY5kAMwdp0" + ] + }, + "Body": "" + } + }, + { + "ID": "667ffc92e9e90f7f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=Cg9ibG9iLWZvci1saXN0LTE%3D\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "825" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:27 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88zU_U_4nSezT24egvt2pjy3kSCRDtdHkRyL6T9-_W-z_9gcS9rrq4qEtpQGchB6OY" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + }, + { + "ID": "aa97c7cbfffbd8e0", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-list-1\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "788" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:27 GMT" + ], + "Etag": [ + "CI3y88+1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Eba27VOv103ZHfwukno6WduRLzncGc88c1auCWsHjIB7v_PQoDILNl9LC_E-7ZYBk" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbGlzdC0xLzE3NTI4NzY0NDc0OTY0NjEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0xIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0xP2dlbmVyYXRpb249MTc1Mjg3NjQ0NzQ5NjQ2MSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbGlzdC0xIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDQ3NDk2NDYxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSTN5ODgrMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjI3LjQ5OVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzoyNy40OTlaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjI3LjQ5OVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzoyNy40OTlaIn0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/PaginationConsistencyAfterInsert.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/PaginationConsistencyAfterInsert.replay new file mode 100644 index 000000000..0957f7e7c --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/PaginationConsistencyAfterInsert.replay @@ -0,0 +1,327 @@ +{ + "Initial": "AQAAAA7gDLyeCAp64gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "f7223f9c1d7cc8a3", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2403" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:26 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89_RKzW6C7blSQvd3TdS26ge_1nqp7cRjVB8SAwA0tgdGbQONPStFQKVW2kmeBicUM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTAvMTU0OTY2MDkyMTY5OTM2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTA/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIxNjk5MzYzJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjE2OTkzNjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLTzRpdWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTEvMTc1Mjg3NTg1MTc3OTAzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTE/Z2VuZXJhdGlvbj0xNzUyODc1ODUxNzc5MDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTE3NzkwMzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOZVg3TE96eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + }, + { + "ID": "946e7a569edd93f6", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=2\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1657" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:26 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89SrKC7UyOKEz8a0G4k7NF8m4yFpMZgBl1ubdkS6Gi3bXZd2A-MzTvf2spnrRAMGUU" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNnOWliRzlpTFdadmNpMXNhWE4wTFRFPSIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbGlzdC0wLzE1NDk2NjA5MjE2OTkzNjMiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0wIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0wP2dlbmVyYXRpb249MTU0OTY2MDkyMTY5OTM2MyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbGlzdC0wIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTIxNjk5MzYzIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS080aXVhSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjowMS42OThaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjowMS42OThaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbGlzdC0xLzE3NTI4NzU4NTE3NzkwMzEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0xIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0xP2dlbmVyYXRpb249MTc1Mjg3NTg1MTc3OTAzMSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbGlzdC0xIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc1ODUxNzc5MDMxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTmVYN0xPeng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMS43ODFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMS43ODFaIn1dfQ==" + } + }, + { + "ID": "21e46c853cfb28cb", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-list-0a\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTBhIn0K", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "792" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:26 GMT" + ], + "Etag": [ + "CITwws+1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH895XgjwiDVkKuEex6reBO0odteRHg6u_8ZntG3l-UGhUXwA2mkKrdYyaCllEivegDH4" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbGlzdC0wYS8xNzUyODc2NDQ2NjkzMzgwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWxpc3QtMGEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTBhP2dlbmVyYXRpb249MTc1Mjg3NjQ0NjY5MzM4MCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbGlzdC0wYSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ0NjY5MzM4MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0lUd3dzKzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzoyNi42OTVaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MjYuNjk1WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzoyNi42OTVaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6MjYuNjk1WiJ9" + } + }, + { + "ID": "ef9bc2c044bcf81f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=Cg9ibG9iLWZvci1saXN0LTE%3D\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "825" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:26 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-6SHKufiFRQnu7Jkkwhf2hr1iQAEgur3NRkiKb4qF0gHapaEIiVxamKJWo4NZmUrbi" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + }, + { + "ID": "e296722707c3c299", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-list-0a?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:26 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88qWhJsWlmJ5cOxMG4iEpbE-19lP3JtciTShnEINvY4BG0cNwtRN0GMmnFl-HQ08MM" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/by_1.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/by_1.replay new file mode 100644 index 000000000..ae82971d4 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/by_1.replay @@ -0,0 +1,264 @@ +{ + "Initial": "AQAAAA7gDLycKr4wxgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "8788eedadea1e5d9", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2403" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:24 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-RgT15JLVly0JiwicD4oRvTE6wPZ4aMpCeFUJmMy5q9bYHMy2GkeZuKclGss2_JuI" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTAvMTU0OTY2MDkyMTY5OTM2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTA/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIxNjk5MzYzJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjE2OTkzNjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLTzRpdWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTEvMTc1Mjg3NTg1MTc3OTAzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTE/Z2VuZXJhdGlvbj0xNzUyODc1ODUxNzc5MDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTE3NzkwMzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOZVg3TE96eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + }, + { + "ID": "af30e1fed94f687a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "868" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:25 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_Xwgh4A-DXL7O7jMk7donboRKhVZ7vUV2PuQ-2mzy5dI0xPJsok17HN_WcP7ZjRlU" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNnOWliRzlpTFdadmNpMXNhWE4wTFRBPSIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbGlzdC0wLzE1NDk2NjA5MjE2OTkzNjMiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0wIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0wP2dlbmVyYXRpb249MTU0OTY2MDkyMTY5OTM2MyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbGlzdC0wIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTIxNjk5MzYzIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS080aXVhSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjowMS42OThaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjowMS42OThaIn1dfQ==" + } + }, + { + "ID": "daec5f9a1766ff2a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=Cg9ibG9iLWZvci1saXN0LTA%3D\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "868" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:25 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-ecEGTxv3Q9nON2otq_IyFgW44TT303UuTfjb9aewaKp0oUbAsd3ecpxWKffrDsSXG" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNnOWliRzlpTFdadmNpMXNhWE4wTFRFPSIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbGlzdC0xLzE3NTI4NzU4NTE3NzkwMzEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0xIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0xP2dlbmVyYXRpb249MTc1Mjg3NTg1MTc3OTAzMSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbGlzdC0xIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc1ODUxNzc5MDMxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTmVYN0xPeng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMS43ODFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMS43ODFaIn1dfQ==" + } + }, + { + "ID": "8f6489d88282ba92", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=Cg9ibG9iLWZvci1saXN0LTE%3D\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "825" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:25 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89AjKMH5XzX0wKYY5c_GQ4hvOmbLZkB-IYDPeVo6MPHz9VaTn_fnNne9xIMg9OE4UE" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/by_2.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/by_2.replay new file mode 100644 index 000000000..f4a6edeb6 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/by_2.replay @@ -0,0 +1,208 @@ +{ + "Initial": "AQAAAA7gDLydD2sj1gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "3bff47fd1fb26976", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2403" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:25 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_kTYB2YStgEiXDqIMxdhxgzdFbOMFGDPrKoZYNsKsolO8DPfuGGj25umjlta8jPKko" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTAvMTU0OTY2MDkyMTY5OTM2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTA/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIxNjk5MzYzJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjE2OTkzNjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLTzRpdWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTEvMTc1Mjg3NTg1MTc3OTAzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTE/Z2VuZXJhdGlvbj0xNzUyODc1ODUxNzc5MDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTE3NzkwMzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOZVg3TE96eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + }, + { + "ID": "6e756ac674a997cb", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=2\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1657" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:25 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-mAKIotzoDqCZAppOap7j-TG8LPaGaIs0m7I6Of1HOPrN7-nZEBdqcwgix420iYD16" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNnOWliRzlpTFdadmNpMXNhWE4wTFRFPSIsIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbGlzdC0wLzE1NDk2NjA5MjE2OTkzNjMiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0wIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0wP2dlbmVyYXRpb249MTU0OTY2MDkyMTY5OTM2MyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbGlzdC0wIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTIxNjk5MzYzIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS080aXVhSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjowMS42OThaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjowMS42OThaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbGlzdC0xLzE3NTI4NzU4NTE3NzkwMzEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0xIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbGlzdC0xP2dlbmVyYXRpb249MTc1Mjg3NTg1MTc3OTAzMSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbGlzdC0xIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc1ODUxNzc5MDMxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTmVYN0xPeng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMS43ODFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMS43ODFaIn1dfQ==" + } + }, + { + "ID": "58b0619829f565fa", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=2\u0026pageToken=Cg9ibG9iLWZvci1saXN0LTE%3D\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "825" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:25 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-jIqYPfYeLJqYoCXWjwr2ufT6qMHQIwQjpaF1-pugFoPdBog9UH_QjGzbrDgoaJEM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/by_3.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/by_3.replay new file mode 100644 index 000000000..9759b171d --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/by_3.replay @@ -0,0 +1,152 @@ +{ + "Initial": "AQAAAA7gDLydLc3eiwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "4860d97e2a42340f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2403" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:26 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_xVs9kG8I3CRUc8G_ADaEegkujCHjGI6WLjQOHqnIe5B9PLCxa88oO1-2I-7dZM4yp" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTAvMTU0OTY2MDkyMTY5OTM2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTA/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIxNjk5MzYzJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjE2OTkzNjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLTzRpdWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTEvMTc1Mjg3NTg1MTc3OTAzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTE/Z2VuZXJhdGlvbj0xNzUyODc1ODUxNzc5MDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTE3NzkwMzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOZVg3TE96eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + }, + { + "ID": "a019acd165644568", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=3\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2403" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:26 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8--RccOUMy60ZnKYyEOIRcwOgibm3sJdyA2L67-QxBnP2V2oGof0DmTmXnmT_q-603C" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTAvMTU0OTY2MDkyMTY5OTM2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTA/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIxNjk5MzYzJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjE2OTkzNjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLTzRpdWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTEvMTc1Mjg3NTg1MTc3OTAzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTE/Z2VuZXJhdGlvbj0xNzUyODc1ODUxNzc5MDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTE3NzkwMzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOZVg3TE96eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/exactly_1_object_due_to_prefix.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/exactly_1_object_due_to_prefix.replay new file mode 100644 index 000000000..fad26c345 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/exactly_1_object_due_to_prefix.replay @@ -0,0 +1,152 @@ +{ + "Initial": "AQAAAA7gDLybO2dScAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "d747469d32b7ca9e", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2403" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:24 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-uTjG42ID7_TjtDPoc3FEyaMY0hwzqvyY0Wnt2EyKMp_MqcQHIZ1luaLBiJq5uXorp" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTAvMTU0OTY2MDkyMTY5OTM2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTA/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIxNjk5MzYzJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjE2OTkzNjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLTzRpdWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTEvMTc1Mjg3NTg1MTc3OTAzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTE/Z2VuZXJhdGlvbj0xNzUyODc1ODUxNzc5MDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTE3NzkwMzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOZVg3TE96eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + }, + { + "ID": "8ce194150014005a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-list-1\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "825" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:24 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_F6r-ry5pQzf2O6wVw3_9XL58pNBoV6mfmsW7UO18R1XwXyF3F1-Tg7eyNK5k6QFTZ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTEvMTc1Mjg3NTg1MTc3OTAzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTE/Z2VuZXJhdGlvbj0xNzUyODc1ODUxNzc5MDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTE3NzkwMzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOZVg3TE96eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoifV19" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/no_objects.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/no_objects.replay new file mode 100644 index 000000000..17598023f --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/no_objects.replay @@ -0,0 +1,152 @@ +{ + "Initial": "AQAAAA7gDLybJYJHpAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "cc54429e9c676aa1", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2403" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:23 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88jE9Lelr8mG3lDk9uy5iFTmvJNfBH-t2YSPNqe7gMlIwvxk0u7hxcVpR1zhP6q-KsP" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTAvMTU0OTY2MDkyMTY5OTM2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTA/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIxNjk5MzYzJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjE2OTkzNjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLTzRpdWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTEvMTc1Mjg3NTg1MTc3OTAzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTE/Z2VuZXJhdGlvbj0xNzUyODc1ODUxNzc5MDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTE3NzkwMzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOZVg3TE96eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + }, + { + "ID": "1ee3b6f099c1596d", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=no-objects-with-this-prefix\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "26" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:23 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_gRAAufc9I2XWlXCPBz6X9bpvxiu6-7WRFy-QdWGAKCulGpFoCZC1-HBrar23-a2rZ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIn0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/no_pagination.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/no_pagination.replay new file mode 100644 index 000000000..97a864cfe --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestList/no_pagination.replay @@ -0,0 +1,152 @@ +{ + "Initial": "AQAAAA7gDLycFmGvVAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "d49ce032a7342a8d", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2403" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:24 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89r5Lthu5wPmPggsUnaPg_VodeE1Em_TU1PjGdPxk_S0VTvlYQuYffYCkagkuhyUhc" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTAvMTU0OTY2MDkyMTY5OTM2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTA/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIxNjk5MzYzJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjE2OTkzNjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLTzRpdWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTEvMTc1Mjg3NTg1MTc3OTAzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTE/Z2VuZXJhdGlvbj0xNzUyODc1ODUxNzc5MDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTE3NzkwMzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOZVg3TE96eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + }, + { + "ID": "45a4d828941bc102", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-list\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "2403" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:24 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89nMKuUhpV4nLP4zKA4zvOsCVg56kCmfOtCgrC8pcFlpfB7Gdi_6p2SGa6_9chXZvg" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTAvMTU0OTY2MDkyMTY5OTM2MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTA/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIxNjk5MzYzJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjE2OTkzNjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLTzRpdWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDEuNjk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAxLjY5OFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTEvMTc1Mjg3NTg1MTc3OTAzMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTE/Z2VuZXJhdGlvbj0xNzUyODc1ODUxNzc5MDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTE3NzkwMzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOZVg3TE96eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzEuNzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMxLjc4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1saXN0LTIvMTU0OTY2MDkyMjg1ODY1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1saXN0LTI/Z2VuZXJhdGlvbj0xNTQ5NjYwOTIyODU4NjU5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1saXN0LTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5MjI4NTg2NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLT1owZWFJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MDIuODU4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjAyLjg1OFoifV19" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestListDelimiters/abc.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestListDelimiters/abc.replay new file mode 100644 index 000000000..e3cd5a0bd --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestListDelimiters/abc.replay @@ -0,0 +1,719 @@ +{ + "Initial": "AQAAAA7gDLyiK9UyJAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "71d0a9cc9e2179ba", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-abc\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "5294" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:31 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89AfC0r_GoLT7yEfIBF9JPKMPksOKid9-HVLKCasfa1ApshrqDtRqexKPOGdg4GPwqh" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNhLnR4dC8xNTQ5NjYwOTUyMDY3MzU0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2EudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjYS50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTUyMDY3MzU0JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNhLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk1MjA2NzM1NCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0pyNngvU0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMi4wNjZaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzIuMDY2WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMi4wNjZaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MzIuMDY2WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2IudHh0LzE1NDk2NjA5NTI1OTc0MTEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjYi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNiLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NTI1OTc0MTEmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2IudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTUyNTk3NDExIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS09uNlBTSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMyLjU5N1oiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMi41OTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMyLjU5N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjozMi41OTdaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjYy50eHQvMTU0OTY2MDk1MzA2NDI2NSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNjLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2MudHh0P2dlbmVyYXRpb249MTU0OTY2MDk1MzA2NDI2NSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjYy50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5NTMwNjQyNjUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNNbm1oUFdJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzMuMDYzWiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMzLjA2M1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzMuMDYzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMzLjA2M1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNkLnR4dC8xNTQ5NjYwOTUzNTg0MzcyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2QudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjZC50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTUzNTg0MzcyJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNkLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk1MzU4NDM3MiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1BURnBQV0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMy41ODJaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzMuNTgyWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMy41ODJaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MzMuNTgyWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiY2UudHh0LzE3NTI4NzU4NTY0ODc4OTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjZS50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmNlLnR4dD9nZW5lcmF0aW9uPTE3NTI4NzU4NTY0ODc4OTgmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiY2UudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc1ODU2NDg3ODk4IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTnJMaTdheng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjM2LjQ5M1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNi40OTNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjM2LjQ5M1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNi40OTNaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dC8xNTQ5NjYwOTU0NTk5OTAyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2YudHh0P2dlbmVyYXRpb249MTU0OTY2MDk1NDU5OTkwMiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk1NDU5OTkwMiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ043RDR2V0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozNC41OTlaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzQuNTk5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozNC41OTlaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MzQuNTk5WiJ9XX0=" + } + }, + { + "ID": "f66e270a6eaf7890", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-abc\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "5294" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:31 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88d5HW-BHTZVNL9oc5rwgzRGBcQrjzsva5YQWezFa_zLmgv6bqAssnD2C2-aGA9yk8" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNhLnR4dC8xNTQ5NjYwOTUyMDY3MzU0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2EudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjYS50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTUyMDY3MzU0JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNhLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk1MjA2NzM1NCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0pyNngvU0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMi4wNjZaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzIuMDY2WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMi4wNjZaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MzIuMDY2WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2IudHh0LzE1NDk2NjA5NTI1OTc0MTEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjYi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNiLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NTI1OTc0MTEmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2IudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTUyNTk3NDExIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS09uNlBTSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMyLjU5N1oiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMi41OTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMyLjU5N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjozMi41OTdaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjYy50eHQvMTU0OTY2MDk1MzA2NDI2NSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNjLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2MudHh0P2dlbmVyYXRpb249MTU0OTY2MDk1MzA2NDI2NSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjYy50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5NTMwNjQyNjUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNNbm1oUFdJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzMuMDYzWiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMzLjA2M1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzMuMDYzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMzLjA2M1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNkLnR4dC8xNTQ5NjYwOTUzNTg0MzcyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2QudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjZC50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTUzNTg0MzcyJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNkLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk1MzU4NDM3MiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1BURnBQV0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMy41ODJaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzMuNTgyWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMy41ODJaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MzMuNTgyWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiY2UudHh0LzE3NTI4NzU4NTY0ODc4OTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjZS50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmNlLnR4dD9nZW5lcmF0aW9uPTE3NTI4NzU4NTY0ODc4OTgmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiY2UudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc1ODU2NDg3ODk4IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTnJMaTdheng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjM2LjQ5M1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNi40OTNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjM2LjQ5M1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNi40OTNaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dC8xNTQ5NjYwOTU0NTk5OTAyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2YudHh0P2dlbmVyYXRpb249MTU0OTY2MDk1NDU5OTkwMiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk1NDU5OTkwMiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ043RDR2V0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozNC41OTlaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzQuNTk5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozNC41OTlaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MzQuNTk5WiJ9XX0=" + } + }, + { + "ID": "0549229b6614e16b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=abc\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-abc\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "956" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:31 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88dOLZxfUin7u1awM5if_ez7sfk7-HKWdfDfWXaE8rEU0rfT_nuM_5JUGBmNif3WUU" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjIiwiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjIl0sIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dC8xNTQ5NjYwOTU0NTk5OTAyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2YudHh0P2dlbmVyYXRpb249MTU0OTY2MDk1NDU5OTkwMiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk1NDU5OTkwMiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ043RDR2V0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozNC41OTlaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzQuNTk5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozNC41OTlaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MzQuNTk5WiJ9XX0=" + } + }, + { + "ID": "2f86310d5279ec17", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=abc\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-abcdir1abc\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1829" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:31 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89yv-Bv7QTGFqrWJXAQaEVAiGT7-TMem4_jVzvG9yp1qdOUvi0_lFOV3bE8jfFPOWg" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjIl0sIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjYS50eHQvMTU0OTY2MDk1MjA2NzM1NCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNhLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2EudHh0P2dlbmVyYXRpb249MTU0OTY2MDk1MjA2NzM1NCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjYS50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5NTIwNjczNTQiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKcjZ4L1NJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzIuMDY2WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMyLjA2NloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzIuMDY2WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMyLjA2NloifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNiLnR4dC8xNTQ5NjYwOTUyNTk3NDExIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2IudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjYi50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTUyNTk3NDExJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNiLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk1MjU5NzQxMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0tPbjZQU0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMi41OTdaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzIuNTk3WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMi41OTdaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MzIuNTk3WiJ9XX0=" + } + }, + { + "ID": "4dc458b0bfe73ba8", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=abc\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-abcdir1abcsubdirabc\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1846" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:31 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_XZ99FwB5mzKIKzpltooZj4hHFqyqrfBGlJIj751tiz-MNSOx5-X4Ifbw3mQDxFes" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNjLnR4dC8xNTQ5NjYwOTUzMDY0MjY1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2MudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjYy50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTUzMDY0MjY1JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNjLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk1MzA2NDI2NSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ01ubWhQV0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMy4wNjNaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzMuMDYzWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMy4wNjNaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MzMuMDYzWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2QudHh0LzE1NDk2NjA5NTM1ODQzNzIiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjZC50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNkLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NTM1ODQzNzImYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2QudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTUzNTg0MzcyIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDUFRGcFBXSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMzLjU4MloiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozMy41ODJaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjMzLjU4MloiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjozMy41ODJaIn1dfQ==" + } + }, + { + "ID": "827933b1c27f1ad4", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=abc\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-abcdir2abc\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "905" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:31 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_MMVKp2Ru3qJ_EmxZ_SjVjbtOYpTrsKwIqsteo2PL6tKP6S2RAneXjgfcDHFOdO74" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmNlLnR4dC8xNzUyODc1ODU2NDg3ODk4Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiY2UudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjZS50eHQ/Z2VuZXJhdGlvbj0xNzUyODc1ODU2NDg3ODk4JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmNlLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NTg1NjQ4Nzg5OCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ05yTGk3YXp4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNi40OTNaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzYuNDkzWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNi40OTNaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjE6NTc6MzYuNDkzWiJ9XX0=" + } + }, + { + "ID": "694d90f0c123cd51", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=abc\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=\u0026prefix=blob-for-delimiters-abc\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "135" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:31 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-dZc7orbgSIv00m7mWJ4shjMKoVK3euBGxsXlOgdNYYk22hT_Enqh4xEQnNTHrSGg" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNoNWliRzlpTFdadmNpMWtaV3hwYldsMFpYSnpMV0ZpWTJScGNqRmhZbU09IiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjIl19" + } + }, + { + "ID": "25b580a5431049d5", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=abc\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=Ch5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmM%3D\u0026prefix=blob-for-delimiters-abc\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "135" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:31 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-PYJbCpiyCVXFE209CpvZ2ea--fMhmxreX2HAI8Yk_BaZ-sjjXvOT4JfJHvFg4_Gc" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNoNWliRzlpTFdadmNpMWtaV3hwYldsMFpYSnpMV0ZpWTJScGNqSmhZbU09IiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjIl19" + } + }, + { + "ID": "da57d5ba78944a58", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=abc\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=Ch5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmM%3D\u0026prefix=blob-for-delimiters-abc\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "877" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:31 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88789K2qYNO3inU0lN1QaOwtfE41xEtsPxv9YoxR2ugUhYyY-ffGkDxcP5dGRA-uwQ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2YudHh0LzE1NDk2NjA5NTQ1OTk5MDIiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTU0NTk5OTAyJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2YudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTU0NTk5OTAyIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTjdENHZXSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjM0LjU5OVoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozNC41OTlaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjM0LjU5OVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjozNC41OTlaIn1dfQ==" + } + }, + { + "ID": "05b2f525c687bdfd", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-delimiters-abcdir2abce.txt?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:32 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_AJQaCn72DBuJ_asl_nCwH_pm3C5kqHHb0ArrjbrkY8Aod0gtuy2NiTTsMPhoilwc" + ] + }, + "Body": "" + } + }, + { + "ID": "c15a13eb8c51bd84", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=abc\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-abc\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "923" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:32 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-K7lJMiXEGKQEYXySMxmCwUNXgDGUL6sSp34n2SQ39hqIkP5iLgE1LhGsTpD0CJZk" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjIl0sIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dC8xNTQ5NjYwOTU0NTk5OTAyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2YudHh0P2dlbmVyYXRpb249MTU0OTY2MDk1NDU5OTkwMiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk1NDU5OTkwMiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ043RDR2V0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozNC41OTlaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MzQuNTk5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjozNC41OTlaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MzQuNTk5WiJ9XX0=" + } + }, + { + "ID": "6d328da5bc0f701c", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-delimiters-abcdir2abce.txt\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmNlLnR4dCJ9Cg==", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "868" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:32 GMT" + ], + "Etag": [ + "CLPJktK1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88oz22b-CZOBz1gZDOjspFGaKaxu76ERYj37IP85NVyuU46vTCOmepJasOowmLjyag" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjZS50eHQvMTc1Mjg3NjQ1MjE5MzQ1OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmNlLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiY2UudHh0P2dlbmVyYXRpb249MTc1Mjg3NjQ1MjE5MzQ1OSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjZS50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NTIxOTM0NTkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNMUEprdEsxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzIuMTk2WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjMyLjE5NloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzIuMTk2WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjMyLjE5NloifQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestListDelimiters/backslash.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestListDelimiters/backslash.replay new file mode 100644 index 000000000..280e2d279 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestListDelimiters/backslash.replay @@ -0,0 +1,719 @@ +{ + "Initial": "AQAAAA7gDLyhD1OpwQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "1fd7079fb3b9f099", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%5C\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "5268" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:29 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88r3WFRBEGLDg5l-yyfvi4KxFxz3nW0yPwlITELfNr71_kP5xysXMS4WL8Mn_siKmM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLVxcZGlyMVxcYS50eHQvMTU1MjU4MTUwNTAxMjM1MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjElNUNhLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZGlyMSU1Q2EudHh0P2dlbmVyYXRpb249MTU1MjU4MTUwNTAxMjM1MSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXGEudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTUyNTgxNTA1MDEyMzUxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDUCtrM2VpSWd1RUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjAxMloiLCJ1cGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4wMTJaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjAxMloiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4wMTJaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXGIudHh0LzE1NTI1ODE1MDUxNDk0MzEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNkaXIxJTVDYi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjElNUNiLnR4dD9nZW5lcmF0aW9uPTE1NTI1ODE1MDUxNDk0MzEmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIxXFxiLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU1MjU4MTUwNTE0OTQzMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1BmVDVlaUlndUVDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4xNDlaIiwidXBkYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMTQ5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4xNDlaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMTQ5WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIxXFxzdWJkaXJcXGMudHh0LzE1NTI1ODE1MDUyNTc3ODYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNkaXIxJTVDc3ViZGlyJTVDYy50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjElNUNzdWJkaXIlNUNjLnR4dD9nZW5lcmF0aW9uPTE1NTI1ODE1MDUyNTc3ODYmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIxXFxzdWJkaXJcXGMudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTUyNTgxNTA1MjU3Nzg2IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTHFpN09pSWd1RUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjI1N1oiLCJ1cGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4yNTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjI1N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4yNTdaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXHN1YmRpclxcZC50eHQvMTU1MjU4MTUwNTM4MTY0MiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjElNUNzdWJkaXIlNUNkLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZGlyMSU1Q3N1YmRpciU1Q2QudHh0P2dlbmVyYXRpb249MTU1MjU4MTUwNTM4MTY0MiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXHN1YmRpclxcZC50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NTI1ODE1MDUzODE2NDIiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNJcnE4K2lJZ3VFQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMzgxWiIsInVwZGF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjM4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjM4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLVxcZGlyMlxcZS50eHQvMTc1Mjg3NTg1NTA1MzE5NyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjIlNUNlLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZGlyMiU1Q2UudHh0P2dlbmVyYXRpb249MTc1Mjg3NTg1NTA1MzE5NyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjJcXGUudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc1ODU1MDUzMTk3IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSTJEdExXeng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjM1LjA1N1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNS4wNTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjM1LjA1N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNS4wNTdaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1cXGYudHh0LzE1NTI1ODE1MDU2NzY5MjEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNmLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZi50eHQ/Z2VuZXJhdGlvbj0xNTUyNTgxNTA1Njc2OTIxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLVxcZi50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NTI1ODE1MDU2NzY5MjEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNQbnNoZW1JZ3VFQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuNjc2WiIsInVwZGF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjY3NloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuNjc2WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjY3NloifV19" + } + }, + { + "ID": "a47c23537a31ae4c", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%5C\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "5268" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:29 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_CBwS65DQUoUXK0w9q-lAoGedrxE_duPpihMcm2gfAcA_XfiVyEl2bx78giSfy8cs" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLVxcZGlyMVxcYS50eHQvMTU1MjU4MTUwNTAxMjM1MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjElNUNhLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZGlyMSU1Q2EudHh0P2dlbmVyYXRpb249MTU1MjU4MTUwNTAxMjM1MSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXGEudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTUyNTgxNTA1MDEyMzUxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDUCtrM2VpSWd1RUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjAxMloiLCJ1cGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4wMTJaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjAxMloiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4wMTJaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXGIudHh0LzE1NTI1ODE1MDUxNDk0MzEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNkaXIxJTVDYi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjElNUNiLnR4dD9nZW5lcmF0aW9uPTE1NTI1ODE1MDUxNDk0MzEmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIxXFxiLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU1MjU4MTUwNTE0OTQzMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1BmVDVlaUlndUVDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4xNDlaIiwidXBkYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMTQ5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4xNDlaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMTQ5WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIxXFxzdWJkaXJcXGMudHh0LzE1NTI1ODE1MDUyNTc3ODYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNkaXIxJTVDc3ViZGlyJTVDYy50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjElNUNzdWJkaXIlNUNjLnR4dD9nZW5lcmF0aW9uPTE1NTI1ODE1MDUyNTc3ODYmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIxXFxzdWJkaXJcXGMudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTUyNTgxNTA1MjU3Nzg2IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTHFpN09pSWd1RUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjI1N1oiLCJ1cGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4yNTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjI1N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4yNTdaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXHN1YmRpclxcZC50eHQvMTU1MjU4MTUwNTM4MTY0MiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjElNUNzdWJkaXIlNUNkLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZGlyMSU1Q3N1YmRpciU1Q2QudHh0P2dlbmVyYXRpb249MTU1MjU4MTUwNTM4MTY0MiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXHN1YmRpclxcZC50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NTI1ODE1MDUzODE2NDIiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNJcnE4K2lJZ3VFQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMzgxWiIsInVwZGF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjM4MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMzgxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjM4MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLVxcZGlyMlxcZS50eHQvMTc1Mjg3NTg1NTA1MzE5NyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjIlNUNlLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZGlyMiU1Q2UudHh0P2dlbmVyYXRpb249MTc1Mjg3NTg1NTA1MzE5NyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjJcXGUudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc1ODU1MDUzMTk3IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSTJEdExXeng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjM1LjA1N1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNS4wNTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjM1LjA1N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNS4wNTdaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1cXGYudHh0LzE1NTI1ODE1MDU2NzY5MjEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNmLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZi50eHQ/Z2VuZXJhdGlvbj0xNTUyNTgxNTA1Njc2OTIxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLVxcZi50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NTI1ODE1MDU2NzY5MjEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNQbnNoZW1JZ3VFQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuNjc2WiIsInVwZGF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjY3NloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuNjc2WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjY3NloifV19" + } + }, + { + "ID": "83b8f1127f9f6047", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%5C\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%5C\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "950" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:29 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88ATI2RQofqPtXAWThYGao_IN2lidZphBlZyAzQryocctaxZ8mNnUP8u0-vQf9CEn0" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXCIsImJsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIyXFwiXSwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLVxcZi50eHQvMTU1MjU4MTUwNTY3NjkyMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2YudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNmLnR4dD9nZW5lcmF0aW9uPTE1NTI1ODE1MDU2NzY5MjEmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtXFxmLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU1MjU4MTUwNTY3NjkyMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1Buc2hlbUlndUVDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS42NzZaIiwidXBkYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuNjc2WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS42NzZaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuNjc2WiJ9XX0=" + } + }, + { + "ID": "61352d5aed3b3a74", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%5C\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%5Cdir1%5C\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1818" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:29 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_EoTVvBcDjMbXxPUTjPIX6t_VWm_oUM3jskrFAfbYD2kDy-K7XQkFHnStbrdNdZTs" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXHN1YmRpclxcIl0sIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXGEudHh0LzE1NTI1ODE1MDUwMTIzNTEiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNkaXIxJTVDYS50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjElNUNhLnR4dD9nZW5lcmF0aW9uPTE1NTI1ODE1MDUwMTIzNTEmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIxXFxhLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU1MjU4MTUwNTAxMjM1MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1ArazNlaUlndUVDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4wMTJaIiwidXBkYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMDEyWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4wMTJaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMDEyWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIxXFxiLnR4dC8xNTUyNTgxNTA1MTQ5NDMxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZGlyMSU1Q2IudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNkaXIxJTVDYi50eHQ/Z2VuZXJhdGlvbj0xNTUyNTgxNTA1MTQ5NDMxJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLVxcZGlyMVxcYi50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NTI1ODE1MDUxNDk0MzEiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNQZlQ1ZWlJZ3VFQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMTQ5WiIsInVwZGF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjE0OVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMTQ5WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjE0OVoifV19" + } + }, + { + "ID": "8beb23171c5f182f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%5C\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%5Cdir1%5Csubdir%5C\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1834" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:29 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-5Ror05EjNMB15F0wxGj6RTFArxWzTrj5aEwYFjk8NsEbJEpLQdn3W3Ttuktf1W18" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLVxcZGlyMVxcc3ViZGlyXFxjLnR4dC8xNTUyNTgxNTA1MjU3Nzg2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZGlyMSU1Q3N1YmRpciU1Q2MudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNkaXIxJTVDc3ViZGlyJTVDYy50eHQ/Z2VuZXJhdGlvbj0xNTUyNTgxNTA1MjU3Nzg2JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLVxcZGlyMVxcc3ViZGlyXFxjLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU1MjU4MTUwNTI1Nzc4NiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0xxaTdPaUlndUVDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4yNTdaIiwidXBkYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMjU3WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4yNTdaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuMjU3WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIxXFxzdWJkaXJcXGQudHh0LzE1NTI1ODE1MDUzODE2NDIiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNkaXIxJTVDc3ViZGlyJTVDZC50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjElNUNzdWJkaXIlNUNkLnR4dD9nZW5lcmF0aW9uPTE1NTI1ODE1MDUzODE2NDImYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIxXFxzdWJkaXJcXGQudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTUyNTgxNTA1MzgxNjQyIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSXJxOCtpSWd1RUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjM4MVoiLCJ1cGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4zODFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjM4MVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS4zODFaIn1dfQ==" + } + }, + { + "ID": "fdbd0ede36498893", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%5C\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%5Cdir2%5C\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "901" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:30 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Q2cAPrK5q3fWdwPHB19HdspDF4k69LHlQ-VbTLT3PFh6_LGp7_F9_-VREW2LbhOy4" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLVxcZGlyMlxcZS50eHQvMTc1Mjg3NTg1NTA1MzE5NyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjIlNUNlLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZGlyMiU1Q2UudHh0P2dlbmVyYXRpb249MTc1Mjg3NTg1NTA1MzE5NyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjJcXGUudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc1ODU1MDUzMTk3IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSTJEdExXeng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjM1LjA1N1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNS4wNTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjM1LjA1N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1NzozNS4wNTdaIn1dfQ==" + } + }, + { + "ID": "fb33149d47898865", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%5C\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=\u0026prefix=blob-for-delimiters-%5C\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "129" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:30 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89qKuoJORRm1IPLL8npQ7Cbp5UWRIuR9sYDhAmvRNplOc4QdSeo_eNOt6OwgV8X_w0" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNocGliRzlpTFdadmNpMWtaV3hwYldsMFpYSnpMVnhrYVhJeFhBPT0iLCJwcmVmaXhlcyI6WyJibG9iLWZvci1kZWxpbWl0ZXJzLVxcZGlyMVxcIl19" + } + }, + { + "ID": "8b6d028bd6d6192f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%5C\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=ChpibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXA%3D%3D\u0026prefix=blob-for-delimiters-%5C\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "129" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:30 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH881_4BaXm82XUyoVg9PijYu22HnHbh0OJhO1Q_UoOfv0lbHxXKVF9JGLzLUnlIDB7w" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNocGliRzlpTFdadmNpMWtaV3hwYldsMFpYSnpMVnhrYVhJeVhBPT0iLCJwcmVmaXhlcyI6WyJibG9iLWZvci1kZWxpbWl0ZXJzLVxcZGlyMlxcIl19" + } + }, + { + "ID": "145ef013c6b26424", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%5C\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=ChpibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIyXA%3D%3D\u0026prefix=blob-for-delimiters-%5C\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "875" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:30 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89I0gSkTY7PanFdnvwotGZ4N70wsZVlDbWkehWsM6SXYiUUKWGqlO8g2lYzTvuVt1w" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLVxcZi50eHQvMTU1MjU4MTUwNTY3NjkyMSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2YudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNmLnR4dD9nZW5lcmF0aW9uPTE1NTI1ODE1MDU2NzY5MjEmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtXFxmLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU1MjU4MTUwNTY3NjkyMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1Buc2hlbUlndUVDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS42NzZaIiwidXBkYXRlZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuNjc2WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS42NzZaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDMtMTRUMTY6Mzg6MjUuNjc2WiJ9XX0=" + } + }, + { + "ID": "d0604303197042e7", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-delimiters-%5Cdir2%5Ce.txt?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:30 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8__PicRjnwHrnFoDBKL3DQWWXb3vk3Dl4GcLVgb1gEd3dUPgW0hWpqdtR8YL0gw12M" + ] + }, + "Body": "" + } + }, + { + "ID": "ce4d514a07e43905", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%5C\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%5C\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "919" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:30 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-58t0jQqdpxnKciceSe2M53SVKb-bibQJc2BgCwSm2YaQCmz6AcG2NLNemEQwzz8Ml" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjFcXCJdLCJpdGVtcyI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtXFxmLnR4dC8xNTUyNTgxNTA1Njc2OTIxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTVDZi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2YudHh0P2dlbmVyYXRpb249MTU1MjU4MTUwNTY3NjkyMSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy1cXGYudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTUyNTgxNTA1Njc2OTIxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDUG5zaGVtSWd1RUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjY3NloiLCJ1cGRhdGVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS42NzZaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAzLTE0VDE2OjM4OjI1LjY3NloiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMy0xNFQxNjozODoyNS42NzZaIn1dfQ==" + } + }, + { + "ID": "f291c75f1018b204", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-delimiters-%5Cdir2%5Ce.txt\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLVxcZGlyMlxcZS50eHQifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "864" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:30 GMT" + ], + "Etag": [ + "CPOUuNG1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8802vn3MqsdSXxAIgn1r7Bf5TgqbmvRlejYfFZDiQpP2HbL59NQNnNntf51aLh3iAIE" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy1cXGRpcjJcXGUudHh0LzE3NTI4NzY0NTA3MTIxNzkiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lNUNkaXIyJTVDZS50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSU1Q2RpcjIlNUNlLnR4dD9nZW5lcmF0aW9uPTE3NTI4NzY0NTA3MTIxNzkmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtXFxkaXIyXFxlLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ1MDcxMjE3OSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1BPVXVORzF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzozMC43MTRaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzAuNzE0WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzozMC43MTRaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6MzAuNzE0WiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestListDelimiters/fwdslash.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestListDelimiters/fwdslash.replay new file mode 100644 index 000000000..b134da7ca --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestListDelimiters/fwdslash.replay @@ -0,0 +1,719 @@ +{ + "Initial": "AQAAAA7gDLyfMARZaQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "0c75197ef0bc3805", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "5242" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:28 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_W2t1Oqq3QG5-yjh-uvI7zK1kuOwgFuew3ixSAZhwpZTslQRpmmA67m_kLi3-XJyo" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2EudHh0LzE1NDk2NjA5NDA1NTQ4MTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGYS50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmRpcjElMkZhLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NDA1NTQ4MTgmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvYS50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5NDA1NTQ4MTgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNNS2tpZStJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjAuNTU0WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIwLjU1NFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjAuNTU0WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIwLjU1NFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2IudHh0LzE1NDk2NjA5NDEwOTk5NjIiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGYi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmRpcjElMkZiLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NDEwOTk5NjImYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvYi50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5NDEwOTk5NjIiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNMckhxdStJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjEuMDk5WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIxLjA5OVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjEuMDk5WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIxLjA5OVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci9jLnR4dC8xNTQ5NjYwOTQxNTYwNDE3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTJGZGlyMSUyRnN1YmRpciUyRmMudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGc3ViZGlyJTJGYy50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTQxNTYwNDE3JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci9jLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk0MTU2MDQxNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ09IVXh1K0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMS41NTlaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjEuNTU5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMS41NTlaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MjEuNTU5WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvc3ViZGlyL2QudHh0LzE1NDk2NjA5NDIyMjE2NTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGc3ViZGlyJTJGZC50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmRpcjElMkZzdWJkaXIlMkZkLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NDIyMjE2NTgmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvc3ViZGlyL2QudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTQyMjIxNjU4IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTnFDNysrSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIyLjIyMVoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMi4yMjFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIyLjIyMVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMi4yMjFaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMi9lLnR4dC8xNzUyODc1ODUzNjE1NjM5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTJGZGlyMiUyRmUudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIyJTJGZS50eHQ/Z2VuZXJhdGlvbj0xNzUyODc1ODUzNjE1NjM5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyL2UudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc1ODUzNjE1NjM5IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSmVrM0xTeng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMzLjYxN1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMy42MTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMzLjYxN1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMy42MTdaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy0vZi50eHQvMTU0OTY2MDk0MzQwNTIwOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmYudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZmLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NDM0MDUyMDgmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtL2YudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTQzNDA1MjA4IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSmlodC9DSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIzLjQwM1oiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMy40MDNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIzLjQwM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMy40MDNaIn1dfQ==" + } + }, + { + "ID": "08b7bba46a11b946", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "5242" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:28 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88CLMitzg1fV9WYBhJJ4yXtaZewxW5st8tM9Y5Y9eoQPlot9JKf_Kh4EkUFwbxyx7Ut" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2EudHh0LzE1NDk2NjA5NDA1NTQ4MTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGYS50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmRpcjElMkZhLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NDA1NTQ4MTgmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvYS50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5NDA1NTQ4MTgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNNS2tpZStJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjAuNTU0WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIwLjU1NFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjAuNTU0WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIwLjU1NFoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2IudHh0LzE1NDk2NjA5NDEwOTk5NjIiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGYi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmRpcjElMkZiLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NDEwOTk5NjImYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvYi50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5NDEwOTk5NjIiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNMckhxdStJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjEuMDk5WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIxLjA5OVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjEuMDk5WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIxLjA5OVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci9jLnR4dC8xNTQ5NjYwOTQxNTYwNDE3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTJGZGlyMSUyRnN1YmRpciUyRmMudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGc3ViZGlyJTJGYy50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTQxNTYwNDE3JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci9jLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk0MTU2MDQxNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ09IVXh1K0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMS41NTlaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjEuNTU5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMS41NTlaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MjEuNTU5WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvc3ViZGlyL2QudHh0LzE1NDk2NjA5NDIyMjE2NTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGc3ViZGlyJTJGZC50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmRpcjElMkZzdWJkaXIlMkZkLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NDIyMjE2NTgmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvc3ViZGlyL2QudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTQyMjIxNjU4IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTnFDNysrSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIyLjIyMVoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMi4yMjFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIyLjIyMVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMi4yMjFaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMi9lLnR4dC8xNzUyODc1ODUzNjE1NjM5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTJGZGlyMiUyRmUudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIyJTJGZS50eHQ/Z2VuZXJhdGlvbj0xNzUyODc1ODUzNjE1NjM5JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyL2UudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc1ODUzNjE1NjM5IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSmVrM0xTeng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMzLjYxN1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMy42MTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMzLjYxN1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1NzozMy42MTdaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy0vZi50eHQvMTU0OTY2MDk0MzQwNTIwOCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmYudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZmLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NDM0MDUyMDgmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtL2YudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTQzNDA1MjA4IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSmlodC9DSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIzLjQwM1oiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMy40MDNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIzLjQwM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMy40MDNaIn1dfQ==" + } + }, + { + "ID": "401d72675274271e", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "944" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:28 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88mHLZ8KOn4dbyPGcZ1SiR7CWHSpA5tc64HklYqCfOpyqGKXnbkJGItEujou_A2dTs" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS8iLCJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyLyJdLCJpdGVtcyI6W3sia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtL2YudHh0LzE1NDk2NjA5NDM0MDUyMDgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZmLnR4dCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTJGZi50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTQzNDA1MjA4JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLS9mLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk0MzQwNTIwOCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0ppaHQvQ0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMy40MDNaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjMuNDAzWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMy40MDNaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MjMuNDAzWiJ9XX0=" + } + }, + { + "ID": "05c806ea67236a7b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%2Fdir1%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1807" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:28 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88XmRybuL6_X1XodXieRNtAocm3i2Q2rKDgoIu0esSZ_onehqhxt91vtSOYRaaSIQ0" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvIl0sIml0ZW1zIjpbeyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9hLnR4dC8xNTQ5NjYwOTQwNTU0ODE4Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTJGZGlyMSUyRmEudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGYS50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTQwNTU0ODE4JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2EudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTQwNTU0ODE4IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTUtraWUrSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIwLjU1NFoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMC41NTRaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIwLjU1NFoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMC41NTRaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9iLnR4dC8xNTQ5NjYwOTQxMDk5OTYyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTJGZGlyMSUyRmIudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGYi50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTQxMDk5OTYyJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2IudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTQxMDk5OTYyIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTHJIcXUrSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIxLjA5OVoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMS4wOTlaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIxLjA5OVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMS4wOTlaIn1dfQ==" + } + }, + { + "ID": "8938204df2dd6618", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%2Fdir1%2Fsubdir%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1822" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:28 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89d5ssOeEBCyNckByl7M_5TRMaZPKUXf4FNeN5Re4JSdWVnOGumIF_8B6FxNW0JDV9c" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci9jLnR4dC8xNTQ5NjYwOTQxNTYwNDE3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTJGZGlyMSUyRnN1YmRpciUyRmMudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGc3ViZGlyJTJGYy50eHQ/Z2VuZXJhdGlvbj0xNTQ5NjYwOTQxNTYwNDE3JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci9jLnR4dCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY2MDk0MTU2MDQxNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ09IVXh1K0lyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMS41NTlaIiwidXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjEuNTU5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMS41NTlaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDhUMjE6MjI6MjEuNTU5WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvc3ViZGlyL2QudHh0LzE1NDk2NjA5NDIyMjE2NTgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIxJTJGc3ViZGlyJTJGZC50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmRpcjElMkZzdWJkaXIlMkZkLnR4dD9nZW5lcmF0aW9uPTE1NDk2NjA5NDIyMjE2NTgmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvc3ViZGlyL2QudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjYwOTQyMjIxNjU4IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTnFDNysrSXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIyLjIyMVoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMi4yMjFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIyLjIyMVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOFQyMToyMjoyMi4yMjFaIn1dfQ==" + } + }, + { + "ID": "021f4399baaff340", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%2Fdir2%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "897" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:28 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-okitEGALN7-cbjk3hy4tLV1aiCERlDmIFO-GHspHua5dq1wDa60S8KZYxUX29PSAQ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyL2UudHh0LzE3NTI4NzU4NTM2MTU2MzkiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIyJTJGZS50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmRpcjIlMkZlLnR4dD9nZW5lcmF0aW9uPTE3NTI4NzU4NTM2MTU2MzkmYWx0PW1lZGlhIiwibmFtZSI6ImJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjIvZS50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4NTM2MTU2MzkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKZWszTFN6eDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzMuNjE3WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMzLjYxN1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjE6NTc6MzMuNjE3WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIxOjU3OjMzLjYxN1oifV19" + } + }, + { + "ID": "9d3df81b7482c625", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=\u0026prefix=blob-for-delimiters-%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "127" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:28 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_pJwvpj4jYJkO1dSUDFNUDCEKm7vzVf6iQVQFjFaxeu-8hpiVdeQTgrqPHs2Ud4gg" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNocGliRzlpTFdadmNpMWtaV3hwYldsMFpYSnpMUzlrYVhJeEx3PT0iLCJwcmVmaXhlcyI6WyJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLyJdfQ==" + } + }, + { + "ID": "1a33b71f3af98f1b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=ChpibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLw%3D%3D\u0026prefix=blob-for-delimiters-%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "127" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:28 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-KZS2sRl5ZkFHdGhdQhlKmJ4sXcrK3Zg59Iz_Ou6bphu5BF_T-2Ek1SaDTWPgOSTun" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNocGliRzlpTFdadmNpMWtaV3hwYldsMFpYSnpMUzlrYVhJeUx3PT0iLCJwcmVmaXhlcyI6WyJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyLyJdfQ==" + } + }, + { + "ID": "1c64093827856993", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=ChpibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyLw%3D%3D\u0026prefix=blob-for-delimiters-%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "873" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:28 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-KauwXS5Gh15JVFLFvrwUbCjF-AR8MDovIhn91_okWL2WfWfJXblg8SZz5YqJSYRmq" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLS9mLnR4dC8xNTQ5NjYwOTQzNDA1MjA4Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTJGZi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmYudHh0P2dlbmVyYXRpb249MTU0OTY2MDk0MzQwNTIwOCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy0vZi50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5NDM0MDUyMDgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKaWh0L0NJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjMuNDAzWiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIzLjQwM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjMuNDAzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIzLjQwM1oifV19" + } + }, + { + "ID": "53413b9e143e5ad9", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-delimiters-%2Fdir2%2Fe.txt?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:29 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_iS_mkblxuFCLgBjSXGehp00lheOnPpFo2H7jTrc5C0sBgJV-Vhr_FkCR_NlS0Nyc" + ] + }, + "Body": "" + } + }, + { + "ID": "7cf49bb9389d99b1", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=%2F\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-delimiters-%2F\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "915" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:29 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH896XdrsCA7v4yCQ_7FJ6lKhEjEmmcY-MUS3QuRw_d1sYvXCIaut6ZDB4rQBUngUHeUG" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwicHJlZml4ZXMiOlsiYmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS8iXSwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1kZWxpbWl0ZXJzLS9mLnR4dC8xNTQ5NjYwOTQzNDA1MjA4Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTJGZi50eHQiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1kZWxpbWl0ZXJzLSUyRmYudHh0P2dlbmVyYXRpb249MTU0OTY2MDk0MzQwNTIwOCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItZGVsaW1pdGVycy0vZi50eHQiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NjA5NDM0MDUyMDgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKaWh0L0NJcmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjMuNDAzWiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIzLjQwM1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDhUMjE6MjI6MjMuNDAzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA4VDIxOjIyOjIzLjQwM1oifV19" + } + }, + { + "ID": "d9cc7819f753fbd6", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-delimiters-%2Fdir2%2Fe.txt\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyL2UudHh0In0K", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "860" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:29 GMT" + ], + "Etag": [ + "CPKH3tC1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88qgVAWCdfmVGKOKz5oiit50849TAa07x3rkLccwzMOttbSBfrcIUs6wWS09b0TuOY" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMi9lLnR4dC8xNzUyODc2NDQ5MjM1OTU0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLWRlbGltaXRlcnMtJTJGZGlyMiUyRmUudHh0IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItZGVsaW1pdGVycy0lMkZkaXIyJTJGZS50eHQ/Z2VuZXJhdGlvbj0xNzUyODc2NDQ5MjM1OTU0JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyL2UudHh0IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDQ5MjM1OTU0IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDUEtIM3RDMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjI5LjIzN1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzoyOS4yMzdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjI5LjIzN1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzoyOS4yMzdaIn0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestListWeirdKeys.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestListWeirdKeys.replay new file mode 100644 index 000000000..4bee7e5f2 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestListWeirdKeys.replay @@ -0,0 +1,152 @@ +{ + "Initial": "AQAAAA7gDLyfHu63QAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "9f83811e0d43e031", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=list-weirdkeys-\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "15938" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:27 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH884PfSzKfkS2rWDpG5ka3Rw0FQYRKAq37J7lRD2-wwnK8No-St7FINJNZki5P5zPfU" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9saXN0LXdlaXJka2V5cy1cdTAwMDBcdTAwMDFcdTAwMDJcdTAwMDNcdTAwMDRcdTAwMDVcdTAwMDZcdTAwMDdcYlx0X18weGFfX1x1MDAwYlxmX18weGRfX1x1MDAwZVx1MDAwZi8xNTQ5NjcxMDA2NzcxOTI1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSUwMCUwMSUwMiUwMyUwNCUwNSUwNiUwNyUwOCUwOV9fMHhhX18lMEIlMENfXzB4ZF9fJTBFJTBGIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbGlzdC13ZWlyZGtleXMtJTAwJTAxJTAyJTAzJTA0JTA1JTA2JTA3JTA4JTA5X18weGFfXyUwQiUwQ19fMHhkX18lMEUlMEY/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA2NzcxOTI1JmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy1cdTAwMDBcdTAwMDFcdTAwMDJcdTAwMDNcdTAwMDRcdTAwMDVcdTAwMDZcdTAwMDdcYlx0X18weGFfX1x1MDAwYlxmX18weGRfX1x1MDAwZVx1MDAwZiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNjc3MTkyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ05XMWdxK3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi43NzFaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNzcxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi43NzFaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNzcxWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLVx1MDAxMFx1MDAxMVx1MDAxMlx1MDAxM1x1MDAxNFx1MDAxNVx1MDAxNlx1MDAxN1x1MDAxOFx1MDAxOVx1MDAxYVx1MDAxYlx1MDAxY1x1MDAxZFx1MDAxZVx1MDAxZi8xNTQ5NjcxMDA3OTQ1NTExIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSUxMCUxMSUxMiUxMyUxNCUxNSUxNiUxNyUxOCUxOSUxQSUxQiUxQyUxRCUxRSUxRiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSUxMCUxMSUxMiUxMyUxNCUxNSUxNiUxNyUxOCUxOSUxQSUxQiUxQyUxRCUxRSUxRj9nZW5lcmF0aW9uPTE1NDk2NzEwMDc5NDU1MTEmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLVx1MDAxMFx1MDAxMVx1MDAxMlx1MDAxM1x1MDAxNFx1MDAxNVx1MDAxNlx1MDAxN1x1MDAxOFx1MDAxOVx1MDAxYVx1MDAxYlx1MDAxY1x1MDAxZFx1MDAxZVx1MDAxZiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNzk0NTUxMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0tlR3lxK3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy45NDVaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuOTQ1WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy45NDVaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuOTQ1WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLSAhXCIjJCUmJygpKissLS4vLzE1NDk2NzEwMDczOTIxMTYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbGlzdC13ZWlyZGtleXMtJTIwISUyMiUyMyQlMjUmJygpKiUyQiwtLiUyRiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSUyMCElMjIlMjMkJTI1JicoKSolMkIsLS4lMkY/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA3MzkyMTE2JmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy0gIVwiIyQlJicoKSorLC0uLyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNzM5MjExNiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1BTaXFLK3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4zOTFaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMzkxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4zOTFaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMzkxWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLS4uXFxmb29cXC4uXFxiYXJcXC4uXFwuLlxcYmF6Li5cXC8xNTQ5NjcxMDA3NzQwMjI0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLS4uJTVDZm9vJTVDLi4lNUNiYXIlNUMuLiU1Qy4uJTVDYmF6Li4lNUMiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy0uLiU1Q2ZvbyU1Qy4uJTVDYmFyJTVDLi4lNUMuLiU1Q2Jhei4uJTVDP2dlbmVyYXRpb249MTU0OTY3MTAwNzc0MDIyNCZhbHQ9bWVkaWEiLCJuYW1lIjoibGlzdC13ZWlyZGtleXMtLi5cXGZvb1xcLi5cXGJhclxcLi5cXC4uXFxiYXouLlxcIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA3NzQwMjI0IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTURDdmErdXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjczOVoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy43MzlaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjczOVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy43MzlaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMtLi5cXGZvb1xcXFxiYXJcXFxcXFxiYXovMTU0OTY3MTAwNjQyNzYyMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy0uLiU1Q2ZvbyU1QyU1Q2JhciU1QyU1QyU1Q2JheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLS4uJTVDZm9vJTVDJTVDYmFyJTVDJTVDJTVDYmF6P2dlbmVyYXRpb249MTU0OTY3MTAwNjQyNzYyMyZhbHQ9bWVkaWEiLCJuYW1lIjoibGlzdC13ZWlyZGtleXMtLi5cXGZvb1xcXFxiYXJcXFxcXFxiYXoiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NzEwMDY0Mjc2MjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPZXo3YTZ1cmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNDI3WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjQyN1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNDI3WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjQyN1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9saXN0LXdlaXJka2V5cy0uLl9fMHgyZl9fZm9vLy4uX18weDJmX19iYXIvLi5fXzB4MmZfXy4uX18weDJmX19iYXouLl9fMHgyZl9fLzE1NDk2NzEwMDcwOTQzNjgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbGlzdC13ZWlyZGtleXMtLi5fXzB4MmZfX2ZvbyUyRi4uX18weDJmX19iYXIlMkYuLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18iLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy0uLl9fMHgyZl9fZm9vJTJGLi5fXzB4MmZfX2JhciUyRi4uX18weDJmX18uLl9fMHgyZl9fYmF6Li5fXzB4MmZfXz9nZW5lcmF0aW9uPTE1NDk2NzEwMDcwOTQzNjgmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLS4uX18weDJmX19mb28vLi5fXzB4MmZfX2Jhci8uLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18iLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NzEwMDcwOTQzNjgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPQ01scSt1cmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMDkzWiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjA5M1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMDkzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjA5M1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9saXN0LXdlaXJka2V5cy0xMjM0NS8xNTQ5NjcxMDA3MzEyNjgxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLTEyMzQ1IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbGlzdC13ZWlyZGtleXMtMTIzNDU/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA3MzEyNjgxJmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy0xMjM0NSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNzMxMjY4MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0ttMm82K3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4zMTJaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMzEyWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4zMTJaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMzEyWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLTo7XHUwMDNjPVx1MDAzZT8vMTU0OTY3MTAwODA2NjMxNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy06OyUzQz0lM0UlM0YiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy06OyUzQz0lM0UlM0Y/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA4MDY2MzE3JmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy06O1x1MDAzYz1cdTAwM2U/IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA4MDY2MzE3IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSTIyMGErdXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA4LjA2NVoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowOC4wNjVaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA4LjA2NVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowOC4wNjVaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMtQC8xNTQ5NjcxMDA3NTAyMTQxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLUAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy1AP2dlbmVyYXRpb249MTU0OTY3MTAwNzUwMjE0MSZhbHQ9bWVkaWEiLCJuYW1lIjoibGlzdC13ZWlyZGtleXMtQCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNzUwMjE0MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0wzK3JxK3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy41MDFaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuNTAxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy41MDFaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuNTAxWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLVtcXF1eXy8xNTQ5NjcxMDA2MTEzMzA0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSU1QiU1QyU1RCU1RV8iLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy0lNUIlNUMlNUQlNUVfP2dlbmVyYXRpb249MTU0OTY3MTAwNjExMzMwNCZhbHQ9bWVkaWEiLCJuYW1lIjoibGlzdC13ZWlyZGtleXMtW1xcXV5fIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA2MTEzMzA0IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSmljMnE2dXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjExMloiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi4xMTJaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjExMloiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi4xMTJaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMtYC8xNTQ5NjcxMDA4MTYzMTY1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSU2MCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSU2MD9nZW5lcmF0aW9uPTE1NDk2NzEwMDgxNjMxNjUmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLWAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NzEwMDgxNjMxNjUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOMnExNit1cmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDguMTYyWiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA4LjE2MloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDguMTYyWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA4LjE2MloifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9saXN0LXdlaXJka2V5cy1mb28gYmFyIGJhei8xNTQ5NjcxMDA3MjAzNjAwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyMGJhciUyMGJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyMGJhciUyMGJhej9nZW5lcmF0aW9uPTE1NDk2NzEwMDcyMDM2MDAmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLWZvbyBiYXIgYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA3MjAzNjAwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSkRpbksrdXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjIwM1oiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4yMDNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjIwM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4yMDNaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMtZm9vXCJiYXJcImJhei8xNTQ5NjcxMDA2NTUyMjg4Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyMmJhciUyMmJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyMmJhciUyMmJhej9nZW5lcmF0aW9uPTE1NDk2NzEwMDY1NTIyODgmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLWZvb1wiYmFyXCJiYXoiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NzEwMDY1NTIyODgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPQ0I5YTZ1cmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNTUxWiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjU1MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNTUxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjU1MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9saXN0LXdlaXJka2V5cy1mb28vL2Jhci8vL2Jhei8xNTQ5NjcxMDA3NjMzMTg2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyRiUyRmJhciUyRiUyRiUyRmJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyRiUyRmJhciUyRiUyRiUyRmJhej9nZW5lcmF0aW9uPTE1NDk2NzEwMDc2MzMxODYmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLWZvby8vYmFyLy8vYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA3NjMzMTg2IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS0wrdHErdXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjYzMloiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy42MzJaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjYzMloiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy42MzJaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMtZm9vL2Jhci9iYXovMTU0OTY3MTAwNTk5MjY3MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy1mb28lMkZiYXIlMkZiYXoiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy1mb28lMkZiYXIlMkZiYXo/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA1OTkyNjcxJmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy1mb28vYmFyL2JheiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNTk5MjY3MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ04vdDBxNnVyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNS45OTJaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDUuOTkyWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNS45OTJaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDUuOTkyWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLWZvb1xcYmFyXFxiYXovMTU0OTY3MTAwNjMyMjM2MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy1mb28lNUNiYXIlNUNiYXoiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy1mb28lNUNiYXIlNUNiYXo/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA2MzIyMzYxJmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy1mb29cXGJhclxcYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA2MzIyMzYxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTG45NXE2dXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjMyMVoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi4zMjFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjMyMVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi4zMjFaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMte3x9flx1MDA3Zi8xNTQ5NjcxMDA2ODc3MTE3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSU3QiU3QyU3RH4lN0YiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy0lN0IlN0MlN0R+JTdGP2dlbmVyYXRpb249MTU0OTY3MTAwNjg3NzExNyZhbHQ9bWVkaWEiLCJuYW1lIjoibGlzdC13ZWlyZGtleXMte3x9flx1MDA3ZiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNjg3NzExNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0wzcmlLK3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi44NzZaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuODc2WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi44NzZaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuODc2WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLeKYuuKYuuKYui8xNTQ5NjcxMDA2NjY3NzE2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSVFMiU5OCVCQSVFMiU5OCVCQSVFMiU5OCVCQSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSVFMiU5OCVCQSVFMiU5OCVCQSVFMiU5OCVCQT9nZW5lcmF0aW9uPTE1NDk2NzEwMDY2Njc3MTYmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLeKYuuKYuuKYuiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNjY2NzcxNiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ01TSC9LNnVyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi42NjdaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNjY3WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi42NjdaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNjY3WiJ9XX0=" + } + }, + { + "ID": "396ee24152aaa69a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=list-weirdkeys-\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "15938" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:27 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88o0SW2ZVI6Td3gMB8ksdYkF--hDXlM3KLbPVesSTnp_4fi8xMTUEL_j7SeQx_DHoA" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9saXN0LXdlaXJka2V5cy1cdTAwMDBcdTAwMDFcdTAwMDJcdTAwMDNcdTAwMDRcdTAwMDVcdTAwMDZcdTAwMDdcYlx0X18weGFfX1x1MDAwYlxmX18weGRfX1x1MDAwZVx1MDAwZi8xNTQ5NjcxMDA2NzcxOTI1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSUwMCUwMSUwMiUwMyUwNCUwNSUwNiUwNyUwOCUwOV9fMHhhX18lMEIlMENfXzB4ZF9fJTBFJTBGIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbGlzdC13ZWlyZGtleXMtJTAwJTAxJTAyJTAzJTA0JTA1JTA2JTA3JTA4JTA5X18weGFfXyUwQiUwQ19fMHhkX18lMEUlMEY/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA2NzcxOTI1JmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy1cdTAwMDBcdTAwMDFcdTAwMDJcdTAwMDNcdTAwMDRcdTAwMDVcdTAwMDZcdTAwMDdcYlx0X18weGFfX1x1MDAwYlxmX18weGRfX1x1MDAwZVx1MDAwZiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNjc3MTkyNSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ05XMWdxK3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi43NzFaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNzcxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi43NzFaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNzcxWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLVx1MDAxMFx1MDAxMVx1MDAxMlx1MDAxM1x1MDAxNFx1MDAxNVx1MDAxNlx1MDAxN1x1MDAxOFx1MDAxOVx1MDAxYVx1MDAxYlx1MDAxY1x1MDAxZFx1MDAxZVx1MDAxZi8xNTQ5NjcxMDA3OTQ1NTExIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSUxMCUxMSUxMiUxMyUxNCUxNSUxNiUxNyUxOCUxOSUxQSUxQiUxQyUxRCUxRSUxRiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSUxMCUxMSUxMiUxMyUxNCUxNSUxNiUxNyUxOCUxOSUxQSUxQiUxQyUxRCUxRSUxRj9nZW5lcmF0aW9uPTE1NDk2NzEwMDc5NDU1MTEmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLVx1MDAxMFx1MDAxMVx1MDAxMlx1MDAxM1x1MDAxNFx1MDAxNVx1MDAxNlx1MDAxN1x1MDAxOFx1MDAxOVx1MDAxYVx1MDAxYlx1MDAxY1x1MDAxZFx1MDAxZVx1MDAxZiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNzk0NTUxMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0tlR3lxK3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy45NDVaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuOTQ1WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy45NDVaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuOTQ1WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLSAhXCIjJCUmJygpKissLS4vLzE1NDk2NzEwMDczOTIxMTYiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbGlzdC13ZWlyZGtleXMtJTIwISUyMiUyMyQlMjUmJygpKiUyQiwtLiUyRiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSUyMCElMjIlMjMkJTI1JicoKSolMkIsLS4lMkY/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA3MzkyMTE2JmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy0gIVwiIyQlJicoKSorLC0uLyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNzM5MjExNiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1BTaXFLK3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4zOTFaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMzkxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4zOTFaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMzkxWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLS4uXFxmb29cXC4uXFxiYXJcXC4uXFwuLlxcYmF6Li5cXC8xNTQ5NjcxMDA3NzQwMjI0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLS4uJTVDZm9vJTVDLi4lNUNiYXIlNUMuLiU1Qy4uJTVDYmF6Li4lNUMiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy0uLiU1Q2ZvbyU1Qy4uJTVDYmFyJTVDLi4lNUMuLiU1Q2Jhei4uJTVDP2dlbmVyYXRpb249MTU0OTY3MTAwNzc0MDIyNCZhbHQ9bWVkaWEiLCJuYW1lIjoibGlzdC13ZWlyZGtleXMtLi5cXGZvb1xcLi5cXGJhclxcLi5cXC4uXFxiYXouLlxcIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA3NzQwMjI0IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTURDdmErdXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjczOVoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy43MzlaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjczOVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy43MzlaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMtLi5cXGZvb1xcXFxiYXJcXFxcXFxiYXovMTU0OTY3MTAwNjQyNzYyMyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy0uLiU1Q2ZvbyU1QyU1Q2JhciU1QyU1QyU1Q2JheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLS4uJTVDZm9vJTVDJTVDYmFyJTVDJTVDJTVDYmF6P2dlbmVyYXRpb249MTU0OTY3MTAwNjQyNzYyMyZhbHQ9bWVkaWEiLCJuYW1lIjoibGlzdC13ZWlyZGtleXMtLi5cXGZvb1xcXFxiYXJcXFxcXFxiYXoiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NzEwMDY0Mjc2MjMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPZXo3YTZ1cmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNDI3WiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjQyN1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNDI3WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjQyN1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9saXN0LXdlaXJka2V5cy0uLl9fMHgyZl9fZm9vLy4uX18weDJmX19iYXIvLi5fXzB4MmZfXy4uX18weDJmX19iYXouLl9fMHgyZl9fLzE1NDk2NzEwMDcwOTQzNjgiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbGlzdC13ZWlyZGtleXMtLi5fXzB4MmZfX2ZvbyUyRi4uX18weDJmX19iYXIlMkYuLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18iLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy0uLl9fMHgyZl9fZm9vJTJGLi5fXzB4MmZfX2JhciUyRi4uX18weDJmX18uLl9fMHgyZl9fYmF6Li5fXzB4MmZfXz9nZW5lcmF0aW9uPTE1NDk2NzEwMDcwOTQzNjgmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLS4uX18weDJmX19mb28vLi5fXzB4MmZfX2Jhci8uLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX18iLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NzEwMDcwOTQzNjgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPQ01scSt1cmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMDkzWiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjA5M1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMDkzWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjA5M1oifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9saXN0LXdlaXJka2V5cy0xMjM0NS8xNTQ5NjcxMDA3MzEyNjgxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLTEyMzQ1IiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vbGlzdC13ZWlyZGtleXMtMTIzNDU/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA3MzEyNjgxJmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy0xMjM0NSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNzMxMjY4MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0ttMm82K3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4zMTJaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMzEyWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4zMTJaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuMzEyWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLTo7XHUwMDNjPVx1MDAzZT8vMTU0OTY3MTAwODA2NjMxNyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy06OyUzQz0lM0UlM0YiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy06OyUzQz0lM0UlM0Y/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA4MDY2MzE3JmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy06O1x1MDAzYz1cdTAwM2U/IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA4MDY2MzE3IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSTIyMGErdXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA4LjA2NVoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowOC4wNjVaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA4LjA2NVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowOC4wNjVaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMtQC8xNTQ5NjcxMDA3NTAyMTQxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLUAiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy1AP2dlbmVyYXRpb249MTU0OTY3MTAwNzUwMjE0MSZhbHQ9bWVkaWEiLCJuYW1lIjoibGlzdC13ZWlyZGtleXMtQCIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNzUwMjE0MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0wzK3JxK3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy41MDFaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuNTAxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy41MDFaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDcuNTAxWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLVtcXF1eXy8xNTQ5NjcxMDA2MTEzMzA0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSU1QiU1QyU1RCU1RV8iLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy0lNUIlNUMlNUQlNUVfP2dlbmVyYXRpb249MTU0OTY3MTAwNjExMzMwNCZhbHQ9bWVkaWEiLCJuYW1lIjoibGlzdC13ZWlyZGtleXMtW1xcXV5fIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA2MTEzMzA0IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSmljMnE2dXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjExMloiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi4xMTJaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjExMloiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi4xMTJaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMtYC8xNTQ5NjcxMDA4MTYzMTY1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSU2MCIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSU2MD9nZW5lcmF0aW9uPTE1NDk2NzEwMDgxNjMxNjUmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLWAiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NzEwMDgxNjMxNjUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNOMnExNit1cmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDguMTYyWiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA4LjE2MloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDguMTYyWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA4LjE2MloifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9saXN0LXdlaXJka2V5cy1mb28gYmFyIGJhei8xNTQ5NjcxMDA3MjAzNjAwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyMGJhciUyMGJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyMGJhciUyMGJhej9nZW5lcmF0aW9uPTE1NDk2NzEwMDcyMDM2MDAmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLWZvbyBiYXIgYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA3MjAzNjAwIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDSkRpbksrdXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjIwM1oiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4yMDNaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjIwM1oiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy4yMDNaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMtZm9vXCJiYXJcImJhei8xNTQ5NjcxMDA2NTUyMjg4Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyMmJhciUyMmJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyMmJhciUyMmJhej9nZW5lcmF0aW9uPTE1NDk2NzEwMDY1NTIyODgmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLWZvb1wiYmFyXCJiYXoiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE1NDk2NzEwMDY1NTIyODgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNPQ0I5YTZ1cmVBQ0VBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNTUxWiIsInVwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjU1MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNTUxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjU1MVoifSx7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9saXN0LXdlaXJka2V5cy1mb28vL2Jhci8vL2Jhei8xNTQ5NjcxMDA3NjMzMTg2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyRiUyRmJhciUyRiUyRiUyRmJheiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLWZvbyUyRiUyRmJhciUyRiUyRiUyRmJhej9nZW5lcmF0aW9uPTE1NDk2NzEwMDc2MzMxODYmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLWZvby8vYmFyLy8vYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA3NjMzMTg2IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDS0wrdHErdXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjYzMloiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy42MzJaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA3LjYzMloiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNy42MzJaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMtZm9vL2Jhci9iYXovMTU0OTY3MTAwNTk5MjY3MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy1mb28lMkZiYXIlMkZiYXoiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy1mb28lMkZiYXIlMkZiYXo/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA1OTkyNjcxJmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy1mb28vYmFyL2JheiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNTk5MjY3MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ04vdDBxNnVyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNS45OTJaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDUuOTkyWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNS45OTJaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDUuOTkyWiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLWZvb1xcYmFyXFxiYXovMTU0OTY3MTAwNjMyMjM2MSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy1mb28lNUNiYXIlNUNiYXoiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy1mb28lNUNiYXIlNUNiYXo/Z2VuZXJhdGlvbj0xNTQ5NjcxMDA2MzIyMzYxJmFsdD1tZWRpYSIsIm5hbWUiOiJsaXN0LXdlaXJka2V5cy1mb29cXGJhclxcYmF6IiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNTQ5NjcxMDA2MzIyMzYxIiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDTG45NXE2dXJlQUNFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjMyMVoiLCJ1cGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi4zMjFaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDE5LTAyLTA5VDAwOjEwOjA2LjMyMVoiLCJ0aW1lRmluYWxpemVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi4zMjFaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvbGlzdC13ZWlyZGtleXMte3x9flx1MDA3Zi8xNTQ5NjcxMDA2ODc3MTE3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSU3QiU3QyU3RH4lN0YiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9saXN0LXdlaXJka2V5cy0lN0IlN0MlN0R+JTdGP2dlbmVyYXRpb249MTU0OTY3MTAwNjg3NzExNyZhbHQ9bWVkaWEiLCJuYW1lIjoibGlzdC13ZWlyZGtleXMte3x9flx1MDA3ZiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNjg3NzExNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ0wzcmlLK3VyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi44NzZaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuODc2WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi44NzZaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuODc2WiJ9LHsia2luZCI6InN0b3JhZ2Ujb2JqZWN0IiwiaWQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2xpc3Qtd2VpcmRrZXlzLeKYuuKYuuKYui8xNTQ5NjcxMDA2NjY3NzE2Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSVFMiU5OCVCQSVFMiU5OCVCQSVFMiU5OCVCQSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2xpc3Qtd2VpcmRrZXlzLSVFMiU5OCVCQSVFMiU5OCVCQSVFMiU5OCVCQT9nZW5lcmF0aW9uPTE1NDk2NzEwMDY2Njc3MTYmYWx0PW1lZGlhIiwibmFtZSI6Imxpc3Qtd2VpcmRrZXlzLeKYuuKYuuKYuiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTU0OTY3MTAwNjY2NzcxNiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ01TSC9LNnVyZUFDRUFFPSIsInRpbWVDcmVhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi42NjdaIiwidXBkYXRlZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNjY3WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAxOS0wMi0wOVQwMDoxMDowNi42NjdaIiwidGltZUZpbmFsaXplZCI6IjIwMTktMDItMDlUMDA6MTA6MDYuNjY3WiJ9XX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestMD5.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMD5.replay new file mode 100644 index 000000000..aea81b950 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMD5.replay @@ -0,0 +1,452 @@ +{ + "Initial": "AQAAAA7gDLy8EPMaLAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "a154dfc691a7493d", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-md5-aaa\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJibG9iLWZvci1tZDUtYWFhIn0K", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "792" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:56 GMT" + ], + "Etag": [ + "CPDU6N21x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88yci1K_hRQUaqK1-Nrs6JWUsiNZQH9X59Qh2-z8nRGizpArS9jKB74ekrsxeFQRPg" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWQ1LWFhYS8xNzUyODc2NDc2NjcyNjI0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1kNS1hYWEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZDUtYWFhP2dlbmVyYXRpb249MTc1Mjg3NjQ3NjY3MjYyNCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWQ1LWFhYSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3NjY3MjYyNCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1BEVTZOMjF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni42NzRaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuNjc0WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni42NzRaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuNjc0WiJ9" + } + }, + { + "ID": "4ac6d22b7cbb4e9c", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-md5-bbb\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6ImFmcXJZbWcxQXBWVkRlZlZoN3d5UFE9PSIsIm5hbWUiOiJibG9iLWZvci1tZDUtYmJiIn0K", + "Z29vZGJ5ZQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "792" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:56 GMT" + ], + "Etag": [ + "CMW98d21x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88vd-jP8gPuQglTvty3XhB2fNxKJEleUgUD5JKhLPx_aU3QS4IAHpxDj1N7k7PtKDs" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWQ1LWJiYi8xNzUyODc2NDc2ODE3MDkzIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1kNS1iYmIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZDUtYmJiP2dlbmVyYXRpb249MTc1Mjg3NjQ3NjgxNzA5MyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWQ1LWJiYiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3NjgxNzA5MyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjciLCJtZDVIYXNoIjoiYWZxclltZzFBcFZWRGVmVmg3d3lQUT09IiwiY3JjMzJjIjoieGxkMnNnPT0iLCJldGFnIjoiQ01XOThkMjF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni44MTlaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuODE5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni44MTlaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuODE5WiJ9" + } + }, + { + "ID": "7d0da1691b37b572", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-md5-aaa?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "792" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:57 GMT" + ], + "Etag": [ + "CPDU6N21x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-7sPnIg87eN1rQNdAg1I2as5C_qOxc3Ai6jx4gA3muiTxZsvBximoo5uyzXjyJiZ0" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWQ1LWFhYS8xNzUyODc2NDc2NjcyNjI0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1kNS1hYWEiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZDUtYWFhP2dlbmVyYXRpb249MTc1Mjg3NjQ3NjY3MjYyNCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWQ1LWFhYSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3NjY3MjYyNCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjUiLCJtZDVIYXNoIjoiWFVGQUtyeExLbmE1Y1oyUkVCZkZrZz09IiwiY3JjMzJjIjoibW5HN1RBPT0iLCJldGFnIjoiQ1BEVTZOMjF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni42NzRaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuNjc0WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni42NzRaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuNjc0WiJ9" + } + }, + { + "ID": "2cbe510102ea89af", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-md5-bbb?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "792" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:57 GMT" + ], + "Etag": [ + "CMW98d21x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_qxyPBx8Z0E8wxofmZryhkfgPw0XxTpjir55bMQAWqydPh9Oe1ZVyEJGJlLEJBaDQ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWQ1LWJiYi8xNzUyODc2NDc2ODE3MDkzIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1kNS1iYmIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZDUtYmJiP2dlbmVyYXRpb249MTc1Mjg3NjQ3NjgxNzA5MyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWQ1LWJiYiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3NjgxNzA5MyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjciLCJtZDVIYXNoIjoiYWZxclltZzFBcFZWRGVmVmg3d3lQUT09IiwiY3JjMzJjIjoieGxkMnNnPT0iLCJldGFnIjoiQ01XOThkMjF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni44MTlaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuODE5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni44MTlaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuODE5WiJ9" + } + }, + { + "ID": "6d11358a5986a011", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1000\u0026pageToken=\u0026prefix=blob-for-md5-\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1622" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:57 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89RvM_bZHoqdae_npjNBYiBQ2zXXHoiTifmC0Pm6Cp_iofkhxN_sLxZgsU4EalNW-xs" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1tZDUtYWFhLzE3NTI4NzY0NzY2NzI2MjQiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItbWQ1LWFhYSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1kNS1hYWE/Z2VuZXJhdGlvbj0xNzUyODc2NDc2NjcyNjI0JmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1tZDUtYWFhIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDc2NjcyNjI0IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNSIsIm1kNUhhc2giOiJYVUZBS3J4TEtuYTVjWjJSRUJmRmtnPT0iLCJjcmMzMmMiOiJtbkc3VEE9PSIsImV0YWciOiJDUERVNk4yMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU2LjY3NFoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni42NzRaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU2LjY3NFoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni42NzRaIn0seyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWQ1LWJiYi8xNzUyODc2NDc2ODE3MDkzIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1kNS1iYmIiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZDUtYmJiP2dlbmVyYXRpb249MTc1Mjg3NjQ3NjgxNzA5MyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWQ1LWJiYiIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ3NjgxNzA5MyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjciLCJtZDVIYXNoIjoiYWZxclltZzFBcFZWRGVmVmg3d3lQUT09IiwiY3JjMzJjIjoieGxkMnNnPT0iLCJldGFnIjoiQ01XOThkMjF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni44MTlaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuODE5WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Ni44MTlaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuODE5WiJ9XX0=" + } + }, + { + "ID": "2c91eacd374f9215", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-md5-bbb?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:57 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-5SNEOi9NW5UQCoKoTvJl153yElOY9msl_hLJByeKo_wwYQJF8JhMCpIpKdD5-_Ow-" + ] + }, + "Body": "" + } + }, + { + "ID": "a98df87f95dd84c6", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-md5-aaa?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:57 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88_9eBsoVzqY-6u_Vq3yl7Y7dZ0fvEaDXpgVziI3AmXC8AA17OBBy0slb9hisb1W41s" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/duplicate_case-insensitive_key_fails.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/duplicate_case-insensitive_key_fails.replay new file mode 100644 index 000000000..3b9d0795b --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/duplicate_case-insensitive_key_fails.replay @@ -0,0 +1,39 @@ +{ + "Initial": "AQAAAA7gDLy6BRW5MQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/empty.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/empty.replay new file mode 100644 index 000000000..301cd376a --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/empty.replay @@ -0,0 +1,218 @@ +{ + "Initial": "AQAAAA7gDLy5HqDILAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "58016486af15e18f", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-metadata\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm5hbWUiOiJibG9iLWZvci1tZXRhZGF0YSJ9Cg==", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "796" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:53 GMT" + ], + "Etag": [ + "CJfRuty1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Dzb0bLO5-6T6UvEw4DGhWf0nvDoUm-mpV2YDkwVEYmpRBgjZ0OVosnbGMkeVfxXY" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWV0YWRhdGEvMTc1Mjg3NjQ3MzgyMTMzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZXRhZGF0YSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1ldGFkYXRhP2dlbmVyYXRpb249MTc1Mjg3NjQ3MzgyMTMzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzM4MjEzMzUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKZlJ1dHkxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTMuODI0WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUzLjgyNFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTMuODI0WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUzLjgyNFoifQ==" + } + }, + { + "ID": "78a0c7a06c29dbbd", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-metadata?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "796" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:54 GMT" + ], + "Etag": [ + "CJfRuty1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_gKbx7O0QgTBMwE2jIHM9h7kcHanZi6GVFgga8dpPOWP8LoB5YSW0naEhCevgjhWOJ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWV0YWRhdGEvMTc1Mjg3NjQ3MzgyMTMzNSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZXRhZGF0YSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1ldGFkYXRhP2dlbmVyYXRpb249MTc1Mjg3NjQ3MzgyMTMzNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzM4MjEzMzUiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKZlJ1dHkxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTMuODI0WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUzLjgyNFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTMuODI0WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjUzLjgyNFoifQ==" + } + }, + { + "ID": "0fd8e6c99d7f11a7", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-metadata?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:54 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-FZxIt2WBpLvXsluTOc6iSnA2VaGAkfvyl_EoA3oUO7fUPw6zn0owqPKQl9wLQh_Y" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/empty_key_fails.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/empty_key_fails.replay new file mode 100644 index 000000000..6752165f1 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/empty_key_fails.replay @@ -0,0 +1,39 @@ +{ + "Initial": "AQAAAA7gDLy6BQMlkQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_key.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_key.replay new file mode 100644 index 000000000..eb7b8519b --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_key.replay @@ -0,0 +1,39 @@ +{ + "Initial": "AQAAAA7gDLy8ENXtMQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_value.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_value.replay new file mode 100644 index 000000000..570fad26b --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/non-utf8_metadata_value.replay @@ -0,0 +1,39 @@ +{ + "Initial": "AQAAAA7gDLy8EOVKRwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata.replay new file mode 100644 index 000000000..3cb1ca3c0 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata.replay @@ -0,0 +1,218 @@ +{ + "Initial": "AQAAAA7gDLy6BSRW/AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "d2da2ababa33ce05", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-metadata\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm1ldGFkYXRhIjp7ImtleV9hIjoidmFsdWUtYSIsImtleV9iIjoidmFsdWUtYiIsImtleV9jIjoidkFsVWUtYyJ9LCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "863" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:54 GMT" + ], + "Etag": [ + "CIvd3ty1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Iubn2N6uiEapuYi-Hoj0SkW83aqCJ1l07Zj2VuPIquLgxICMkUNY1hCCRpOri3xWT" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWV0YWRhdGEvMTc1Mjg3NjQ3NDQxMjY4MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZXRhZGF0YSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1ldGFkYXRhP2dlbmVyYXRpb249MTc1Mjg3NjQ3NDQxMjY4MyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzQ0MTI2ODMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNJdmQzdHkxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTQuNDE2WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU0LjQxNloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTQuNDE2WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU0LjQxNloiLCJtZXRhZGF0YSI6eyJrZXlfYSI6InZhbHVlLWEiLCJrZXlfYiI6InZhbHVlLWIiLCJrZXlfYyI6InZBbFVlLWMifX0=" + } + }, + { + "ID": "7c7d8fb58f819894", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-metadata?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "863" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:54 GMT" + ], + "Etag": [ + "CIvd3ty1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-YOGP-6MrNNoPDIXjnsqxZ0ZGHqNWqx7euqLygZel7oOMkGkHUsHPfXWUOp408rMg" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWV0YWRhdGEvMTc1Mjg3NjQ3NDQxMjY4MyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZXRhZGF0YSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1ldGFkYXRhP2dlbmVyYXRpb249MTc1Mjg3NjQ3NDQxMjY4MyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzQ0MTI2ODMiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNJdmQzdHkxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTQuNDE2WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU0LjQxNloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTQuNDE2WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU0LjQxNloiLCJtZXRhZGF0YSI6eyJrZXlfYSI6InZhbHVlLWEiLCJrZXlfYiI6InZhbHVlLWIiLCJrZXlfYyI6InZBbFVlLWMifX0=" + } + }, + { + "ID": "6886b171a057d9a4", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-metadata?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:54 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89jQKdgxv-S0zjEpx6WiWJ79-ljXeEF5QOOfPKsUyfwX76na4-pbo5b-RueBV7OQfc" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata_with_content_type.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata_with_content_type.replay new file mode 100644 index 000000000..140282c78 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata_with_content_type.replay @@ -0,0 +1,218 @@ +{ + "Initial": "AQAAAA7gDLy7EL/PogAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "0286a300a8408988", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-metadata\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluIiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm1ldGFkYXRhIjp7ImZvbyI6ImJhciJ9LCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "806" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:55 GMT" + ], + "Etag": [ + "CKXpp921x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89nqF9A_0XgMcPI-I4N9s9G4UzAsiXzyeJLPtunkaP4EBMAb8fyf9GN7Yah1XmJTo6K" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWV0YWRhdGEvMTc1Mjg3NjQ3NTYxMDI3NyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZXRhZGF0YSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1ldGFkYXRhP2dlbmVyYXRpb249MTc1Mjg3NjQ3NTYxMDI3NyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzU2MTAyNzciLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLWHBwOTIxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTUuNjEyWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU1LjYxMloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTUuNjEyWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU1LjYxMloiLCJtZXRhZGF0YSI6eyJmb28iOiJiYXIifX0=" + } + }, + { + "ID": "92a7da50c3f96de4", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-metadata?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "806" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:55 GMT" + ], + "Etag": [ + "CKXpp921x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88FlO-NLgyx9uLIqw-nupr7XJXL52N8V2y_AuBypGz9ojMn6DyR0Jp_jz67W-kPRLQ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWV0YWRhdGEvMTc1Mjg3NjQ3NTYxMDI3NyIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZXRhZGF0YSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1ldGFkYXRhP2dlbmVyYXRpb249MTc1Mjg3NjQ3NTYxMDI3NyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzU2MTAyNzciLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLWHBwOTIxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTUuNjEyWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU1LjYxMloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTUuNjEyWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU1LjYxMloiLCJtZXRhZGF0YSI6eyJmb28iOiJiYXIifX0=" + } + }, + { + "ID": "19564be5444623c7", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-metadata?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:55 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH881WJa9ML1yCCoPaoH8X9xoDcu_cy1GJveY5oG7xxSYv0i8IKX45ex-9AVciJHzRtXr" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata_with_empty_body.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata_with_empty_body.replay new file mode 100644 index 000000000..e7d1800d3 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/valid_metadata_with_empty_body.replay @@ -0,0 +1,218 @@ +{ + "Initial": "AQAAAA7gDLy6KkLC6QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "04c0653ad7316893", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-metadata\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm1ldGFkYXRhIjp7ImZvbyI6ImJhciJ9LCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "821" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:54 GMT" + ], + "Etag": [ + "CJqSgt21x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89NsdcQlF3m29SyXQpLH2W3Fsu9LZUS2ZmBJ0rozh7nsQzdky9QvxPYnS4UIDMcEjQ" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWV0YWRhdGEvMTc1Mjg3NjQ3NDk5MjkyMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZXRhZGF0YSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1ldGFkYXRhP2dlbmVyYXRpb249MTc1Mjg3NjQ3NDk5MjkyMiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzQ5OTI5MjIiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKcVNndDIxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTQuOTk1WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU0Ljk5NVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTQuOTk1WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU0Ljk5NVoiLCJtZXRhZGF0YSI6eyJmb28iOiJiYXIifX0=" + } + }, + { + "ID": "15e6897afd35dab1", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-metadata?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "821" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:55 GMT" + ], + "Etag": [ + "CJqSgt21x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Te_7ZfwVJVsQh7Fca9rCiMAT2abSQiLtcjeVQRM3x5QMlh7Z0Yhk3PfT0Qzsep_Q" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWV0YWRhdGEvMTc1Mjg3NjQ3NDk5MjkyMiIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZXRhZGF0YSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1ldGFkYXRhP2dlbmVyYXRpb249MTc1Mjg3NjQ3NDk5MjkyMiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzQ5OTI5MjIiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNKcVNndDIxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTQuOTk1WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU0Ljk5NVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTQuOTk1WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU0Ljk5NVoiLCJtZXRhZGF0YSI6eyJmb28iOiJiYXIifX0=" + } + }, + { + "ID": "03db67d01ed2bb8b", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-metadata?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:55 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Nd5Kiuons5xeCXzk5onCr0aw_Xm5mWqiRxpKM9qDp3CHk2NxS2l2Qou_rFzcPU5g" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/weird_metadata_keys.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/weird_metadata_keys.replay new file mode 100644 index 000000000..ea812aa8d --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestMetadata/weird_metadata_keys.replay @@ -0,0 +1,218 @@ +{ + "Initial": "AQAAAA7gDLy7LHwIPQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "8839301a875081f3", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-metadata\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsIm1ldGFkYXRhIjp7Ilx1MDAwMFx1MDAwMVx1MDAwMlx1MDAwM1x1MDAwNFx1MDAwNVx1MDAwNlx1MDAwN1xiXHRcblx1MDAwYlxmXHJcdTAwMGVcdTAwMGYiOiJcdTAwMDBcdTAwMDFcdTAwMDJcdTAwMDNcdTAwMDRcdTAwMDVcdTAwMDZcdTAwMDdcYlx0XG5cdTAwMGJcZlxyXHUwMDBlXHUwMDBmIiwiXHUwMDEwXHUwMDExXHUwMDEyXHUwMDEzXHUwMDE0XHUwMDE1XHUwMDE2XHUwMDE3XHUwMDE4XHUwMDE5XHUwMDFhXHUwMDFiXHUwMDFjXHUwMDFkXHUwMDFlXHUwMDFmIjoiXHUwMDEwXHUwMDExXHUwMDEyXHUwMDEzXHUwMDE0XHUwMDE1XHUwMDE2XHUwMDE3XHUwMDE4XHUwMDE5XHUwMDFhXHUwMDFiXHUwMDFjXHUwMDFkXHUwMDFlXHUwMDFmIiwiICFcIiMkJVx1MDAyNicoKSorLC0uLyI6IiAhXCIjJCVcdTAwMjYnKCkqKywtLi8iLCIuLi9mb28vLi4vYmFyLy4uLy4uL2Jhei4uLyI6Ii4uL2Zvby8uLi9iYXIvLi4vLi4vYmF6Li4vIiwiLi5cXGZvb1xcLi5cXGJhclxcLi5cXC4uXFxiYXouLlxcIjoiLi5cXGZvb1xcLi5cXGJhclxcLi5cXC4uXFxiYXouLlxcIiwiLi5cXGZvb1xcXFxiYXJcXFxcXFxiYXoiOiIuLlxcZm9vXFxcXGJhclxcXFxcXGJheiIsIjEyMzQ1IjoiMTIzNDUiLCI6O1x1MDAzYz1cdTAwM2U/IjoiOjtcdTAwM2M9XHUwMDNlPyIsIkAiOiJAIiwiW1xcXV5fIjoiW1xcXV5fIiwiYCI6ImAiLCJmb28gYmFyIGJheiI6ImZvbyBiYXIgYmF6IiwiZm9vXCJiYXJcImJheiI6ImZvb1wiYmFyXCJiYXoiLCJmb28vL2Jhci8vL2JheiI6ImZvby8vYmFyLy8vYmF6IiwiZm9vL2Jhci9iYXoiOiJmb28vYmFyL2JheiIsImZvb1xcYmFyXFxiYXoiOiJmb29cXGJhclxcYmF6Iiwie3x9fn8iOiJ7fH1+fyIsIuKYuuKYuuKYuiI6IuKYuuKYuuKYuiJ9LCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEifQo=", + "aGVsbG8=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "1679" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:56 GMT" + ], + "Etag": [ + "CK2owd21x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-L-sQoh1h0ZruNG11PIwtMiCglMx7NE0LGjQI_AXMLX1UML72G7EL36WE42yG2BwM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWV0YWRhdGEvMTc1Mjg3NjQ3NjAyNzk0OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZXRhZGF0YSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1ldGFkYXRhP2dlbmVyYXRpb249MTc1Mjg3NjQ3NjAyNzk0OSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzYwMjc5NDkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLMm93ZDIxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuMDI5WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU2LjAyOVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuMDI5WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU2LjAyOVoiLCJtZXRhZGF0YSI6eyJmb28vL2Jhci8vL2JheiI6ImZvby8vYmFyLy8vYmF6IiwiLi5cXGZvb1xcXFxiYXJcXFxcXFxiYXoiOiIuLlxcZm9vXFxcXGJhclxcXFxcXGJheiIsIlx1MDAwMFx1MDAwMVx1MDAwMlx1MDAwM1x1MDAwNFx1MDAwNVx1MDAwNlx1MDAwN1xiXHRcblx1MDAwYlxmXHJcdTAwMGVcdTAwMGYiOiJcdTAwMDBcdTAwMDFcdTAwMDJcdTAwMDNcdTAwMDRcdTAwMDVcdTAwMDZcdTAwMDdcYlx0XG5cdTAwMGJcZlxyXHUwMDBlXHUwMDBmIiwiICFcIiMkJSYnKCkqKywtLi8iOiIgIVwiIyQlJicoKSorLC0uLyIsImZvb1xcYmFyXFxiYXoiOiJmb29cXGJhclxcYmF6IiwiMTIzNDUiOiIxMjM0NSIsIkAiOiJAIiwiZm9vXCJiYXJcImJheiI6ImZvb1wiYmFyXCJiYXoiLCJbXFxdXl8iOiJbXFxdXl8iLCLimLrimLrimLoiOiLimLrimLrimLoiLCJcdTAwMTBcdTAwMTFcdTAwMTJcdTAwMTNcdTAwMTRcdTAwMTVcdTAwMTZcdTAwMTdcdTAwMThcdTAwMTlcdTAwMWFcdTAwMWJcdTAwMWNcdTAwMWRcdTAwMWVcdTAwMWYiOiJcdTAwMTBcdTAwMTFcdTAwMTJcdTAwMTNcdTAwMTRcdTAwMTVcdTAwMTZcdTAwMTdcdTAwMThcdTAwMTlcdTAwMWFcdTAwMWJcdTAwMWNcdTAwMWRcdTAwMWVcdTAwMWYiLCIuLlxcZm9vXFwuLlxcYmFyXFwuLlxcLi5cXGJhei4uXFwiOiIuLlxcZm9vXFwuLlxcYmFyXFwuLlxcLi5cXGJhei4uXFwiLCJ7fH1+XHUwMDdmIjoie3x9flx1MDA3ZiIsIi4uL2Zvby8uLi9iYXIvLi4vLi4vYmF6Li4vIjoiLi4vZm9vLy4uL2Jhci8uLi8uLi9iYXouLi8iLCJmb28vYmFyL2JheiI6ImZvby9iYXIvYmF6IiwiZm9vIGJhciBiYXoiOiJmb28gYmFyIGJheiIsImAiOiJgIiwiOjtcdTAwM2M9XHUwMDNlPyI6Ijo7XHUwMDNjPVx1MDAzZT8ifX0=" + } + }, + { + "ID": "68fd7f6510bd804f", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-metadata?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1679" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:56 GMT" + ], + "Etag": [ + "CK2owd21x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89xcOconPLmFaK0oaz56bElclv8p6ErRoiMq3PX5sWfF5iT0DwsMeTOitcuMm_3sdc" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItbWV0YWRhdGEvMTc1Mjg3NjQ3NjAyNzk0OSIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1tZXRhZGF0YSIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLW1ldGFkYXRhP2dlbmVyYXRpb249MTc1Mjg3NjQ3NjAyNzk0OSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItbWV0YWRhdGEiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY0NzYwMjc5NDkiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiI1IiwibWQ1SGFzaCI6IlhVRkFLcnhMS25hNWNaMlJFQmZGa2c9PSIsImNyYzMyYyI6Im1uRzdUQT09IiwiZXRhZyI6IkNLMm93ZDIxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuMDI5WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU2LjAyOVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTYuMDI5WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjU2LjAyOVoiLCJtZXRhZGF0YSI6eyJmb28vL2Jhci8vL2JheiI6ImZvby8vYmFyLy8vYmF6IiwiLi5cXGZvb1xcXFxiYXJcXFxcXFxiYXoiOiIuLlxcZm9vXFxcXGJhclxcXFxcXGJheiIsIlx1MDAwMFx1MDAwMVx1MDAwMlx1MDAwM1x1MDAwNFx1MDAwNVx1MDAwNlx1MDAwN1xiXHRcblx1MDAwYlxmXHJcdTAwMGVcdTAwMGYiOiJcdTAwMDBcdTAwMDFcdTAwMDJcdTAwMDNcdTAwMDRcdTAwMDVcdTAwMDZcdTAwMDdcYlx0XG5cdTAwMGJcZlxyXHUwMDBlXHUwMDBmIiwiICFcIiMkJSYnKCkqKywtLi8iOiIgIVwiIyQlJicoKSorLC0uLyIsImZvb1xcYmFyXFxiYXoiOiJmb29cXGJhclxcYmF6IiwiMTIzNDUiOiIxMjM0NSIsIkAiOiJAIiwiZm9vXCJiYXJcImJheiI6ImZvb1wiYmFyXCJiYXoiLCJbXFxdXl8iOiJbXFxdXl8iLCLimLrimLrimLoiOiLimLrimLrimLoiLCJcdTAwMTBcdTAwMTFcdTAwMTJcdTAwMTNcdTAwMTRcdTAwMTVcdTAwMTZcdTAwMTdcdTAwMThcdTAwMTlcdTAwMWFcdTAwMWJcdTAwMWNcdTAwMWRcdTAwMWVcdTAwMWYiOiJcdTAwMTBcdTAwMTFcdTAwMTJcdTAwMTNcdTAwMTRcdTAwMTVcdTAwMTZcdTAwMTdcdTAwMThcdTAwMTlcdTAwMWFcdTAwMWJcdTAwMWNcdTAwMWRcdTAwMWVcdTAwMWYiLCIuLlxcZm9vXFwuLlxcYmFyXFwuLlxcLi5cXGJhei4uXFwiOiIuLlxcZm9vXFwuLlxcYmFyXFwuLlxcLi5cXGJhei4uXFwiLCJ7fH1+XHUwMDdmIjoie3x9flx1MDA3ZiIsIi4uL2Zvby8uLi9iYXIvLi4vLi4vYmF6Li4vIjoiLi4vZm9vLy4uL2Jhci8uLi8uLi9iYXouLi8iLCJmb28vYmFyL2JheiI6ImZvby9iYXIvYmF6IiwiZm9vIGJhciBiYXoiOiJmb28gYmFyIGJheiIsImAiOiJgIiwiOjtcdTAwM2M9XHUwMDNlPyI6Ijo7XHUwMDNjPVx1MDAzZT8ifX0=" + } + }, + { + "ID": "be5d97d1685123ff", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-metadata?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:56 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89nRw8S1kEXq_QDQIZP7wo44HCEhdC9GgSxPPDT4ixnIO876g1xqxvK8TaR7RA7r_A" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestNonexistentBucket.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestNonexistentBucket.replay new file mode 100644 index 000000000..652e9bd6d --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestNonexistentBucket.replay @@ -0,0 +1,155 @@ +{ + "Initial": "AQAAAA7gDLyaIJaENgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "1143db950177a430", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/bucket-does-not-exist/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=\u0026prefix=\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "446" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:23 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89eAgVZ8N0yc9SM2AVYo_cCe_cFwcKZyB3dKR-JtQR0U12mYIIk0f_JQcJ6mdkf1--6KVebGNM" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDMsIm1lc3NhZ2UiOiJydmFuZ2VudEBnb29nbGUuY29tIGRvZXMgbm90IGhhdmUgc3RvcmFnZS5vYmplY3RzLmxpc3QgYWNjZXNzIHRvIHRoZSBHb29nbGUgQ2xvdWQgU3RvcmFnZSBidWNrZXQuIFBlcm1pc3Npb24gJ3N0b3JhZ2Uub2JqZWN0cy5saXN0JyBkZW5pZWQgb24gcmVzb3VyY2UgKG9yIGl0IG1heSBub3QgZXhpc3QpLiIsImVycm9ycyI6W3sibWVzc2FnZSI6InJ2YW5nZW50QGdvb2dsZS5jb20gZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMubGlzdCBhY2Nlc3MgdG8gdGhlIEdvb2dsZSBDbG91ZCBTdG9yYWdlIGJ1Y2tldC4gUGVybWlzc2lvbiAnc3RvcmFnZS5vYmplY3RzLmxpc3QnIGRlbmllZCBvbiByZXNvdXJjZSAob3IgaXQgbWF5IG5vdCBleGlzdCkuIiwiZG9tYWluIjoiZ2xvYmFsIiwicmVhc29uIjoiZm9yYmlkZGVuIn1dfX0=" + } + }, + { + "ID": "259324496a86c175", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026delimiter=\u0026endOffset=\u0026includeFoldersAsPrefixes=false\u0026includeTrailingDelimiter=false\u0026matchGlob=\u0026maxResults=1\u0026pageToken=\u0026prefix=\u0026prettyPrint=false\u0026projection=full\u0026startOffset=\u0026versions=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "1019" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:23 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH898UNRHrvuzQNlINo-DTRTnfoELjzhwz1prriKIUkTM5kAYHfXpwDRXKEBHaEFXQ1w" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3RzIiwibmV4dFBhZ2VUb2tlbiI6IkNoVmliRzlpTFdadmNpMWpiM0I1YVc1bkxXUmxjM1E9IiwiaXRlbXMiOlt7ImtpbmQiOiJzdG9yYWdlI29iamVjdCIsImlkIjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1jb3B5aW5nLWRlc3QvMTc1Mjg3NTg4MjI5MDEwMCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1jb3B5aW5nLWRlc3QiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1jb3B5aW5nLWRlc3Q/Z2VuZXJhdGlvbj0xNzUyODc1ODgyMjkwMTAwJmFsdD1tZWRpYSIsIm5hbWUiOiJibG9iLWZvci1jb3B5aW5nLWRlc3QiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzU4ODIyOTAxMDAiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW4iLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiIxMSIsIm1kNUhhc2giOiJzUXFOc1dUZ2RVRUZ0Nm1iNXk0LzVRPT0iLCJjb250ZW50RW5jb2RpbmciOiJpZGVudGl0eSIsImNvbnRlbnREaXNwb3NpdGlvbiI6ImlubGluZSIsImNvbnRlbnRMYW5ndWFnZSI6ImVuIiwiY2FjaGVDb250cm9sIjoibm8tY2FjaGUiLCJjcmMzMmMiOiJhUjJxTHc9PSIsImV0YWciOiJDTFMzc3NLeng0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU4OjAyLjI5N1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMTo1ODowMi4yOTdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIxOjU4OjAyLjI5N1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMTo1ODowMi4yOTdaIiwibWV0YWRhdGEiOnsiZm9vIjoiYmFyIn19XX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/length_0_read.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/length_0_read.replay new file mode 100644 index 000000000..e508922ab --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/length_0_read.replay @@ -0,0 +1,313 @@ +{ + "Initial": "AQAAAA7gDLynBkxd5QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "47766f05f0a9461b", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsIm5hbWUiOiJibG9iLWZvci1yZWFkaW5nIn0K", + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Etag": [ + "CJKL1tO1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Quwfb_ApKBtoCb5ySv-LFMWOohsRNkZ142Q-lU7dxj85FE22Qc1nn2qeN7fbzml3q" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDU1Mzk2NzU0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ1NTM5Njc1NCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ1NTM5Njc1NCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjI3IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsImNyYzMyYyI6Ik1vVm02UT09IiwiZXRhZyI6IkNKS0wxdE8xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzUuNDAwWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM1LjQwMFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzUuNDAwWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM1LjQwMFoifQ==" + } + }, + { + "ID": "7ec578f013512646", + "Request": { + "Method": "HEAD", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876455396754" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_VPyaeWtmsMHz2WeKfqsBM6taAMuBrb5NMKQBaWXfZn8QpoZbIOx14rTzfE26sHvdI" + ] + }, + "Body": "" + } + }, + { + "ID": "c1d49758921336b5", + "Request": { + "Method": "HEAD", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876455396754" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH882USJd6joPjY_LA6csL7z4Ksr40uRUT_pZMzthpnb5ZnZBs8MVrgQ5-P5t7JwHhdTI" + ] + }, + "Body": "" + } + }, + { + "ID": "ecc3ef56bb889112", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89WA9p0wXiM4rhUyfpmp9dHuIejg-jLlcFfTw25PGUk9nDGG0NUDeyKPnHd_87g8PHs" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/negative_offset_fails.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/negative_offset_fails.replay new file mode 100644 index 000000000..e66f60a68 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/negative_offset_fails.replay @@ -0,0 +1,39 @@ +{ + "Initial": "AQAAAA7gDLynBjuT0AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_a_part_in_middle.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_a_part_in_middle.replay new file mode 100644 index 000000000..693ba62a0 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_a_part_in_middle.replay @@ -0,0 +1,574 @@ +{ + "Initial": "AQAAAA7gDLyoKvpIbwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "07381d881538b105", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsIm5hbWUiOiJibG9iLWZvci1yZWFkaW5nIn0K", + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Etag": [ + "CLu7udS1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89NdClkXcmycNQ0VCjtSUIKxPig0rL_5rGWcQa6e5BNm2L6BoGKj6TGu-Xnq6R9tXw1" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDU3MDI0OTU1Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ1NzAyNDk1NSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ1NzAyNDk1NSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjI3IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsImNyYzMyYyI6Ik1vVm02UT09IiwiZXRhZyI6IkNMdTd1ZFMxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzcuMDI3WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM3LjAyN1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzcuMDI3WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM3LjAyN1oifQ==" + } + }, + { + "ID": "a59b1cbdd1803b81", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=10-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 10-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876457024955" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-2kOta0VlnXP3GUMiK8yZQ7aMDV5vsSAWqvel_zH7c01EQjmHfJG-Poe1gPzFO9gc" + ] + }, + "Body": "a2xtbm8=" + } + }, + { + "ID": "885f998341d2cb27", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=10-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 10-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876457024955" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH89EVN3LHpKXe9tdXpxBhAZlUcDe-yjA6ckCCq2Iz3hOxvyOFisNIzD-_bK86aYp5Jo" + ] + }, + "Body": "a2xtbm8=" + } + }, + { + "ID": "27a37987a3c9e8a7", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=14-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 14-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876457024955" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-Z2JS5OUEJOhvFqDIdkfcsMQ-nm5JaqfC0IX2SppCzm7Ts2egtIIoxF8A8hgTLBU_x" + ] + }, + "Body": "bw==" + } + }, + { + "ID": "9fcc6b88c0eb15fa", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=14-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 14-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876457024955" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH89hL6-ccAWbKtbz-Z1io3pJdq4GWM6HFhABabffgxNPhYEXdkK3cgHgsfnW5cfgnbg" + ] + }, + "Body": "bw==" + } + }, + { + "ID": "ace1e462e5962e7e", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=12-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "3" + ], + "Content-Range": [ + "bytes 12-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876457024955" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH89RbYwiQ9Tf4KNCd9lPa-32v0cl1EwN7gaxr5Ya0N1yzatagvrrS3idAdic9RkPpxc" + ] + }, + "Body": "bW5v" + } + }, + { + "ID": "54c8961eaf311dbd", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:37 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_nqUChlM1cy_UuL0ovuPE6nafsxRe2NmWS_w-WndQK3_C7WImQkAMyatMOUNKTZTwn" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_from_positive_offset_to_end.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_from_positive_offset_to_end.replay new file mode 100644 index 000000000..d79577a75 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_from_positive_offset_to_end.replay @@ -0,0 +1,574 @@ +{ + "Initial": "AQAAAA7gDLynKBZZqQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "4df646755fc3455b", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsIm5hbWUiOiJibG9iLWZvci1yZWFkaW5nIn0K", + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:36 GMT" + ], + "Etag": [ + "CPHN+tO1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH889ltrqsW4soTzWWeMHB4sdFshGNutsMvjkS8tauDtIge28kdMFEvbYY8D0PaHvEatM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDU1OTk1MTIxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ1NTk5NTEyMSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ1NTk5NTEyMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjI3IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsImNyYzMyYyI6Ik1vVm02UT09IiwiZXRhZyI6IkNQSE4rdE8xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzUuOTk3WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM1Ljk5N1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzUuOTk3WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM1Ljk5N1oifQ==" + } + }, + { + "ID": "b61f0914f3be63cd", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=10-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "17" + ], + "Content-Range": [ + "bytes 10-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:36 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876455995121" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_bHZJHJwSDOeyNasXtWoDj67PX9tNs8qp52paTfxWk5Lpm4nhlDxvLJHA-DFPhdRo" + ] + }, + "Body": "a2xtbm9wcXVyc3R1dnd4eXo=" + } + }, + { + "ID": "b14410d657e7aebd", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=10-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "17" + ], + "Content-Range": [ + "bytes 10-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:36 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876455995121" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-doUeR751N4ECA158_l8P8tD806_a_10Zy5XjX3UickKmWuI0zK6vJNp2_llXy5lo" + ] + }, + "Body": "a2xtbm9wcXVyc3R1dnd4eXo=" + } + }, + { + "ID": "f983b2b7972698c3", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=22-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 22-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:36 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876455995121" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH88QfrfRjxGXnaU62Qkjz5l69hs-Yw-2csZ3-x2LX-QEOxuN-Sd0m3FCrqiKZyb78Rh0" + ] + }, + "Body": "dnd4eXo=" + } + }, + { + "ID": "a34fbaf484beb39a", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=22-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 22-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:36 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876455995121" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH89kg8-haMNXJI_59PZyt_Kd4KDyVCG_0o4ernAEXKMMBZj94qjgrgwfZ-POW26oiYQ" + ] + }, + "Body": "dnd4eXo=" + } + }, + { + "ID": "2bf0684a60e9dab4", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=16-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "11" + ], + "Content-Range": [ + "bytes 16-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:36 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876455995121" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-xm2eudg1GTrgF3H8I7GDJ3igrW5IxJ5iezEqHoJGGpuszLaTsDDwYgLgZ95skwZk" + ] + }, + "Body": "cXVyc3R1dnd4eXo=" + } + }, + { + "ID": "20e4343504e60afe", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:36 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-VqH4HXbyJto2z1QfEYBpXNspj1F8QpzuZj7ldLoJnoNHV78MEVsz2T8-2Inqa92i0" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_in_full.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_in_full.replay new file mode 100644 index 000000000..c78b8ae2c --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_in_full.replay @@ -0,0 +1,568 @@ +{ + "Initial": "AQAAAA7gDLypLU0sZQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "5d8bc71abc37f8f7", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsIm5hbWUiOiJibG9iLWZvci1yZWFkaW5nIn0K", + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Etag": [ + "CP3299S1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89WFG2Xj6HkpEdLdLpYl0nmYF-84dnV9mYYkSilT6EKzUaOAs3GPbR38uLSx1SznS2o" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDU4MDQ4MzgxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ1ODA0ODM4MSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ1ODA0ODM4MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjI3IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsImNyYzMyYyI6Ik1vVm02UT09IiwiZXRhZyI6IkNQMzI5OVMxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzguMDUwWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM4LjA1MFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzguMDUwWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM4LjA1MFoifQ==" + } + }, + { + "ID": "031147e4aea9a97e", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876458048381" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH88f-JxNytw01hqGo0ESyFERS_26J-rxRcRtoNS5e2tlR7KGpbIaaoAk1NSMBdNjSHhU" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "4de5a31651e28835", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876458048381" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH89eBoRFNNUaczweKJ2xCyHRGm4HDsyTnUG2IaRaGVsCRgKeKkWOlz4YQGcsJV79Gibo" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "3592230dbf576797", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876458048381" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-NEPwG1XX0Y7NscPntQ4ksi1M3tfVhcOAfRK9F6SV9U3HWdajpXu1xrZbW2d5frkM" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "e312880e622c527c", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876458048381" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_qJoA9gA7Afm0a4xUgPF9_IFU-SfRBzsOzr4Xi9-LOpQIFO37qbX1476LNsDEE3wU" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "9cf2d9a8a93b4d65", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=9-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "18" + ], + "Content-Range": [ + "bytes 9-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876458048381" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_PRVB4Jigvw2sV2J4b891v-N2jrJYbslpAG7bHSfV4PFs-VHVSDZ1-9FcoTtlJuxQ" + ] + }, + "Body": "amtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "e8b97fc95075d121", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:38 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89xm4WjJp-CuHFW2XrxGUnz3vbjqwrWanzOk4LN1UT-Rga8hqJ1K_h63mVGWQfkvAgB" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_in_full_with_negative_length_not_-1.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_in_full_with_negative_length_not_-1.replay new file mode 100644 index 000000000..9af65845a --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_in_full_with_negative_length_not_-1.replay @@ -0,0 +1,568 @@ +{ + "Initial": "AQAAAA7gDLyqMYZSXwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "1947ecb0e537785b", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsIm5hbWUiOiJibG9iLWZvci1yZWFkaW5nIn0K", + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Etag": [ + "CPnFutW1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-I5fxYQ2BzcTFfSgjxAaiekJBYqdDtXl-cxecaVgZcos7FKQdB8pgUvdGXK_vv6B_f" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDU5MTM5ODMzIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ1OTEzOTgzMyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ1OTEzOTgzMyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjI3IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsImNyYzMyYyI6Ik1vVm02UT09IiwiZXRhZyI6IkNQbkZ1dFcxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzkuMTQyWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM5LjE0MloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzkuMTQyWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM5LjE0MloifQ==" + } + }, + { + "ID": "d720a8757b8aa7f0", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876459139833" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH89bSB0RMxnbTjGMPTk6NIIMbFMDeYcsEMAjHsbrhaN1BYB60l1VeJgA2PT1Ov509Xk" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "628a32b0512917a2", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876459139833" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_PT6yhl1e9HeP4ORcEYWmPxBhhiM-qS4IRlUFQ3PjeeeVhSSyhm9VhZrsNXhUDNtE7" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "a204cc1eab61f841", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876459139833" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-mSot7_RPQSndiwvvwuDWaSaPMtaYb6SRit2bHnR4wafF3IOFdTY-x-gdy77v1Tuw" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "b06e5d6b129b41ba", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876459139833" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH88sskeyUst9NV5SeYwaHLXuiXPwZIjyNTUWhCEB_CtcRhnHRgQZuWsnh1C_78Nb0Yuq" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "939914d1c4755dd3", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Range": [ + "bytes=9-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "18" + ], + "Content-Range": [ + "bytes 9-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876459139833" + ], + "X-Goog-Hash": [ + "crc32c=MoVm6Q==", + "md5=PflsWr6X8pZ9OAEIcAMKXw==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "27" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-XOjII9SpPC_YVMmQFx2vIRsLuFPxOBFC4i2yleyr7XILT4BIPuuRlWGR42ArDKBcu" + ] + }, + "Body": "amtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "a90d8548e68c770e", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:39 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89mE9xtTBzPFJHvJLYiB7jRn7xtNlqVdxqagALokTdYmLCicj-7BmqZbC-mqI5OPEZD" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_of_nonexistent_key_fails.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_of_nonexistent_key_fails.replay new file mode 100644 index 000000000..09ecad842 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestRead/read_of_nonexistent_key_fails.replay @@ -0,0 +1,211 @@ +{ + "Initial": "AQAAAA7gDLymG8l9WgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "2c31824080e600cf", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsIm5hbWUiOiJibG9iLWZvci1yZWFkaW5nIn0K", + "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:34 GMT" + ], + "Etag": [ + "COCQsNO1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_vFgROm-11lDtFEbrjRU6bTMFLJyaIcxBmIK8CnGLalxN2qKK0fd0VCvkvJyJPnuGq" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDU0Nzc0ODgwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ1NDc3NDg4MCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ1NDc3NDg4MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjI3IiwibWQ1SGFzaCI6IlBmbHNXcjZYOHBaOU9BRUljQU1LWHc9PSIsImNyYzMyYyI6Ik1vVm02UT09IiwiZXRhZyI6IkNPQ1FzTk8xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzQuNzc3WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM0Ljc3N1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6MzQuNzc3WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjM0Ljc3N1oifQ==" + } + }, + { + "ID": "f773a3d8dca8b017", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/key-does-not-exist", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "206" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH88RqkTCUOVLvJQOaGpL2p1axrh5aB1QaULi8PjNbAjOKQBVgocqeKkRwaENdsZe2utW" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9rZXktZG9lcy1ub3QtZXhpc3Q8L0RldGFpbHM+PC9FcnJvcj4=" + } + }, + { + "ID": "e4ca8b2c0e89bff3", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:35 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89VSEjV1infu3hy490hcxU7R6pUt4FMR3MVeuPYScxTCI9ZgNGhwuM6PVQCBXntKkai" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestSignedURL.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestSignedURL.replay new file mode 100644 index 000000000..7fae29422 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestSignedURL.replay @@ -0,0 +1,915 @@ +{ + "Initial": "AQAAAA7gDLzTJessZQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "70704aa657c55a66", + "Request": { + "Method": "PUT", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "355" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:19 GMT" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-eXc5Tbi8KrDwpd77sJuYcMmxB4LWXrCe2otnHx2SnPX2hKUAjkHlTcx0Yk16u5pbal6HUSOs" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+U2lnbmF0dXJlRG9lc05vdE1hdGNoPC9Db2RlPjxNZXNzYWdlPkFjY2VzcyBkZW5pZWQuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0IHNpZ25hdHVyZSB3ZSBjYWxjdWxhdGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaWduYXR1cmUgeW91IHByb3ZpZGVkLiBDaGVjayB5b3VyIEdvb2dsZSBzZWNyZXQga2V5IGFuZCBzaWduaW5nIG1ldGhvZC48L0RldGFpbHM+PFN0cmluZ1RvU2lnbj5QVVQKCgoxNzUyODgwMDk5Ci9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLXNpZ25pbmc8L1N0cmluZ1RvU2lnbj48L0Vycm9yPg==" + } + }, + { + "ID": "859a5a65e45d16cc", + "Request": { + "Method": "PUT", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "355" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:19 GMT" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88ks6cPcNwA5zAnlGeRys4WAxKg8R2Qe11PmbQUkt5sWA9K61k2cWSujFU8_JpUzahknRUwCaE" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+U2lnbmF0dXJlRG9lc05vdE1hdGNoPC9Db2RlPjxNZXNzYWdlPkFjY2VzcyBkZW5pZWQuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0IHNpZ25hdHVyZSB3ZSBjYWxjdWxhdGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaWduYXR1cmUgeW91IHByb3ZpZGVkLiBDaGVjayB5b3VyIEdvb2dsZSBzZWNyZXQga2V5IGFuZCBzaWduaW5nIG1ldGhvZC48L0RldGFpbHM+PFN0cmluZ1RvU2lnbj5QVVQKCgoxNzUyODgwMDk5Ci9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLXNpZ25pbmc8L1N0cmluZ1RvU2lnbj48L0Vycm9yPg==" + } + }, + { + "ID": "b8c1c702a997a133", + "Request": { + "Method": "PUT", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/html; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:20 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin" + ], + "X-Goog-Generation": [ + "1752876500005070" + ], + "X-Goog-Hash": [ + "crc32c=yZRlqg==", + "md5=XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH88A2dqkjfuYIoFfWDocVkfjrnugweF_0cDlB2ROTeFFAwwFiQESwCeokFRbqpxItutTUCbdtPA" + ] + }, + "Body": "" + } + }, + { + "ID": "cbb542525a2577f2", + "Request": { + "Method": "PUT", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "379" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:20 GMT" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88BbTkjwo1Zsgw8DWXRTa3t9xm8Ow0tpdFhRqGYmbIIvny-__4HQL_B4szNljbThTH_Xl6hePs" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+U2lnbmF0dXJlRG9lc05vdE1hdGNoPC9Db2RlPjxNZXNzYWdlPkFjY2VzcyBkZW5pZWQuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0IHNpZ25hdHVyZSB3ZSBjYWxjdWxhdGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaWduYXR1cmUgeW91IHByb3ZpZGVkLiBDaGVjayB5b3VyIEdvb2dsZSBzZWNyZXQga2V5IGFuZCBzaWduaW5nIG1ldGhvZC48L0RldGFpbHM+PFN0cmluZ1RvU2lnbj5QVVQKCmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbQoxNzUyODgwMDk5Ci9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLXNpZ25pbmc8L1N0cmluZ1RvU2lnbj48L0Vycm9yPg==" + } + }, + { + "ID": "e18cd2bd58b18da9", + "Request": { + "Method": "PUT", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "355" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:20 GMT" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-jil-L9WCnOOfaBgaGajE0wG31B7R1TxV3o3k2KJUHyAxeO0ANymHsRCZ-3c9TSKP_CajpOMc" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+U2lnbmF0dXJlRG9lc05vdE1hdGNoPC9Db2RlPjxNZXNzYWdlPkFjY2VzcyBkZW5pZWQuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0IHNpZ25hdHVyZSB3ZSBjYWxjdWxhdGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaWduYXR1cmUgeW91IHByb3ZpZGVkLiBDaGVjayB5b3VyIEdvb2dsZSBzZWNyZXQga2V5IGFuZCBzaWduaW5nIG1ldGhvZC48L0RldGFpbHM+PFN0cmluZ1RvU2lnbj5QVVQKCgoxNzUyODgwMDk5Ci9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLXNpZ25pbmc8L1N0cmluZ1RvU2lnbj48L0Vycm9yPg==" + } + }, + { + "ID": "4e5c1b3cdefcfe97", + "Request": { + "Method": "PUT", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/html; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:20 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin" + ], + "X-Goog-Generation": [ + "1752876500309753" + ], + "X-Goog-Hash": [ + "crc32c=yZRlqg==", + "md5=XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH89ey7Nw9PYlIqEpkjQBTcYlcVcSPGrcCrUPZGwNzwJOkm4tZu4_HJkoV4wAbbTzJ8e8L5xZFqg" + ] + }, + "Body": "" + } + }, + { + "ID": "628dad72644e59b7", + "Request": { + "Method": "PUT", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "379" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:20 GMT" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89qZNksUCTnKEpWPqaRnFm6yJ5aVIcuz7cg9FP_92znemzYflFNbbKJxbEo9vsCsq7jucWWJaw" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+U2lnbmF0dXJlRG9lc05vdE1hdGNoPC9Db2RlPjxNZXNzYWdlPkFjY2VzcyBkZW5pZWQuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0IHNpZ25hdHVyZSB3ZSBjYWxjdWxhdGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaWduYXR1cmUgeW91IHByb3ZpZGVkLiBDaGVjayB5b3VyIEdvb2dsZSBzZWNyZXQga2V5IGFuZCBzaWduaW5nIG1ldGhvZC48L0RldGFpbHM+PFN0cmluZ1RvU2lnbj5QVVQKCmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbQoxNzUyODgwMDk5Ci9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLXNpZ25pbmc8L1N0cmluZ1RvU2lnbj48L0Vycm9yPg==" + } + }, + { + "ID": "6940d57013b26411", + "Request": { + "Method": "PUT", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/html; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:20 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin" + ], + "X-Goog-Generation": [ + "1752876500526849" + ], + "X-Goog-Hash": [ + "crc32c=yZRlqg==", + "md5=XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_a5iEb-v_B052zoYO-YJryh88M7pL92DhO9yGag0kWm8J88MGij05dkygGQzLkMQBg94ApiMY" + ] + }, + "Body": "" + } + }, + { + "ID": "ceea7dbab8db988b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "355" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:20 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH89MW_3ONur8R-ygTK7UQe7B40jvs8V66GboX3rKFp2r4uUVouPxlm96qJsyktX7HZM" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+U2lnbmF0dXJlRG9lc05vdE1hdGNoPC9Db2RlPjxNZXNzYWdlPkFjY2VzcyBkZW5pZWQuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0IHNpZ25hdHVyZSB3ZSBjYWxjdWxhdGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaWduYXR1cmUgeW91IHByb3ZpZGVkLiBDaGVjayB5b3VyIEdvb2dsZSBzZWNyZXQga2V5IGFuZCBzaWduaW5nIG1ldGhvZC48L0RldGFpbHM+PFN0cmluZ1RvU2lnbj5HRVQKCgoxNzUyODgwMDk5Ci9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLXNpZ25pbmc8L1N0cmluZ1RvU2lnbj48L0Vycm9yPg==" + } + }, + { + "ID": "a1eff2f8ce09e93e", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "355" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:20 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_wqrPTiIj1XGeWiEL-YctlyzBgrnih-QKJcVkyC3-KvwJ6EVJx0UlsiPfCec9lYxI" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+U2lnbmF0dXJlRG9lc05vdE1hdGNoPC9Db2RlPjxNZXNzYWdlPkFjY2VzcyBkZW5pZWQuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0IHNpZ25hdHVyZSB3ZSBjYWxjdWxhdGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaWduYXR1cmUgeW91IHByb3ZpZGVkLiBDaGVjayB5b3VyIEdvb2dsZSBzZWNyZXQga2V5IGFuZCBzaWduaW5nIG1ldGhvZC48L0RldGFpbHM+PFN0cmluZ1RvU2lnbj5HRVQKCgoxNzUyODgwMDk5Ci9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLXNpZ25pbmc8L1N0cmluZ1RvU2lnbj48L0Vycm9yPg==" + } + }, + { + "ID": "fc316f2582fca5e0", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "298" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:20 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH892pCoAdUgxGLtSahDucEnRIyd25D5LERBcr9v_NoPmI6VjdMVvN83utdIOebX9BGAL" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+QWNjZXNzRGVuaWVkPC9Db2RlPjxNZXNzYWdlPkFjY2VzcyBkZW5pZWQuPC9NZXNzYWdlPjxEZXRhaWxzPkFub255bW91cyBjYWxsZXIgZG9lcyBub3QgaGF2ZSBzdG9yYWdlLm9iamVjdHMuZ2V0IGFjY2VzcyB0byB0aGUgR29vZ2xlIENsb3VkIFN0b3JhZ2Ugb2JqZWN0LiBQZXJtaXNzaW9uICdzdG9yYWdlLm9iamVjdHMuZ2V0JyBkZW5pZWQgb24gcmVzb3VyY2UgKG9yIGl0IG1heSBub3QgZXhpc3QpLjwvRGV0YWlscz48L0Vycm9yPg==" + } + }, + { + "ID": "8601b93fe51a60de", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:21 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:20 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876500526849" + ], + "X-Goog-Hash": [ + "crc32c=yZRlqg==", + "md5=XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH88JfytUX5rs2OWUk4r3gHhx5H8ME3MH2L62LHR6fXiyawrsAdpTl7c9GrBj8eKQCvA" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "8fd5fecfabc111b2", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "358" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:21 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-C2QF4EvuiqPfmjSQLa_sSsjtT3wz0slLCYH0BSWcVwD5Ppi_nVE1wyjl02aKsf27mr2a86bs" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+U2lnbmF0dXJlRG9lc05vdE1hdGNoPC9Db2RlPjxNZXNzYWdlPkFjY2VzcyBkZW5pZWQuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0IHNpZ25hdHVyZSB3ZSBjYWxjdWxhdGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaWduYXR1cmUgeW91IHByb3ZpZGVkLiBDaGVjayB5b3VyIEdvb2dsZSBzZWNyZXQga2V5IGFuZCBzaWduaW5nIG1ldGhvZC48L0RldGFpbHM+PFN0cmluZ1RvU2lnbj5ERUxFVEUKCgoxNzUyODgwMDk5Ci9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLXNpZ25pbmc8L1N0cmluZ1RvU2lnbj48L0Vycm9yPg==" + } + }, + { + "ID": "e0910f2d7f044a14", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "358" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:21 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-dVj4DWXaeDwGiEjUIyvXkY7QpMhJT07Evn_dtb7K7dzpD9zPCFGcCTDYGG9mA2LxnJe7nLIk" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+U2lnbmF0dXJlRG9lc05vdE1hdGNoPC9Db2RlPjxNZXNzYWdlPkFjY2VzcyBkZW5pZWQuPC9NZXNzYWdlPjxEZXRhaWxzPlRoZSByZXF1ZXN0IHNpZ25hdHVyZSB3ZSBjYWxjdWxhdGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaWduYXR1cmUgeW91IHByb3ZpZGVkLiBDaGVjayB5b3VyIEdvb2dsZSBzZWNyZXQga2V5IGFuZCBzaWduaW5nIG1ldGhvZC48L0RldGFpbHM+PFN0cmluZ1RvU2lnbj5ERUxFVEUKCgoxNzUyODgwMDk5Ci9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L2Jsb2ItZm9yLXNpZ25pbmc8L1N0cmluZ1RvU2lnbj48L0Vycm9yPg==" + } + }, + { + "ID": "4dfca2f27b10fd33", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "0" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:21 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89zN8THi8OelXGLZI-1KQUAqOXPgtwmgilB5hh5OxK-xFedSl2FEnJk2fIf4swp3rJ4TM8-KE8" + ] + }, + "Body": "" + } + }, + { + "ID": "2e3ff5b012790987", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-signing?Expires=CLEARED\u0026GoogleAccessId=storage-updater%40go-cloud-test-216917.iam.gserviceaccount.com\u0026Signature=CLEARED", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "204" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:21 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH88iyU_DI1gIV1zQg2XQjQASLBGq-nqFaiiliKhJZddacz4NIeWFsGOLe5tD-jhcN_8" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1zaWduaW5nPC9EZXRhaWxzPjwvRXJyb3I+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestUploadDownload.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestUploadDownload.replay new file mode 100644 index 000000000..15b1e5eea --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestUploadDownload.replay @@ -0,0 +1,358 @@ +{ + "Initial": "AQAAAA7gDLy4KBPBrwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "335bb95822956dab", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-upload-download\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0IiwibmFtZSI6ImJsb2ItZm9yLXVwbG9hZC1kb3dubG9hZCJ9Cg==", + "dXAgYW5kIGRvd24=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "804" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:52 GMT" + ], + "Etag": [ + "CLWHhty1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH883aIndOg9tWClQCCJKN1b56SzbxbiVDPT-ZL-pw-jLwiFQX9E2a42hAs63uUAXhQE" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItdXBsb2FkLWRvd25sb2FkLzE3NTI4NzY0NzI5NTk5MjUiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItdXBsb2FkLWRvd25sb2FkIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItdXBsb2FkLWRvd25sb2FkP2dlbmVyYXRpb249MTc1Mjg3NjQ3Mjk1OTkyNSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItdXBsb2FkLWRvd25sb2FkIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDcyOTU5OTI1IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoiRzNWVFB0V29hZjl2T3VBemJRd3pJQT09IiwiY3JjMzJjIjoiMzVjNnJnPT0iLCJldGFnIjoiQ0xXSGh0eTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Mi45NjFaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTIuOTYxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1Mi45NjFaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTIuOTYxWiJ9" + } + }, + { + "ID": "b86c31cb560d88c1", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-upload-download", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:53 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:52 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876472959925" + ], + "X-Goog-Hash": [ + "crc32c=35c6rg==", + "md5=G3VTPtWoaf9vOuAzbQwzIA==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH89fjNm9N0bUnGKsrVreCWuVjbbAGNvxEr78f9ul3VF6tVOk3SOzDS23MUGHT5VLxR_s" + ] + }, + "Body": "dXAgYW5kIGRvd24=" + } + }, + { + "ID": "b1ec5a03275550b8", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-upload-download\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0IiwibWQ1SGFzaCI6IkczVlRQdFdvYWY5dk91QXpiUXd6SUE9PSIsIm5hbWUiOiJibG9iLWZvci11cGxvYWQtZG93bmxvYWQifQo=", + "dXAgYW5kIGRvd24=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "804" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:53 GMT" + ], + "Etag": [ + "CJu+mty1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8--qzbJnmsT0eZ3uQSJCvapx9cNFVqLQZOcaUtehphEbdVPDbcH1gBz7RQubKSXpGg" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItdXBsb2FkLWRvd25sb2FkLzE3NTI4NzY0NzMyOTQ2MTkiLCJzZWxmTGluayI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItdXBsb2FkLWRvd25sb2FkIiwibWVkaWFMaW5rIjoiaHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL2Rvd25sb2FkL3N0b3JhZ2UvdjEvYi9nby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0L28vYmxvYi1mb3ItdXBsb2FkLWRvd25sb2FkP2dlbmVyYXRpb249MTc1Mjg3NjQ3MzI5NDYxOSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItdXBsb2FkLWRvd25sb2FkIiwiYnVja2V0IjoiZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldCIsImdlbmVyYXRpb24iOiIxNzUyODc2NDczMjk0NjE5IiwibWV0YWdlbmVyYXRpb24iOiIxIiwiY29udGVudFR5cGUiOiJ0ZXh0Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiMTEiLCJtZDVIYXNoIjoiRzNWVFB0V29hZjl2T3VBemJRd3pJQT09IiwiY3JjMzJjIjoiMzVjNnJnPT0iLCJldGFnIjoiQ0p1K210eTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1My4zMDFaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NTMuMzAxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo1My4zMDFaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NTMuMzAxWiJ9" + } + }, + { + "ID": "7b918a1781943bb5", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-upload-download?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:53 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_JBfvEF4gduOO93QEJ3sUGkaftbJbxsYZAzI6otzNZL4IbVra88Q56XhAQPIxpRPP_" + ] + }, + "Body": "" + } + }, + { + "ID": "22792189bea4822e", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-upload-download?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "231" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:53 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89mDfHGdK3PkKpb_hifZjoguCnOaHbtM9pKi4hLFJp8W-5glSzPLCBYPPgB-dG3ig37" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDQsIm1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci11cGxvYWQtZG93bmxvYWQiLCJlcnJvcnMiOlt7Im1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci11cGxvYWQtZG93bmxvYWQiLCJkb21haW4iOiJnbG9iYWwiLCJyZWFzb24iOiJub3RGb3VuZCJ9XX19" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/ContentType_is_discovered_if_not_provided.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/ContentType_is_discovered_if_not_provided.replay new file mode 100644 index 000000000..0fab988cb --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/ContentType_is_discovered_if_not_provided.replay @@ -0,0 +1,298 @@ +{ + "Initial": "AQAAAA7gDLyuL0QpmgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "afa1d8ec5ff11f69", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyJ9Cg==", + "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "794" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:43 GMT" + ], + "Etag": [ + "CPDJrNe1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89KQEdd1HMWtfqWJrBrEBOeTXbuNGgzN3yNr6GVd6kcQKEDGCbBxNTLlUsDg6SBBBVG" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDYzMTA1MjY0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2MzEwNTI2NCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2MzEwNTI2NCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNjM1NCIsIm1kNUhhc2giOiJEMnA4bi9QVDEzQzQ5L29ad3E0WjBBPT0iLCJjcmMzMmMiOiJ0ZHdyZ1E9PSIsImV0YWciOiJDUERKck5lMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQzLjEwN1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0My4xMDdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQzLjEwN1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo0My4xMDdaIn0=" + } + }, + { + "ID": "dcfa0f12a0a62260", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "text/html; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:43 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:43 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876463105264" + ], + "X-Goog-Hash": [ + "crc32c=tdwrgQ==", + "md5=D2p8n/PT13C49/oZwq4Z0A==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "6354" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-7sma3ueLmYoKbLJgRYIjEAcnyv9OgeNktIXPbG28pWzXAwU1WDxFRXkP6NQtHaYA" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "41245e04d21fcb86", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "794" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:43 GMT" + ], + "Etag": [ + "CPDJrNe1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89SW8rfRa8Jt8fqNmqkll8aI3G0rCM9MVCBX5EWpCS62FAj_ztZe2LJRwrb63ZhNrnG" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDYzMTA1MjY0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2MzEwNTI2NCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2MzEwNTI2NCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Iiwic3RvcmFnZUNsYXNzIjoiUkVHSU9OQUwiLCJzaXplIjoiNjM1NCIsIm1kNUhhc2giOiJEMnA4bi9QVDEzQzQ5L29ad3E0WjBBPT0iLCJjcmMzMmMiOiJ0ZHdyZ1E9PSIsImV0YWciOiJDUERKck5lMXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQzLjEwN1oiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0My4xMDdaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQzLjEwN1oiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowNzo0My4xMDdaIn0=" + } + }, + { + "ID": "5bbd0adfa457fd75", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:43 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH892oGhzUgWKKD1HDDuGfVMXIgd23H3ya2yxtJ8eZrc7uwt4c6sPEUq3mODrU6Qvm8Iv" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay new file mode 100644 index 000000000..8581da927 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay @@ -0,0 +1,239 @@ +{ + "Initial": "AQAAAA7gDLyvHUa2TQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "4534fc255f9c3ec9", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwibmFtZSI6ImJsb2ItZm9yLXJlYWRpbmcifQo=", + "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "753" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:43 GMT" + ], + "Etag": [ + "CKXI2Ne1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89GqfMOncATv1a5b6HDVeEdtmsPhurP6AXDG_ShPRAPStQyzgRwIS4uHy-0Bvk8ukE" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDYzODI1OTU3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2MzgyNTk1NyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2MzgyNTk1NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjYzNTQiLCJtZDVIYXNoIjoiRDJwOG4vUFQxM0M0OS9vWndxNFowQT09IiwiY3JjMzJjIjoidGR3cmdRPT0iLCJldGFnIjoiQ0tYSTJOZTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0My44MjhaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDMuODI4WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0My44MjhaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NDMuODI4WiJ9" + } + }, + { + "ID": "9a8ef092bfe9aa2b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:44 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:43 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876463825957" + ], + "X-Goog-Hash": [ + "crc32c=tdwrgQ==", + "md5=D2p8n/PT13C49/oZwq4Z0A==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "6354" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Ax5BEZ3mAXQoVnDCtJAOprUeJimblEAZbmVUcUGWsFYhK2qRWsYPoLFfKjzn4w1k" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "f7d111c33a1f3a81", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:44 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89E4OVy_onmh08ocpsTGwpHsZyCvnVC2YOSMZlS2VHJ-Fct5raLTfpVIz-rKBYDf-em" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match,_blob_existed.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match,_blob_existed.replay new file mode 100644 index 000000000..12b6a6b21 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match,_blob_existed.replay @@ -0,0 +1,239 @@ +{ + "Initial": "AQAAAA7gDLyxKyJJ1gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "16ea046d74008df2", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6ImRIOUIvU2NQN0J1Q3ZnTU13YzFJQVE9PSIsIm5hbWUiOiJibG9iLWZvci1yZWFkaW5nIn0K", + "ZXhpc3RpbmcgY29udGVudA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:46 GMT" + ], + "Etag": [ + "CPfR39i1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89K0KQXeLGysE3KrgWB5Kcp1Pd5dsMmg9iJMQDbid8hwkfrifRRrPLUOkAbBTdqHHM" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDY2MDM5MDMxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2NjAzOTAzMSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2NjAzOTAzMSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjE2IiwibWQ1SGFzaCI6ImRIOUIvU2NQN0J1Q3ZnTU13YzFJQVE9PSIsImNyYzMyYyI6Incvci9YQT09IiwiZXRhZyI6IkNQZlIzOWkxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDYuMDQxWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ2LjA0MVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDYuMDQxWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ2LjA0MVoifQ==" + } + }, + { + "ID": "ed083349ab1dd409", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "16" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:46 GMT" + ], + "Etag": [ + "\"747f41fd270fec1b82be030cc1cd4801\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:46 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876466039031" + ], + "X-Goog-Hash": [ + "crc32c=w/r/XA==", + "md5=dH9B/ScP7BuCvgMMwc1IAQ==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "16" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-mmVtbAzHZ-DfnHuIp5R1gE2UTv2rx_LDVUAYs0SqF_jPnceJ2RYFiKP2FAIhxqng" + ] + }, + "Body": "ZXhpc3RpbmcgY29udGVudA==" + } + }, + { + "ID": "e079b110ede3874d", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:46 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_nVVjkbQfz9P-B08hSjj9LTyDHejmArohhl6O_SFDWuNhSsAW595dbfsNh5pJMcKUg" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match.replay new file mode 100644 index 000000000..518ff6ed0 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_did_not_match.replay @@ -0,0 +1,92 @@ +{ + "Initial": "AQAAAA7gDLyxGg2K7gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "98423d9a068c45c0", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "204" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:45 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH895jtUqrS9l0e5pZMztrDgJhKPIAfnXjtGfcVPDcq97Q1skmhKb0AQ58ybIdrJB-hI" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1yZWFkaW5nPC9EZXRhaWxzPjwvRXJyb3I+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_match.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_match.replay new file mode 100644 index 000000000..91538950e --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/Content_md5_match.replay @@ -0,0 +1,239 @@ +{ + "Initial": "AQAAAA7gDLywMyLlHQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "cf93be6705795785", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsIm5hbWUiOiJibG9iLWZvci1yZWFkaW5nIn0K", + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:45 GMT" + ], + "Etag": [ + "CNv1qNi1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-I0gbKnSWKpnSZBMk6ikK6ZVrH5-6uHBonxV5J2grv818QerqPYDWZUh1ahwLHEOo" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDY1MTQyNDkxIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2NTE0MjQ5MSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2NTE0MjQ5MSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjExIiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsImNyYzMyYyI6InlaUmxxZz09IiwiZXRhZyI6IkNOdjFxTmkxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDUuMTQ1WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ1LjE0NVoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDUuMTQ1WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ1LjE0NVoifQ==" + } + }, + { + "ID": "fee993212e942843", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:45 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:45 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876465142491" + ], + "X-Goog-Hash": [ + "crc32c=yZRlqg==", + "md5=XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH896k2DGx35rTTTu7YNMm-Cv1eXG9FIkJwkqZL6h9HPIdBIc2k3Wug_RODFelFdQW3_x" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "ad6ca75d593a99b3", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:45 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-WtpV8X_-BXq3tBHA7J7fKkRIRyWv51ZX4vKzHr6g2JaCO4qunHat3P3oQ3u3GzGY" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/a_large_jpg_file_gets_a_ContentType.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/a_large_jpg_file_gets_a_ContentType.replay new file mode 100644 index 000000000..53f37c36e --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/a_large_jpg_file_gets_a_ContentType.replay @@ -0,0 +1,298 @@ +{ + "Initial": "AQAAAA7gDLyyOr+9CQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "e35bc31fca4a8001", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "781" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:47 GMT" + ], + "Etag": [ + "CLa3rtm1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89BPgLJKk0wqyam4y_DmTlWHRYbJoiLU0oivAD0Myk3dc47qrg96Qyw9r0DPLGTsVE" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDY3MzI5OTc0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2NzMyOTk3NCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2NzMyOTk3NCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiaW1hZ2UvanBlZyIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjM4NDMwIiwibWQ1SGFzaCI6Ill0US9vZzV3djZIOXNpVVEwY0JnMGc9PSIsImNyYzMyYyI6IitEWE5MUT09IiwiZXRhZyI6IkNMYTNydG0xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDcuMzMyWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ3LjMzMloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDcuMzMyWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ3LjMzMloifQ==" + } + }, + { + "ID": "c05e0aae548392e7", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:47 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:47 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876467329974" + ], + "X-Goog-Hash": [ + "crc32c=+DXNLQ==", + "md5=YtQ/og5wv6H9siUQ0cBg0g==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "38430" + ], + "X-Guploader-Uploadid": [ + "ABgVH88D0EUMCTyo3-M3R_YvPpLNG1lzaLpXc5uPHKiM5b7n1wlqEWqUU_bokVmzNZDhBZM" + ] + }, + "Body": "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + } + }, + { + "ID": "809bf814458744b8", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "781" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:47 GMT" + ], + "Etag": [ + "CLa3rtm1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_YRk8myHsOonWiWuFr5aObxRBccJMVo8xYpd2cmXrGtrfTfQM9HLQM7O6fn94ISm8" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDY3MzI5OTc0Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2NzMyOTk3NCZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2NzMyOTk3NCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiaW1hZ2UvanBlZyIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjM4NDMwIiwibWQ1SGFzaCI6Ill0US9vZzV3djZIOXNpVVEwY0JnMGc9PSIsImNyYzMyYyI6IitEWE5MUT09IiwiZXRhZyI6IkNMYTNydG0xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDcuMzMyWiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ3LjMzMloiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDcuMzMyWiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ3LjMzMloifQ==" + } + }, + { + "ID": "705c7de2be8e0301", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:47 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_ahccFtBU6dPx_gp7rPNWh_EL-g9GPsRMV_cTBte1YyNTRruHk4Cptdtv_VBDF8naI" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay new file mode 100644 index 000000000..5f52847a8 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay @@ -0,0 +1,298 @@ +{ + "Initial": "AQAAAA7gDLyzKHw/RgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "81873233d5a1bf4a", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJpbWFnZS9qcGVnIiwibmFtZSI6ImJsb2ItZm9yLXJlYWRpbmcifQo=", + "/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAH0A+gDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigAooooAKKKKACiiigAooooAKKDRzQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFMkkSJS7sFUdSTQA+iq/wBth3Fd65xnGamV1YZByKAHUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAAGBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFNd1QEsQAOpNADqKwr3xhoVg+y41O2jbjgyDv0qXSfE+ka2hfT76GcA7TtbkH6UAbFFICD0NLQAUUUUAFFGRRQAUUmaTcPWgB1FN3j1FKWA7igAZgqknoK8H+InjWbVNZfSLB7zCtsWOA43sD349vf8ACvV/Getx6H4Wvb9tx2R4G3sTwDXm3wm8OQS2cmuXRWe6uJGdXcElBnpzQBg23w/8ZzWx1VdRe2ugQ8VqJTwPQt612HgDx3qt/q02haxAqXlumWIBBbnuO3avTFjQRYwOBXjscsQ+O935TNkxBWA4Gdo6468etAHtkbbkBp9RQf6sfSpaACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAzzRRRQAUUUhIHU0ALRTd6+op2QaACiiigAooooAKKKSgBaKKKACiiigAooooAKKKKACkzzS0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAjHCk+leGfFLx1Lcu+jaeWVt+C5yuSO3PHPrXtWoXAtrCaYnARCa+f/CsVpr/AMTrm4kh27GJH/TQjvQBteDPhLb3lrDqOuhppZIx+5YkY5zzg81ual8Jbe0/03wzdy6bfpkptfcjcdDnJ/KvTII0hhAHAAqG21S0unZIpkZkOGAPSgDzjw58R7iz1FNC8URi11PzCgbGFcdiPY9K9PhuEmQMjAgjNeY/GDwuuraL/adoyx31mCwbpuTuMiuK0r4u3dn4dWK2t/PvEUKzHO1T0+tAH0M0iqMkiqN7rVhYQmS5uooVHJLuAAK8bt9b8b+I51tSk1sHhwxQfu8nnduAz07Z61sxfDDU7u1SS91udpjy6uisufUZHB/GgDrbvx5pdtG0yTfaI1++0QyE6dfzFY//AAtrRxbzvtuGkjJxEqZLc4GCOOfrUtn8KdFifzLjzbgk5Ikbg57YHaujtPB+iWciywWECSKMbggzigDz+/8AjEpkENhp879N7MCpXjJ4I7fWs+38ZeM9TZpNP064G9SYy8W5Poc4A7cjNewLo1gq4FrCBnOAg61Zjto4wAqKAOmBQB5E918S4oTO0NvgA5QqWJ54IA6fmaW3uPiUbIl4UM8pUpkj5Fzzn3wf0r2DYuMYFARR2FAHjEuieP8AVdMeO+lhk8zG23lVQFI65I/+vUdnYfELSVjgiht4oUXhLeNNuc/d59QeuO1e17B6UFAe1AHkJ1P4kral5LW3B3bQvl7mJ9eD07Dp71xOneIbnS/HtzfavpzQXHypcm35AY45Oe2PSvpQxqR0FUP7HsvPkmFvGJJDl22DLfWgDldD+JWg6mgCzvC27afPQqAc9CwyM/jXaQXUU6bkdWHqDmuO8Q/DTStaVmiZ7Nnbe4twArtggMR689f8K4dPCPjvwlqAbR7yXUbJWBWIyhV285BDd/cUAe35FLXmWj/FKKG6+xeI7cabMuMlycZ98jjPNei2l9b30KTW0qyRsMqynINAFiiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACkJAHNDMFUk14/8Svik2ku+j6Q2b8nYxGcqT6Y70AdX4z+I+l+E0WJmE94+QkKHOD746V5i+vfEfxvI0mnIdOt1YDumee2eTWt4E+Hd3qdxFrPibdNPnekbnOOc5P8AhXssNjDCiqiABemBQB4LeeGPiNpdp9rbV5rnaQzJFKxbaBzycelbPgv4k6hFd29lrMwlE+7bIy4KlTjHGc+tezmNSuCARXm/xA8HW0Wh3OraVFFb3to5vC2OHI5bd+FAHpEUgkjV1OQRmn1zHgjXBrfh2zuiyF3jBYIcgHvXT0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUCigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDm/HAu/8AhGLr7Jy+35lClsr36V4F4V1P+yvHscqPuieQq+8EHBPvX09KgkQowyCMGvCvif4Hk066XW9LgJgiO6ZUYIUHc5oA9vgkE1sD1BFeF+LdS1Dwd4s8+CSRoZpCxYrhR7H1r0jwf4lh1Tw/bzLICdoUgsD04NR+JfCFr4ihfdEjyEEpuJ2nPrigCDw74ms/F2nK6uCRw6MO/wBK85tLaDwf8UrnT57Um01Ah4eBjJI7exroPCngHWfC3irfAXksHHzlnGB9PU/hXoeueD9M8Q/ZpL2FvPt23wzRsVdD7EUAatlbxrEpRQBjjAq6BUdtCIIEjBJCgDJ6mpaACiiigAooooAKKKKACiiigAooooAKTaKWigDmPFnhKz1+xYmygmukH7vzRgH2J9K8ut18VfDAtcmyku9IL5ljik3LCM9VHX8694qOWFJkKOoKngg0AYnhrxXpvifTY72wuFkVuGXoynuCOxrf615l4h+H13pt1Jrng2b7Dfg7pLVR+5n9iOgPvT/C/wAUoL27Ok65bHS9WiKpJDKRhiRxtNAHpVFRxyrIqkHORUlABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRVa/keOxnaLmURsUGcZOOOaAPNfix4/Gh6c+l6dMpv5/kyhyUB6/Q1zfw5+Hvk3S6xrDia4kXKIQSFzzk5715idahtvFM97rllNc3CSNiLO75857mtS/8AiP4k1W+SbSEmtYYQFjRTlQfU9j+NAH1NbNFHGFUjgVP5qk4Br5k0i6+J2syzPb3txFIcYUqFTBHXNbF/YfEnwzbNrl7rxniiw0sSMSAM+mAMc0AfQqnNRXltFd2c1vMu6KVCjqe4IwRWT4T1pdd8P2t9n5pE+b69622+6aAPHfhQyaTr+r6MVdHimb5cgrgMRwevQDrXsleFWVw9l8b9SSGDejNyzM3yBgDkDpyT+le4RSB0BHTFAEtFFFABRRRQAUUUUAFFFFABSb1zjIzXGePfHEXhayEEGJNQnGIowRkZ4Bx1PPavJp7nxvcvJqckOooWVZPMVDwvU4xyOO2B0oA+jcg0V4l4d+KN3pl3Fb6zPFd2Uj7Eu425QcD5hjOM8ZNeyWV/b39vHPbyrJG43KVOcigCzRRRQAUUUUAFFFFABQM45oooAKKKKACiijFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFACMcKTXkvxX8cPpsf9iWNsZ7q4jOcgNt/4Dg5rr/GfjO28Lae0hTz7huEhVwGOe/Nee/D7wzceINduvFOsRyM0r/6OJjk7fXGPyxQBw2gp4m8Hz2zzwsIZz54DcKOuVx2r6D8Oa7bavYQTxkB3UNs3AkfXFR+KPCNt4j0OWwfZG5H7qUpkxt6iub8HfDm88MysTdpIdy/OAQWUHoc0AekqB1xwafSKMACloAKKKKACiiigAprNtHNQXN5DbRs8jgBQTXk/ib4nHzZLPSZvtN0GwIYoWLNg84PT/P4UAeszXkNuheWRVAGck4rIu/FemWgQyXMY3HH3xgcZ5ryo6J498TuiNs0q0YjIaUvJj/P0rorH4M6SrmW/uru9Z1AkE0nBPqMcigDoJviT4bhKhtTg2scAq2f5fStey8UaTfQiWC+hlQ91auePwm8KnP/ABLEyV2n526enWqFz8GNAaN0s3u7TcAMxTH8+c0Ad/FqdrM5RJkZ1ALKGyRmrSyK3Qg14xqnwl8QQSxz6T4ou96YUGWRgQmOmRwfyrNtPGPi/wAATxw+KIzdWJcr5wIZwBnBOPXjrQB73RWFoXifTtds457KdZFYZ6YrcBB6UALRRRQAhFcJ49+Hdl4rtvtEP+j6nD80M6Hbkjs3qK7ykIzQB5R4E8Z3sOoyeGPEMMkGp254ZyMSDtg9+Oc16Y+o2kKAyzxp0HzMBzXnvxb8L3F5ow1zSJHh1PTyZQ0fV1A5B+grzz4e+H38d2klze63dvMshEyMxJz26nGPwoA9guviV4dtZpInumby+rJEzL+YFRzfE/w5FKsYuJZCcZ8uJm2k9jgdam0L4f6Nom54YmllY5LytuPTFaR8JaOZXm+wwiRyCzBcE4II/kKADRvFuk65G72dyGCMVIYFTkdeDWzHPFKMo6kH0NcNq3wt0W6gdrKN7O5bJEsUjDJPrz0rjLHwd448Jy3UtnqsdxCpXyoSSxcDtg8LQB7gKK8x0T4pQrNFYa7by2V8ZPJIdMBnx25OByOtekwXEdxGHjYEHmgCWiiigAooooAKKKKACop4EnQqyg5GOalooA4w/D3QU1c3rWELvJnJdQ3P49K37fRbC0j2Q20SKOgVQBVy9uBbWrykZCjNeHax8ZNdu76Wy0DSVkkRmBcqzAAH0GKAPZha28N0SgVc8kCuU+JGrWVn4N1SNp4RNJAyohkClieOK4C3n+J/iLT3hZ1t1n+UyeRtKg475+tOh+Ceu6iqHWvEUsgUAbFLNx+JoAr/AAv8fW+neGja3swQ20nVmABB5rvY/i74edMO86ZztYxHDfTFZGkfArSLOM/apnncjjtiuug+G/huGFY/7LtzjqdnJ/GgD551/wAW3f8Awnd/renxXAjlOFDcE4AwenT2r0X4ffFu8vNTTSfEVutrLJgRSlSgY+hB716oPCejKBixiyvQlc15x8Z9MtLfw/aXcapFcRXAMbKBu6HPHftQB7DG4kQOpyD0p1c74L1JdT8M2M6ur7ohyvTI4NdFQAUUUUAFFFFABRRQelAHhHjRbfVPi5psMkhZVlAIC4K7e3X1HoK9straMQKAoxivEviXbxaX8QLK+l3ojyK4kCA7TkdDn869ig1W2h0xLiWZFiCbixPbGaAMzXPAWga4h+1WSh+MPESjDGccj6mvJdO1zUvhd4wk0vVJrm40eXLRyMdwRScAj+tdzqXxp8KWbvGLiWR1BxsjPzEehryHxr42/wCEs1azbStMupkjyNkiEs+e3HbvQB9M6Xq9pq1lHdWkySxSKCrKcgiru9c4yM18ueHrr4hWmbDR7C6tY2zKUlQquTzwx/lXXaXp/wATpA1zdPtfj5GlGT/hQB7o0iKOWA+ppv2mHOPNTJ7bhXicvhrx9NObi9kNwrc7DKCI/YAde361Wm8MeLZFP+hlkzgMu4MuAexP+c0Ae7+bGf41/OnBgehFeFjSPFltNvlhvmhUqMRTMMdOncioodZ8RaYRFNdarHwSEADgEDOORn8M96APeqK8LtPilrxkSGYwCQrv2zRMm0e/ua6nTfig77Beaa7DgGS2bzByM5xjNAHpdFc7pnjXRNUYRxXqJKf+WcvyN+RrfSVJEDI4ZT0INAD6O9FFAATiiikJA70ALRWXqHiLSdLLC8v4IioywZxkD1I9KXT9f0vVP+PK+gmOM4RwePWgDTooBzRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABWXr+s2+haRPf3LAJGucE9T6CtMnAzXivxZ11tV1a18PWe+TDBpFRScseAOv40AUfD+lTePPF82ramubVCNsbgMCOw9OPpXt9nZx2kKxxqFUAAADpXO+CfDkPh/R0hXl3O52xjJNdZQAmDmloooAKKKKACiiigAqlql9Hp1jJcybiqDkKuTVwkKCT0FeR/EfxfcXV3F4e0O6zcXLbGePDAdiCCD/kUAZN/wCI9V8feJZNG0WdodNjH76dAQR0zyRj1GPavRvC/gbS/DlikVvCrPnc0rqNzH1zVfwF4Pg8M6UIgTJPJ880p/iau0AxQA1Y1UABQKfRRQAYooqGS6gibDyKp9CaAJsVla34e07X7NrbULWOeMjow6e4q7He28rFUlViOuDnFTggjigDwTVvhz4g8BiTVfCt956oWJgeL5tp984OPwrrfhv8R28Ro1jqqRW+pxHDRA/f9wK9MkjWRSrAEHgg14P8QdHk8F+L7LxHpqxpDJIA0YQD6gdOtAHvKtuAPrTqzdGvl1HTYLlCdsiBgD15FaVABRRRQAySNZEKsMg14TfwN8NvifHIg26Vq0pdnx91jnK+mM4Ne8E4ryv46WLXXgoTxKDLbzrJnbkgdyD2oA9OtpVlhRgc5GanriPhjrX9s+ELO4aQvIF2Mx6kjiu3oAKjlhWUEEdqkoPFAHnfjz4f2OtW73xkliniG7zIkBbAHbHNc58PPGFxp+tTeG9SnMsasRaXDnHmqOwzn1r1y5vII0bzXVVA5LHAr56+JNsPDnjTT9SslIidlKOvRSDyue/rz69aAPo5G3qD606sjw5qMeqaNb3URJSRAwJrXoAKKKKACiiigBAc0tFFAFbUI5JLGZIQpkKELuOBXh3wndYvFmtabc7fO8zeFYc5BINe8P8AcOOteFJatofxw3hfLivSJAAf73X9aAPdFjVVACin4pFOQDUN1KYbaWRQSVUsAO/FAEjyIn3iBVG81zTrBS11ewQgcnfIBXzh4h8b+KNf197SK+e0j3lFjU7dpH6nGOtdDYfCaS/ijudR1qeYnDlVUDJ7gk5yKAOz1z41eHNOLw2bvf3A4CRDg/jXnkms+Lfibqf2eO3+yWBYqf3WVVfUk9T0/wDrVn6r4RtPCfj/AEvZt+wTSKhDqXOT65GBzivofTLWCGBPLRQMdhQBB4S0NtA0SCyaUysg5Y1vZAqB50RCSwGBXG+LPGkOjWMsguFj2jO88ge31NAHaS3UMK7nkAHua5/UfHvh3Sw/2jUoA6ZygbJ4ryG2m8U+O939mh7ezJ+a4uMjPsq9xXf+HfhjpOnW0RuIlubnO6SWZAxY49xwPpQBHN8aPD6k+Rb6hcjGf3VuTn/PP5Vp23xS8MzwCSW7kt2xuMc8LowHrjHT36V0UGhWFsoEVvGvrtQDNU9a8JaPrsCRahYwzKhyu5RkcY4PUUAWNK8UaPrW7+z7+CfacNscEj6itOS4jijLs4CgZJJ7V4V4u+HVl4WE2r6Nq8mmyKMxopPJx0zye1cTB428aeLbVNEgnlcr8ssiDLOM9WIHHTtQB1/xj+IOkalZLpVhH9qm35EwyAuCRx69PpXLaJoni/x7NaQXc9zHp6KoYlWRCAPTuceld34P+DjJNb3+uXUk86YYIrEgY6ZJ5/CvZrWyhtYwkaKoA4AFAHlenfAvRIh/pFxcOOcgEKCCc449Oa9A0zwlpOlIgtrSJSi7Q+3LY+vWt2igCAWsS8BAB9KlVAO1OozQAmB6UYHpS0UAJtB6io3toZCC8asR0yKlooA5rUfAuh6lcG4kt2jmJyXicqc4x2rm7v4R2hG+x1S7gnByGZtw/Hpnv3716TSDmgDya/8Ah3rJRxFdLKcD95Kfm4HGMDP+etY2nah4x8JsZbi1urm3UBXjPzIuDjIORj6V7nUFzaQXcLRTxJIjdVYZFAHlA+NsEF6IbuzZEwFJCk/N39gOnevSdI8QWGs6el5aXCSRN3U5xXC+NvhtHqjJLYfut/EgXAI989ef6V5Ott4s8Naw3hjTdQjuTdgB4kcv5fr6Y/OgD3XxP8RNL8PObcCS6u8f6qIcLxkbieBXmVx4x8ceMb1k0ZZLe23gDyU28d8sc812nhr4W6Xa20c+qxte3jANI0zs4yPQE13ltbWtogSNEQKOmMAUAeMWfwc1XUpEutY1yVpicsMb+vXkn+lZPibwXP8ADyS1vrPVbpYDwSqA5YHOCMgdK+hYriCVikUiMy8EA5Irj/im0cfgm6aRcncojwoOGz15B96ANPwTq11rHh6C6u12uw44xx27mukrlfh/A9v4UtY5EVCF4CnII9eAP5V1VABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSc59qAFooooAKKKKACiiigAooooAqahdJZ2cszkBUUkk15R4Mg/4STxdf6424xiQqFKbVyMY4z1/Kui+KmpT23h2W2gKDzxsYnOcHrjHSrPw60ZdI8PQRhQHb53Oc5J96AO0jQIoApxOBmgUY5oAWiiigAopOc0tABRRRQBn63ci00e6mJj+WM4EjbQTj1rxz4W6NJrOv3fiO7WM7mKRbVHH+feu2+Ld4bXwZMBHG+9guHzx9MEc1Z+G+mLp3hKxQRorNGGbb0JPNAHYxoEXAFOxz1paKACiiigDL13U10vTZZ2YDapPNeAya/rHjTxI+n2N09umCfMychRxxj616F8YL2W20CfbIEwuef4vYVz/wAOpdG07w6l9LeReaylmZ35XuR1oA841lfEvgzxFFanVy0sieYpVyARngH8q9J+H3xdm1C6+xawYxtGBIhwD065NeOeO/EUfiTxfNewybrYYSLdkAKPr0qnpDSWt7bnywQScYbryMGgD7bjdZEDKQQRkEVxfxS0WHVvBN6XQGW3QzRt02kVueFJZJvDlm8ow5jGQauavbQXml3NvcIrwyRsrq3QgigDjPhTqp1HwrbBiN0WU4AxgdOhPavQa8I+Dxex1a7sFuEkiDHYglDYXPXivdh0oAWs7WNasdEsZLy/uI4YkBOWOM47D1NaDHAJrwDxdcXPjz4iHSFYrZ2WV2FhgHPLEevTFAGzqPxqvri3E+heG7q5g3bTNIDt/DaP61yPij4keJdX0a50+/0IQRXKmMSbGyT3IB/Hv2r2/RNNstO0+G0hRVjiAAHrir17ptld25SaBHVieCOh9aAPHPhd8QtP063h0S7gkt5VYIHCcEn1A5Fe8RSCRAw7186/EDwQnhvVDrsChLNSoCxMcq3bg/QdK9l8C6s+s+F7K8dSrPGMg9/egDqKyfEeprpGjXF2zbQi5zWtXEfFSC4n8F3KW5+Y4zzjigDxXxDq3inxL52oAyw6cD5aNGTgehIzyCa4bU77VIZDb3k8m1lD7AeGB75966q48ciw8Ox6R9nDRyQiMhSQyMD1+hri9S1D7b5UqhVZE2YBycDj9aAPpv4Oagt34MtEVyxjyrcjr+dek15F8C7Ka28JiWZcedIWXjHHT+leu0AFFFFABRRRQAUUUUAFeR/Fy0bT9V0XXoY8eU5ilcYz1BX3PU165XC/Fuy+2eAbxhnMLLINoyeuP60Adfpl0t5psE6nIdAaluU3wOvPIxxXCfCPWxqvg+3RnJkg/dtnrxXfuMqRQB8eeNLJ9L12+cMFkt7xl256huc4/D9a6ew+J3i06Y89lo6PaQx4eRkbHAPOcit34reFmg8Y22rLBFLaXWEdXYcyZxyD2x6e9Fzf65daFLYWGgW9laeSY3a4k2AAjnAx2H8qAOGtb3xR438T2d1MGlEbJKViPyqoOMgZ69a9g8WeO5PDYs9NtPKlvZgAyOx3L6YA7nPWsb4PNaPplxAGVp4JWViMHjPrXn/xL1WWH4gXE7xIzQN5akkg4HTvigC9rHxB8VaBf+Tc38d15iBpIj/B7AjHvVnwvYaj8Q9fS+1NSunxkFYP4WI9fWvP7O0u9c1t+EaR2BkLHjH+RX058PvD66Vo8AZFD4GcUAdbpelwWFtHHFGEVRjaBWkAAMDigDA4paACuN8beO7XwtaeXGonvnB2RBgNvuf8O9a3inxHb+GdEn1CcFyg+SNfvOx6AV8/WcepeOteuLmOEy3EjL5ssg2rGM5A4OfyoAzb0+IPHOrNLKJ23Z89yfkiXP3QO3Tp717p4A8E2XhnR1ihiJdzuZ2AySfU1c8L+DrHRtNWD7OhJO6Q4J3N68k11kcaRqFVcAdB6UAKqhRgDFOorE8SeKdM8L6c15qM4jQfdXqXPoB60AbLOqAlmAArifEHxO0TR5TbW7PqF7natvajexPpx0ric+KfifetOlzPpWgZxHEpKvMvckg85rvPDnw70Xw+Ee3tVMw5MrElifxNAHOP4w8fajI/9neF47WNV3gXbks49iMAH2rPufEvxVtQssvh+3cAfMIjuz+TZzXsSxIowFFKY1JyQKAPH4vjHdaazReINDurORDgkKSCfyrtfDvxC0LxHEDZ3aeaesTHDj8K6Sawtp1IkhVs9ciuE1X4R6HcM1zpYk029GSk0DkAH/dzigD0BJ436MKkr5+Os+KvAXiu3ttenlnsGJVLnPyOOMZHY/417XomvWetWaT2sySKw6qc0Aa1FFFABRRRQBw/xK8Wjw5oyW9uUa/uzsiRienc8c1mfD7wU+nvLrWpYa/uuTxwg64Gcmum1nwXpuua7Z6peoZHtfuIWO3PqRVnxLcSad4fuGtreaWQLhUhByPy7UAYnirx1baLK1hbI0t1tyzKQREMdSM8/SvLYtR8RatqLz3V5ESzhYvNl2q6/wC7yMnPTPatbw58Mv8AhI5zrWqQzWrSSEm2cnp+hFdNL8JrCKB/sckgZnDAO5wv0oA6Pwnoh02JriY5nlUBjuzgAdM964v4iXuoeIvE9n4c0uPzIIWDXDldwVscZ9MCur8Ua5F4L8IlizNNtEMA5ZmfHFZPww8PtbWMusXiyfb79vMl8zg/l2oA73S7c22nwxMAGVACBxVygDFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFBz2ooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKQnAzQAtFFIehoA8j+KMd1qOr2NhDCH3Nkhmxx+dekaDaiz0uCAY+RAP0ryv4nGX/hI9IljRWj8/BwOc5H5V61pf8Ax4xk+goAv0UA5ooAKKKKACiiigAooooA80+MshXw7bKFDbpwMbAx/wDrV2XhtFj0W1RcYEajj6Vz/wAU4oz4RlmktoZjGw2+b/CfUe9X/Ad+L7wxZSblY+WAdvTigDqqKKKACiiigDiviR4VTxPoDQiOR5UPGyQJx3znjFfLeseHLnQbuSO5RpIgzKAHwwIOORX2yRmue1bwXomsySSXVmheT77AAFvxoA+NYrP5opUO5sj92BuOa9P+HPw7v9X1aLVL6F4bYPkApjOOePSvb7P4deHrSbetjG+37gYZ2109vaw2sQjhjVEHQKMCgBbeEQQrGowAMCo9QkSKwnkfOxY2Jx6YqzWJ4s1CHTPDl7czyrGixHk+vpxQB4/8IAlx4o1WaNsRpIwiDDJZSfX8K943BUyTgDqa8b+EFhJFDPeSs3znKq3JAPI5zzVj4g+O7xrkeHdAUy3U+Y5GUZx2IHpj6UAdT4n+I2kaFA4VzcyjK7IumcZxu6flmvCNRuPFUeuN4l0rw/cWkc56rGZC2fX/APUK9e8HfDDTLGwguNRt1ub0/vGaTkKevA/E16JHp9vHEI1jUKOgAoA8d0HxjqMUKi/huBdbctE8YTp/KtmT4iNLbSRxeRDOB0d84+uK7vUPDWmajzPZxOQD1Xr9ao2ngnRreR5P7PtvNcYZljxkUAeE+MvEK6pFLA95LqFzKoAjQYii56jjn617N8NLZrPwjYxSkbxGMjPSqviT4W6LrVqVigS2nUYjkjXla4PRPEOr+AddbStXQGAyEq2f9YpOAw6gHjpkUAe+jpVW/sYtQtWgmUFT2IyKWxu1vLVJl6OMgelWc0AeJeJvgdBfX013ZzkNK5YpkIFznpwe9cLrngay8KaHHDcxxtrN3KURPMDMieoXv6cetfSut6raaNpFzf3kgSGFSSSQM+3NeH+EBdePvHUmuXkSG3hYhI2G7YoztA464Oc5/pQB6x4B0uHTPC1lDDGUXywcHrzya6qo4IlhhVFAAUYAFSUAFFFFABRRRQAUUUUAFQXkC3NnLCyqwdCuCM9qnoPSgDxH4SSHTPE+taQ6vEySbhE+Mr+XFe29q8Q8SN/winxntbyOVxb6gAZVJ4BORxx0yPevbIXEkSsO4oA8++L1oJvCDXAVQ0EgbcewPB/nXD2fhHSbnRLS/wBW165MEZEjxyXAK57g/wAuK9h8W2B1Lw1f2qHDvC2364yK+fvDEOkarbXH9vSMyW2WUtOQBnqCAeuR+vtQBtaTrOk6J8Sha6GEktL1AjJbgAIwHU/lWV8V9GW18QNrE1s09tKgA2gkI3Oc8/SpIry01fxHpx8I6LO0Vq582QAKrDPU/TrzXQ/FuSWDw40bYVnUjGPzoA5H4S6TLqmqG5C/ulfLkqCD7V9IWdqlrH8q4z79K8o+CdtCNBWVRyxORjpzXsDOQvt60AWBTC4+b2FVJL1Ily7AAVzHiXxna6VoF9dLIFkjjbZ0OW+lAHmPjO+vPHPxDbSLFRLY2eEcknCt3OM8/iK9W8LeF7bRLbEMYDNy5AxmvN/g9plxI95rOoFlkvJCyqc4xk817fCFCDGKAJdvHFLQKDQBl+INdtPD2kT6jeNiOIZxnlj2A968S8K6ZqPxJ8Tv4h1ku+mo5EFu5ynXgAZ6Ditzx/d/8Jr40tvCVm5NvaMJLx19f7v4f1r0vw7oVroenpa2sYSNRwPegC/ZWENnGEiRVUDAAGAKt0UhYAckUALR3pokU9CD+NOoAKKKKAMvXdFtNc0qexu4leKVCpBFeCSrq3wo8RKsJa40x3AAkJ+QZ/lX0fXHfELw1Hr2gy/JukjXIGOooA3dD1eDWNNiuYXDB1ycHoa1K8K+E/iSbS9en8N37MFOWgL9cZ6GvdQcjNABRRRQAU1kVxhgCO4NOooAQKFGAAKpatqlpo+ny3t7MsUMalmZjir1cV4z8GXPi+7tYpbxoLGDLbUGSzHjnnH060AeO+Pdd1DxRP8A27H50VhYufsymEFAM4DE55Jx36V6R8MfHttr2nJazMiXsfyug4z7iu007wxp2maSNPgt08kLtKlevrmvD/G/hOX4d+IrTW9FaSOzdyTGgJ2nOSCfQ0AfRQIIyKWud8IeJLbxJosF7A3DLyDjKnuDXQigBaKKKACiiigAooooAKTvS0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAYooooAKQ9KWkPQ4oA8p+KER/tLRpASo+0c7VyfWvStN/484sN/CO1edfFaNo7SyuFk2vFPuBLAf8A167DwlNLLpMQlkEhA4YelAHRUUUUAFFFFABRRRQAUUUUAY/ifTV1Xw9eWjRmQtGdqrjJPbGeK86+FWoy2kt5o1yJQ8EmR5iBcZ7cfhXrhGRivF/iNp8nhDxBbeJbESRwyuRP5fOW9/rj6UAe0KdwzS1zXhXxRZ+INOjnt36qCVPUV0uaACiiigAooooAKKKKACvIfjJrjzxWvhuyaRprlszLF1C9uMc+uPavRvEGv2eg6ZNd3UqosakjJxk+lfPmhy6j8QPHf9qyNK0UUoxj5cLngfSgD03RLCbwt4LmuBExuIoSThMlsAgHArifhht1fxlfahcyyyPHlsSnjcTzgHpXtxsEn0uS2dcq6bSD0rwXXNM1X4c+I4NbgSSYSZN4GcFWUkdB2Pt7UAfRUIGwYPGKmrkfDPjjRdesY5LO/hdyoLR7huX2Ircm1uwt0LzXUaIBklmAxQBpUV5re/GzwraX5tRPLIB1mRMoPTmr/h34maPr+9UuYkkUn5d3UevNAHdHGK8I+OTJDrOkSLG5fDBnHCquR37fX2r0HWviRoWlWjyLqNpLKpwUE44+uM/lXhHiHxZH4x8dW15eMDptsAI3RSuR75HqaAPozwk06+H7UXMwlcoDvxjIqzrfiTTNAtPP1C7jgQ8DceW9gO9eLP8AFfV7uX7DoFjHFGija8rZd+3yjpSxeDfEviy7tbrVrgyZOWVmJQDqeM4BwcYAxQBoXWp6j8WNZeyspZ7XQIGwzKoPnng5Ofr79K9Y0DQLXQ7JYLeNQepIUDJ7nApdC0Gz0W0WG1gSNRzhRitigAooooAKKKKACiiigAooooAKKO9FAHlvxksHXTbTVE2f6PKC27OcjpjA+td34avl1HQrS4V1bfGCSp4zjmmeK9P/ALS8OXkIClwm5d0Yfkc9DxXG/CLVml0a402YAS2czIQD2/pQB6POgeNge4r5W8Q6Jp+l/ES5s5jLLbzzbmiVyig57k9e9fVcgJQ7etfPXxU0yWy8YfblTEbqG+Xg479/XNAHsnhnRbDT9NjS0hREK547nrnPeuP+MfhufU/C8lxbAmSD5iAccZGf0zXZ+DLoXvhqynByWiGeMVt3NulzA8UgyrAjFAHlXwckhPhtYhgSox344zzXomr38en24kkYKGOMnoK8sjM/gX4gS27tEumXpBRVwNnYEj6it74ka3pw8Kuk1ygkJDxKG+YkZweo4z9elAHBalquufETxHdWFhcz2WlWhKl4iQ0pzjr+dYOq/C7U4pEgs7uYhz+881sgj6d6m+G/jSw0PWbiDUJVSC7ffHIpyqE9Q3pXvNvLY6msN3a3Mbqw+UqQVagD57jvPGHgFh9te4+z7R5ZiQvEOehz0r2bwD8RrPxPH5DsI7tFBZOua6vULWxlsGW4jjZcfMGAxjvXzppd3aL8TpE0SJo7Vpx+7GUAOec4yMZoA+pVYMOKralcrZ6dcXDttEcbNn6D8afasWgQnrjmuN+LV89n4AvtkojaVkjB9csOP0oA5X4SWH2681PX5iWmu5my2zAIBPSvYRhVznAFcZ8NrJbTwlYoFAPlhjjuTXYzgtA6gZJUjrigDkPE3jqz01Ta2dzA964by1Ykgkdsj34rgb/WPFuo2VvLNJOEkILJaJuXBPdsfpivO/HUs+l+IZ0k8ouHYIyqcsOnOeKl0b4matpOiQqUimCsQc5+YDoPY/SgDes/iNrGl+I/ImnuGskc71kGWUZ6gDBwMdK958Oa9ba9psdzbzCTI54wQfcdq+NdT1mTWNflv58hZHLbOoUGvbvgtq0gPkuVCynjjrxxjigD3WigdKKACmuoZSD0NOpD0oA+cvGbJoXxbsbiByjtKoZuMYPFfQtlL5tpG+c5UV89fGtVXxbBNG2243KoVRnPIINe7eG3Z9GtixO7y1znr0oA2KKKKACiiigAooooAMjOM81l+IdKGs6FeWGdpmiZAwxxkVqUUAfOfw21O68J+Mn0G83QxO7JscgDcDwR65r6JikEkYYHORXhvxk8NvpuoR+JrVz5gYFUCDhgcn3NeleAtbOu+GrW8dBHI6AugOcHvQB1dFFFABRRRQAUYxRRQAUUUUAFFFFABRRRQAUUCigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooPSgDz34rWiXPhp3Eqo8Tq4JXPetDwBdC40K2bdlig3cY/SpfG1mb3wzqETAH92xGcdcVzvwx1JTp8FoxBkQYJ3g5oA9PooFFABRRRQAUUUUAFFFFABVW+sob63aGeNZEbqrDINWqKAPDPEHg/UPAesNrfhoS/ZWy00G75R9FA6V3fhPx/Ya1bJ50ghuMfOjHofr0rsri3juI2R1DAjBB715rr3w1b7c99o5t4ZpOGDIRge2Dj9KAPTEmjkUFHUg+hp+R614kqeN9HeKKGykdR8pZZiRj3pD4+8T2N60U2nSsq5BPPJ/GgD27Io3D1rxVvi7fRK/2jS3DKORG27Jzjr+tRz/FTUZYGFtbOJ84VNnA4/vZ65NAHtM11DAuZJFUe5rmta8d6RpNu8k1wFUA8txkjsPU15ZDf+OPEMa3kQjt/mICzIxJXjkD/APVWh4b+Heo6hqDXviV/tknVA4IVPoM0Ac/qVzqvxL1weTI66ZFINsbKBuP0NeveDPCkOhaeF+zrFK2d5AHzcnmtrTNCsdOQC3t44yBj5VArVAA6UAIq4GKpalpNlq1v5F7bRzx/3XXIq/RQB4d8RfhPpVnpl1rOm28ySRDeYbchRj1HHbFeJw2T3dzaeZcu6TuAElcjd6+o6n9a+2J4lmiZHUMrDBB7188a94Z02w+IX2ax08ukcqsIlB2xs2Dnjtx06UAa/wDwo7RnslkhuLmNzgsd2eO4HpXA6Z8OIta1iaCwvybaNjlzndgHoQQPzr6L1e9XTPCN3ckf6qBjgE56e1ef/DLQsPcagzNIJCdrOoBz36cnt1oA898EeBdP1Dxze6XqMTSxWpIGZB8xDegr3qH4ceHFVR/Z6BRztUkL+Q+tee6BaJZfGO+CMz7pSWIUbVyM4Jx1r3EdKAMu38O6XasGhsoEYcAiMZ9K0kiRBhVAHsKfRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQA2RBJGyHowwa8T8Pr/AMIp8Wp9KiMgguwSS4zuPUYPsK9urxT4qRDSPHeg6xDGVZ5AHcHAPIH8sUAe1A5WvMfjHooufDyanFbwyzWjZPmHGV9M5FekWcnm2kb+qg1neKdObVvDOo2MePMmt3VM/wB7HH60AYfw3uUl8KWjJkKV6Z7967M8ivGvg9q/lW8mizNtlgdvkPHfng89TXsg5X8O1AHiHxq1SEPaxR2iG7RxiVlG5Bntn1qh4R+FEeqQW99r1xcXTMAyQPISqDqB71Q8eadLJ8VYoL0vOkrxlW2cFc9DgEHnive9KtkitY1RQAoGMelAHC6z8ItF1VFMUP2V17w/LmuZtvhLr+hyl9I1yVU2kbM4wexH6V7mAKMA0AeFX3gTx3rkE8F/rZFucKqtnLDB5O09efyri/D1g/gDxqLPXrdM+Z+7nIwMHHzAntX1OYwe1ebfGTSLa48I/a3jXzYJkKv3UE46igDv9NuUubNJI2VlIyCD1rz742XGzwhHGIg+Zw5J52gd8fjU3wtuZf7GMDRukKN+6Ehydp5pnxasp7rw+xjRpFQEkHbtHB5we/T/AD1AOp8Hbf8AhHbLAH+pX7vTpXQ9RXBfC+/e88I2O+QSSKoVmxjOOK76gDwn4z+BNS1C/wD7YsLT7UDGI9qhiynvwOPxNeFXlpqFq4tbiylt2iXDqUIPPc190socYYZrkPEXw28P+JJZJbu02zOMNJGxUn0Jx1/GgD4/sd32sKkIdmGMNX0L8F9AniWfUJ7fy0ZsRluWbGcn9T9a6DTfgr4b02YyJHM2eu+TOB6V6FY6fb6fbpBbxLHGgwFUYAoAtUUUUAFNY4Uk9BTqp6rdLZaZcXDZwiEnFAHzv46Da38ULK0jZiZJgeuRtB9vpX0LpUPk2iLjGFFeBeCI/wDhIfifdXjqGSzVsOpyCxP696+hbWPy4VBOeO9AE9FFFABRRRQAUUUUAFFFFAGbrulwaxo9zZTxq6yIQAw4Bxwa8n+Et3Jo2saj4duE2SRyGRDn7w6GvajXjnjWOPwp8SNN1wQsLe7BSVk3Yz79qAPYgcilqvZXEdzaxzRsCjqCCKsUAFFFFABRRRQAUUUUAFFFFABRRjmigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKAc0UAFFFFABRRRQAUUUUAcx4sndNKu0RAT5ZIz9K4D4SyedFI8gj84SnJCkMfrmu88WuV066ZRkqmQM15b8KGuBrF5OwJSSXGc5GcmgD3sdKWmocoKdQAUUUUAFFFFABRRRQAUUUUAFIQDS0UAMaFGHKiqs2m28v3olJHTirtFAGM/h2xfrbx/lSxeHbCI5W3jUn0UVsUUAU4tPhhUBUAx6VZWJVPAFPooAKKKKACiiigAPIrznxR4Y1xtdbVdIKyFlz5TSEAMBxxnmvRefWloA8c1HRPiHqtjLY3L2ogniIfaq8HGNvuD17Yz36V1vgTwpc+GdDW1uZVkk+8SOxPOPf0zXa4FB6GgDxfQ4tnxg1ElSZGkJbKbdoxkYPft+dezqflFeR6TcxH4wasvlksBjzDn0HHP0x+FeozajbWluZbiZIkXqzsAP1oAu0Vwd98W/C1nM0S3pnK/eaFCyjr3/AA7VLpfxQ8N6kqEXqxF32Kso2kn6envQB29FRQzx3EayRMGVhkEd6loAKKKKACiiigAooooAKKKKACiiigArhfirpMeoeDri68oPPZ4mjwuWHrjiu6qjrMJuNHu4lfYzRNhtu7Bx6d6AMPwBria54XtZ1I3qgR19GFdSwypFeO/BLUvk1TS9+5YLgsp6ZyT2r2OgD5+80+F/i41nPvWOW5d48NwRJyM/nXvVs/mQqeua8V+MsX9k+KdI1yEojqRvZhuztPpj0NeuaFex3+mwzxtuR1DA4xQB5z8ZPDN/eJY65pURe6siS2xdzYHIxx65/OpPBfxW0i+05ItUuobO9iXbMkp2jI4PWvU5YlmjZHAKkcg14l8TfBnhzRbKTU4NPUXkz/KsZKj1JwCKAPUbfxloFyF8jVrNy3ACzKea2UuYpACrr+deC+HPhbZa/wCGob3dLZ3cy71YMWHXIJB/lWN4hk8W/DzW9OWPWptQixvMOSflGAcg5wDQB9M7ga4P4u7T4CuuMv5ke0Zxk7x/9eubsPjno4IivbO9t5ApPMYIJHbg1znijxZffEkxWWlWcyafG4Ylg2ZmHbjpjNAHoPw2i8rRYFdt8pHzHIPP4V1+tWEd/p0sL5wQQcHFZfg3SptM0WCC4ULIi845/nXTlQRzQB4n4N1mXwj4sl8O6gsiwTyM1rLK2c+2e9e1RyK6ggjpXCeOvCY1e03wuyXEZ3xupxyO2fWuV8K/ES/0WV9O8UAgRfKk4jPzdOD70Ae0UVU0/UbbUrVLi2lWSNxkMpyDVugAopCM0tABRRSE4oAUnAryj4weK/7P0mSxglKyMMHGO4+tdf4x8TR6FYHZMFuCCQNueB36182XKXnxB8ZQ21mHZHbEsyg4x3PPTjtQB6Z8DtFZdMudSYbDdPkADoBXtqABQB0FYXhXQY9A0iGziHyIoUZrfoAKKKKACiiigAooooAKKKKACuJ+KOhLrfg25VYEkmhxJGWbG3HU5+ldtVTU0Mmm3KL1aNgMru7enegDmfhxqX2/wnZklS0a+W23kZHHBrsa8h+D+puZ9V0x2/497liq7duAT6dBXrw6UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFHagDjPGd7b2VvN9oLbTExwBngCuV+E2mo9hJd+WVEkxZM9evemfFnV2hBsxcbDKMKofBb1GB1rpPhjaiDwzbsHlfeN2ZVw3PtQB3YGBiloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigApG+6aWo5shGIOAAc0AfOOp+KtQT4j6ymgQxzTSSbfMyxxjjGDx1Hb1rck8BeKvE0cEuqamXz8xV84U56AduKvfD2ztLzxbq99GdrySsGRmD55PINexxxIqqQOgoA87034V2NuwNzcTzKQCRuI55z0NaGr/DnRL2waKO2W2mVT5c8Q2lD1z+YrtyQv4V5/8AETx9YeH9JubSC6zqcqFIkVd2Ce59KAM34TeIL+8ju9JvJjP9icxiQgAnkjGB2GOteqDkV5Z8HdDmsdBN1OiLLO5c7VwfxOa9ToAKMc5oooAKZLKsMLyucKilifQCn1U1S3+16XdW5yRLCyEDGTkY70AeeW+seI/FM017pmoJZWyTFBCUB3KDwTnkEg/qPStPwJ4rutRnudI1Vw+p2rsJCq4BGeORwa8fk13xH4f0290dUS2MUuZZwuGUFh0PTjpxXs3gXw8ml28l48rTXN2RLJISeTj0J4zQB2tFFBGRigAooooAKbIu6Mr6inUUAeDac0nhT4zzWjs6W1zgICMBs9PXgYx2r3dG3ICO9eI/G2xmsNV03XreFgUdFeXOBkNwP0r13QL4ahotrdA58yNW/MUAcZ8YNNW48NR3oCbreTBZlzhW4P8ASovhRrq32jtYkYktTtJHQ57j05zxXa+JrBdS8PXtsVDFoiVBz94cjp7gV4t8K7oWXjK5s8ALPCHyWJJYHB+v1oA9+rxT4pw/2v4007THIEbKE+YE4JOSwHA/nXtanIFch488H/8ACT6Uy2xhgv05juWTLL7Aj2zQBo6JbQ2OlwW8WAsahcAdhXkfxLunm+I+l28UgHlhGGxcuGycjA9RWLr2s/EH4cQRW1xdxXNs7FY53G4sfTk5o8Faf4k8TeMYtZ1GJ8CQOZJIAOMEYHHFAHuNnoNjd2ym4tIZCy4O+MHI961LPRrGwjKWttFEpOdqIFH6VZtYjHCqnqBU9ACAAAAcYpaKKAGuiyLtYZFcH4x8FpqKm6tYF+0KwORxkZHX8BXfUhAIwRQB4Jpeq+IPA3nCGNbuwLFhb5IeP1Ht616J4e+Juh615MRuFguHH+rkYAhvT610up6Bp2rWr293axyI/XI5/OuGv/g5otzG4iaeMliwxKeCRjP8vyoA9GiuYpV3I4I9ql3DPWvJLX4eeK9IumbT/EDeSVCiOZmbA46e/v8A/rqvLoPxLt2VYtRRw2QX8zJXPc54/SgD1i61Ozs1Zri4jjCjJ3MBgV5t4s+N2haKWttNzqN2QQPJ5RT2ye/4Vhv8G9X1b5tT1uUO77ppASzP7e3Wuw8N/CTw54fWORLJJ7pP+W03zHPr6D8KAPII/D/jT4jX732pJ9jtZ2DYZcHb7D6ete4+C/BVj4X0yOCCEBhyWPJJrpYLGKDkLk9s9qs4oAUcCiiigAooooAKKKKACiiigAooooAKa4yhHqKdQelAHi/g+wm0v4parGXQBwSETAGM8ZUV7OvQV5neutj8YkYqpNzagZL9Me2P8a9LQ5UUAOooooABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFRXEohgZ2OAB1qWsXxBqMVlYyuzj5FLMO+PpQB8+/Ee+m1nxzBbQXhCq4Ux7yVUjuR75r3rwegXQLXoT5Y5AwK8K8NxR+LfG89+ke1FmAJKYORkjBGR0HevoywhEFskargAUAW6KKKACiiigAooo5zQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVk+JrlrXw3qEyffWB9v1xxWtXM+P7lbXwbqEjBDiPgPjGe1AHAeAtX0vRdIlubyVYWkmI+Zskk8nqa6a/+Keg6fa+c0xePgIUIO7Iz2PT/AANea2Pw21XxLbrNHqMVvaS/MFQu2MgBhjOOfr9K7rSPgxodl5TTB5nQ7yWxy2APTgcZAoAwNV+K+sa0VsfDekss0vy+dMwZR16bT/XrS+APh1dPqq63rayPcEhiLhdzbiOTkn1/GvWLLw9p1gQ0FqiMBjcBzWmqKvQAUAR29vHboEjUKo6AVNRRQAUUUUAFI33T9KWkb7poA+cPGEMraz4ykjjZo28tUkAxuIIyOTzjmvb/AAazP4Y09mXDG3QkZ9hXifiuCWzbxRbzxiMS3UKKAdy7C+QRgcen+Fe8eH0SLR7dEwVWNQD68UAatFFFABRRRQAUUUUAcZ8T/DreIfBd3DCm64iHmRD1I/GqHwi1t9U8JxQSxlJbQ+S2RgnHqPWu+miWaF43UMrKQQe9eRfD5Z/D3j7V9HuI/JincyQoBwQD19qAPX3UMpU9D1r5w15JfCvxHdIo2iQTboiicBCc4yMDnPT2r6Rrx740aPmG21OPeGJ8pynrzg4HXr+lAHqWk3QurKOQc7lBq8RkV518MvEBvtBt1mYCRV2uD6ivQxKpXduGPWgDxP49QJONGhOR87tuzx2HSvU/DNpHBpFsq84jHP4V5P8AF51uvHWi2zIzxqq7xztwzH0H9a9l0iNYrCJEXChQAKAL9FFFABRRRQAUUUUAFFFFABijAoooAMUUUUAFB5FFFABRRRQAUUUUAFFFFAARRRRQAUUUUAFIaCM0UAeS/EEyWPxF8P3/AJR8tj5YbHGSeefyr1W2bdAp9q82+LANvcaDftGWihuwHIXkA4744r0TT3WWyidehUEUAW6KKKACiigUAFGaKTNAC0Ug6UtABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIehrx34u6ndadpDWtvLB5l2+0/OAwHtmvYZGCoSTgYrwTxVKviz4nW1la2rSfZAUmcqQAPfIoA7D4W+HZNM0GFrhU8xgG+UDH4Yr0tRgYqjpVqtrZxxqOFUAVfFAC0UUUAFFFFABRRRQAUUUUAFFFFABRR0ooAKKKKACiiigAooooAKKKKACiiigAooooAK87+LFwjaRaae0TOLqbBYcBcDucEc9K9EryT4izw3viuztJ3k8qBA21T/GTx9e3pQB3nhawhstHgiiXamMgFcda36oaTG0dhErkltozmr9ABRRRQAUUUUAFFFFABTX4U/SlJAqveXMdtaSzOQFRCxP0FAHy34/vp08ba9pzOssVxKnlNjJQqwOOO/WvobwHK83hPT2kYM4hUMcY5AxXzx4ysZpdM/t6VAJJ9T52gjIK5GD+Fe+fDtfs/hSyRpPMLRhg315oA7KikDBuhpaACiiigAooooAK8Y8asnhr4r6bqqytEt4mJMKADjjk17PXnXxa0eO50SPU87ZLPJyIt5YHBxntyKAO+s51ubSKZTkOoIrm/H2mPqnhXUYY3ZHWEspUZPA549xkVP4Eu/tvhGwm3ht0QOcVu3MQlhdD0ZSDQB8s+CtAl1m8vI7TVrvT7qKT5WhkbH1xxkV3cWseOPAFwh1tjrWiD5WniXMiL6kdfrnP1rD0W1Xwv8V3sVkDxyllyOMt1/OveYkjuYFDKCD3xQB4B4h8YaT4w8YaPdWhkMcYVZdyYMZ3cZzwB+NfRGmEfYo8HIwK8G+JXh+10zxto88EUEUNwwEgWPbvweSccGvd9KwLGLGMbRjFAF6iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDy/41hf8AhHrNyrELcrkqM12/hh1l0K0kXODEvXr0rkfjDZJdeF0d5lj8qdW+aIuPTnHT61v+CJkn8LWRhlVh5YG4A4P580AdRRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAGD4w1VdH8N3l2WAKRkj59pP0ODzXCfDTS/PuLzVyXzdsG2tL5hHfn0PNZ/xW8RzX2rWvh7T5kZmfM2wZKgds9sntXpfhexNppMCuPn2DcffFAG4q4UCnUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFIWAGScCgMCODQAd6WiigAooooAZK4jjZ2OABkmvEReLrnje8v1dvIEnlcKGBGQP7xwcdx6V6d441X+yPCl7cq4SXYVjJGfmPt3rzbwDYzTamnKMuVllbaoPfGBjI6/5yaAPZrZdsCD2qamoMKBTqACiiigAooprOqKWYgAckmgBxOK5XxV40s/D1odrxSXLYEaM2FznHJ/zmuf8eePpbLy9K0SJLu6ugyK6PwhHY8fXj2rD0H4d3WuSi+8UlZHkXm3jyoB9yMUAVL34rX11dNBEyhAwQfZ87z7gdSMc8VkeIPEHjjWorqx0y3vXgKhWcw7fMUqR8vPAJ59a9osfCOj2USJDp9uoTG392CfzrZW0iXogoA+Y20rxdqnh86I2g3SpuWRDIAoRsk5yQOPb3rV/wCEm+IPha0gtLrSPLjwAjRJuA7fw5/Kvoj7NED9wUPaxOPmUH60AeB+G/i3rUd2sOqxMdkgSTfGYwR7ZGN3fBx1r3DSdZtNXtFuLaZHUgE7WBxkZ7VW1fwxpms6fJZ3dsjpJycDBB9QfWvKrvTPEPwvupb6zke+0IFfMiyWdBnBOPp7gUAe4UVheGfE1h4l05buylDqeozyp9DW7QAUUUUAFZ+tWLajot3aJKY3ljKq4AJU9jg1oUHpQB5X8I9Suo47/RrwtvtJiqZXAx6CvVOoryHxYsvhT4g6ZqsTWdtZ3L+VIRlWfd1yBwcHv9K9YgmE0IZTnIoA+e/jLZ3WkeL7TULGUxzSMHiOM4PQ9vWtLw98UtX0iFF8VaZJDakYjvIIiUY+/wCFb/xwtF/sbTtRa28429wcrkdxnnjkce1bHg2yttX8JWRuoIZAUBKFQVBx6HNAHm/jLxRZeLdU0W50y5ZofOZH38BSMYO0ivetIBGnwgtuIUDPrXinxM0Sw03XNMjsLS2t8/OdgVcYOc4yD29+le06Kc6ZAc9UBoA0aKKKACiiigAooooAKKKKAADFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUfSiigDzz4xO0fgtyqb8zIGG7Ax6k1Z+F8jP4TtQzqzKCp2n/OayvjRGZtBs4hgbp8klsdB9ak+D6NH4bKFw+2VuQc96APS6KKKACik5zxS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFVdRuls7CadzhUQsTkD+dWq5/xlfJp/hi9ncxhQhB8w4Bz2oA8k8F2yeKvHWpalcbpVgm/d73BK/gBg/WvdbdAkSgDHFeQ/BeGWTT7i7eCOKOR8LsGA2O+MV7Eq4AoAdRRRQAUUUUAFFFFABRRRQAUUUjEKpJoAWiqkWo20t09ssqGZBlk3cgVJdXUdpbSTyECONSzEnGBQBPRXO6N4y0vXBKbSUERyGMnPUj09RW4J49mSwxQAT3MNsm+aRUUdSxwBXOap4/0DS7d5pb+JwvQRtuLH0HrXnfxJ8RKPEKadNqTQ25AdlESkBcY69T+Vc79r8JCxVhO1yrEny/s+GJ5HpwPpQB2v8AwuqzlvUWK1YwyPsUscHHqeMAV6NZ6zb3VolwsiFGGQQeK+avtr6lo9zb6d4ftlaAlppiuxVAPB4Pp710vgPw5eeIdPQ399J9mic7YY5flP4D3z3oA9suPE2k2wbzb6AMoyy+YMj61x918TJZbsw6ZpjXSbgBIGJyCOuAOnar1j4C0+2uHmkkml34JRn+U857dR7Gt9LSzsYRHBDGgHACqABQBwe7xv4gs5J7i7XTLdSWCRIVkwB7/wBa1Pht4ludV01oL6ZpbiJuWbOWUnjtWxrniHR9BsWe+vYow3CpnczE+gHJrgPhc8S6/fwwF9hYn51AJGeD7fjQB7SORS0i/dFLQAUUUjHapJ7UAeV/GG+YwWenoVy5LEOpwc8demeTwa0vhzpX2O3MmYzvUNhMHb14Jx/n2rj9fnbXvHM91JDG8MJEEK/aVUuOTnrkfQjnPWvXdAtVttLgVYwmEAxnP60Aa1FFFACEgDJqJbiJujg/jVbWdP8A7U0m4sxK0RlQqHUnKn8K8O07w/dW+t3WjT6xe2OoRHfFJDMQrrnjIxgmgD3ozoELkgKOa8l8T+NtT8Q6tN4e8MxB40Pl3VySRgcggEdOnXNc54u1LxHoiJpdvrD6ks6hWikwJFP+8uDg4713/wAP9Bj0/Q4M2yQzOoeXGTljyeTzQBB4S8AQaXOLy8PnXjc7j0Ukc4H9a9EhhWNQAB60yJFUnjBqyuMUAKBgYFFFFABRRRQAVFNbxzxtHIoZWGCD3FS0UAeSa1pl18O/EA13TC/9iXMoF9arjERI4dc9s4GK9L07U4L+zS5jkVkdQwINS6jYwahZS21xEkkcilWVhkEV8/SXmveEtYuPC+nXiRoZMQGXn5W6YGM/5NAH0Bc6la2ah7ieOJMgbnYKOenWn2t/bXoY28ySBTg7TnBrw7VtBvpNLfUPEWtXE8MKgvChChm7AfnW18GrGa2tby7cSJHcy5RWYkY9RkUAewUUDpRQB5/8WvD8Gs+FWnaKdp7RvMiaDll9eO44q98PNdj1vwvbTAneqhXzwcjrXVX1nDf2ctrcRrJFIu1kYcEV5J4KR/CPjXU/D0sEkcUrmW3kLYUr6AE/XpQBv/GOVY/A8j7CZPNCoAMnkEVZ+GULR+DrFGCg7OgBGD+Nch8YNWGpXWn6BbqZn3ec6xjcQ38PGc9M/nXpfhayNrotspi8tigLITyDQB5f8bLVxf6RMArLlh8wBxzz29xXqnhaWOXQrVoirL5ajKnjgVwPxwQf2HZOygospzxk9Mjt/hXXfD9ETwpZLGyFfLH3elAHV0UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUmKAPNPjMsT+G7fdnzFmDIApPI9x0pnwfR00B1K7V85sEfxCofjXPGmj2IberCYkOvbirvwgj2+E4yQd29ixLZyc9aAPR6WkxS0AFFFFABQaKKAAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABXm/wAWlZtDcpH5jKjfKS2PrxxXo5615l8YHm/sZUhWVmPVVk2oR/tY5NAFv4Tqi+DrLbt+6f516EK80+EOf+ERt8ED5jwAeOenNelgcUALRRRQAUUUUAFFFFABRRmomuIk3bnA28nJoAlqOZgIzzWBf+NNIs96JP58qruKRAnA9Sewrkrz4g3+t2EQ8PabPLLOxUuVIWMDuSwAIP8AWgDP0W6ki+MupxeYTGYQcE59Oa9N1VPP0e6Qoj5jI2vjB4714Jol/feHviy8OrzJJJd91YkDPTrz+Fe/b1msmBPDLz9KAPmbTfFcvhbV7y1SwWacy71WBvl/QH07V2tm3jfxnEgmzp1ky5ASQo2fw5I9jXOaBollB8T763uIZfLVmMPnemete2WWraRaQiM3tshTjBkAx+tAHhPjbwTNot3DLPPJco4DMztkgjPrk11HwxsdPf7VaTWcBuYHJWYrkspJ55q38S9d0rXLGW10lDeX0Q+eWGLcI17/ADdK4nwbe6ydQaPTGVJLpELO7AcLwcZB54oA9O0yytbXxXrWmiNAtyqzLhcDBG0/qKx9G1vSvCGuXkN/qJhP/PGViR16qCO/tWYbPxNp/jHTNT1W9iaGV/s+Y1yQDkgE4Gc/StDWdN0qXx5BLewLJI7BQZMkYwMYAXHX1JoA3n+I91qkgi8OaNdagp+UXGNkO76+lT2/g/xHrMjSa7r8qwSEs1paDywB/d3dcf410YutM0PT/MnmgtoVzjOFHr0rJk+KvhqEER3M0zBchYoGO76cUAaGn+APD+kuJrXT4VkXkOwLEfQnOK5HQVTTfipq1qN7ediRSx+6MZ49smr8nxM1G+UnR/C+pXK54dwEUj15rl77UbmHx9puoahbyw3EqKWgXDFeSPT0x0PagD3RDlRTqhtn8yBT7VNQAVm67qEel6Ld3chQCOMkb3CAnsMngVpV5j8VNf8AIW10qEh2d1aZNxUhe3Qjg4OaAOQ8FRDUPEELgPsLmVcOGKduuD2K9MV7zAgSJVHQCuD8BaZDFEZgT8p2IrDhAOwJFd+OnFAC0UUUAFcV468M/wBq2RvrQtFqNspaF0bGT1wfUZArtazddkEGi3kpO0JCzZ9MCgDxPwhZyax4imk1W3mN1j995uDHnjgD8K9cvb2PQtFuLxkysETPtHHQZrz74YWNu9qdSgYv57YzwMY7bQOPzNdj41uFg8GalJJvCLAc7CAfzNAHG2fxusJ0klu9Kv4Ykk2NJGnmJn/eFdBp3xc8L3UzwNf+QV53XCGNT9Ca4X4UGCw8Jahf6gFW2EzOWYZOBjr610X/AAn/AIFv3CSXds2cDEsOPzyKAOoHxQ8JZCnXLMN6b/fHWrI+IvhYrIw1uy2oQCfOGMkZ4PfofyrFtrTwXc22YrfSWik9FjIPf/Cnf2J4JtY5J/selRqWy5KIBkcf5+tAFuf4seD7eTy21q3d/wDpmC4/MAiptG+JOha7q406xlleRh8r+SwU98Zxx+NRWemeH95WwgsVdeqxIufxxXC6dMy/Fq6tYGMO2UElTlXGwcY7d/zoA9xByKKZEcoM0+gAI4rxT40aS9vPZ6xbrl9wUgJkgqcjB9TyK9rrhfilaNdeFHERAmWRSjZxjsee3BNAHnD67/wnc1jpNlvWBU33RIHJIIA/D1Br2Dw9pkWnWMUEYCrGoVceleH/AA2ntLTxhc2yyjM8e9ADu7/MCfXJPbtX0HYY8v1IoAvDpRRRQAVx3jTwPF4pNvcLcSW11bEmORDz/OuxooA838IfC+HSJTfavMb/AFElSJpDu2hegGf516MqBFwo4p1FAHnvxYtPtXhyFt23y51xlAQSeOc9B/jVX4Q30s2jTQNtaOGUqhXAAHoAO1dL4/sxeeD75TH5m1d4X6enofeuE+DUuXvI4mYwrtABHT29PyoA9iooooAKKKKACiiobm6hs7d553EcSDLMe1AE1FVbLULbUIRLbSrIh6EHNOvbyDT7SW7upVigiUs7t0AFAFiiqWnarZatAJrG5jnjPdDmrtABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUdqAPF/jleNBJpcaumCWZk4J+uDXbfDe0a28JWYdcOyBiMdM1wHxlVo/ENjcu0fleSUwRk59eOccivTPA0bx+FrFXOWES8jPp780AdLRRRQAhApaMZooATvS0UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVwfxMtJrnSAVV/JXPmOjhSo+pI/ka7snArnvF9rb3+gzxT7igG7Cru6e2DQBw3wauBJpt1EpxGkxCLvLEfia9aByOteEfCDUxbaxqGmSSEYkJVPTBxjNe6xnKA+tAD6KKTGKAFooqOdmSF2RC7AZCjvQBX1DU7TTLdprqZI0UZJJrgr74waZHOLbTrC7vrgttCRgc/1/SvOtUE3iTxrfQeIdRksbVGJjV2UfLnkZ6dq7Gz8R+DfDQW3h8vzM8vDHuJx3LAUAS3XiXx5qzltL0ZrOM/dNwVXH1ByT+n40yPwn4kvZmk1zxISjAhooolGR25I/pU4+IjXpcaVpF/cKoBSQQfKx9Ac+9Z6aB4z8SytJqN4dMtpD/q4SPM2+nGf50AXDpHgnwlHvu3i8wNuPnSF2Lf7vr+FWU8ZtdkQeH9Du7xFUfP5flIue3zY/StPSPhrotjJHcTxPeXQOfOuWLnP0PArso7WKJcKgH0FAHz9438NavJbp4iurGODU42DmKIl1I4611nhb4paPcaSYr68WG4iUKVY5LHHbjn0xivRNYtoprZw2MY/CvMtW8GeFJ2FzfS28Euc4QhS/Hp1oA4Oy0uXx18QdRvIr27istxCSAkNj0Gegr17RfhpoFpaos1kty3UtcZck+vNYGjap4X8N7IrF5WL5YADG4/jj2rbuPFfiC4AbR9CeSFhlXmO3I+mRQBa8Z6Tb2vgy9t7CBIBswPLVVCjue1eN+DtThXxDYCOVwI2MZQnqCOpI4659K9HvdI8Z+IbVk1G+t7GM4HlRKSGGDnPPvXjd9oKaL4mls4L5N1uPMGS3BHJBwP5UAel+O/GWku1rp9tOkk9tcI7gAEdcYBPf6VY8c21w8NtqFsVRyiv5knKoQR6DI/Ouc8vwld+C57lvsS6iyNIN8g37/bJyPapdQ+IGlXPgizgku5ftS7VkRODx9QQelAHaeGfh/a6hHb6prN5c6lcyKr4mc+Wp68L/jXodro1jZoFhtoox/sIBXl+h/FPRLDS7azg+23lwsagKkeWbnHU4FS3XxcvJJ0j07QLiXcQBubJ6c8KCOPrQB6p5ESJwuBjHSvJvigbaz1/RJ0cPcyEoITHv3DI5HzDHWhfEXxC1qW3gg08WAlJ3zGHIC4HPJODz6c1b0T4Uyyat/aviTUJdRuQcxrIxIQ/Xj9AKAPTdLZmsIS3UoM4GO1XajhiWGJY14CjAqSgCG6uI7W1lnlYJHGpZmPYCvn24vT4o8Xz6izE/vSIIyu0FQMDkjn1/HivQ/in4ol0bS4rS0lCz3DEMuAcpg5HPTPSs/4aWAKyu8SiMgMnyjofw9jQB2vhvTG0+wijdmb5QTuYsQfxroBTEUKoA6U+gAoopkjlFyBn6UAPrnPHM8UPg/UvOdkR4ShZU3EZ46d+tb/AJq4PPSuE+Kt3Evg6VXmMcZkUO69QM9vf8qAIvh1ZPbeGrUSPIzkE5k4JGfTtxXQ+JNF/t/QrnTS4jM67QxBO0+vas/wxIkGj2sfm7isa8k9eK6MXETqPn/I0AeM51r4cyHT59Pn1XSHBc3EKEsgx90j/PWqXhqLTPGfjiW7+wwrZRw+WiPb435554xkf4V2/wASfEAsdJjtLcxtdX7+Qis3OD1PHPt269RWx4A0KDSNGijVVL9SwAyc80ARx/DPw6hEn9nQjb91RkAV538QtK8G6DIJZdPieeQlvLDN859AAe9e63MyQwMzEAAc14qLW28X+OzfyBHsrFikasvV88k888jrQBwnh3ULXTddj1WTZpflg7bS1gZ3de4Zj9K7vwDBdav48v8AXZrWWNJC3lF4tuFyMDkdce9ekRaZpRbcbaAnGCSgrRtmtYeECLjgYxQBrJ90U6qa3kQHLjripPtcIGd4x9aALFZet2y3ljJASV3DIYHkEcg1NLqlumR5i7h2z0rC1fXI442+Yb8AqM9KAPm3SZF0bxcrAqlzbam0ZPHKscdvx7mvqzSpBJao4OcqDXybPJ9o+JUplYbZLzzPlXgnqBX1P4dk/wBAjz/dFAG5RRRQAUUUUAFFFFAFe9hFxaSwkAh1K4PuK8Z+HuoDRvGGoaTcmPJk2qQ+45Hp6D+Ve2kDrXgviBTp/wARr2Wa4hzHIjxiRMMwPIUEKc9x+VAHvSnKg0tVdOuVvNPgnT7roGFWqACiiigArm/HNy9t4XuDHEZTIQhQMQxB9Md66SuR+Icbv4ZZgsZCSqx8xsDrjrketAFD4d232fTW2zq5X5CgUKBj6d/xNVfi7qjWvgt7UqfMvJFjAABHBzznp0rU8A2wTSFm2Ro0h+ZYzlVxxgHJ44rj/jFdS3GpaXpUUe5TmThsHOcD69KANf4R6fdW+kNc3U4kebAwFAwBx1HWvTK5jwNAYfDlqpQKQg4H+TXT0AFBFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSH1oA8T+MqouvaazJbFShDF8l+vtz+NereHih0e2ZM7TGvX6V5h8aIpFvtLnSKN1ZthLqeOfyr0zw1ltDtsjB8sdPpQBtUd+lNA29B1p1ABRRSUALRRRnjmgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKgurqG0geaeVY41GWZiABU5rwj4wa/dXepR6PbyuIN6q8aKQWPc5yOPwNAGx4w+LWyb+z/DLRXE4JEs+Cwj6dB3znr0rhxrHjHUUkZ9Yvyzj7hhUJg+5AH4Cuv8LfDwS20LXcKRQjDBAoDk+7D/APXXp1jotlp9qIoYlUfnzigD5z8Gi80j4g2y3VxuLyfMzIVLkj3HT3r6ftW3QKfUV478VtLj06+0vXreGMGCZRK5YcDPYGvU9DvY7vTYJUZWDoDwfagDWooooAD0pMcYpaKAPEviz4Yij1O11QFdpkBcSMcdeevQV1nhbwzoMUYubWygDSLnzMbiQeSMmuj8VaFb67pEtvNgHGQ3oa8e8JX+tJd3ujaZfW5WGQj5uGUZwSvUUAe3w21rBHtVEA9B2qG81Ww0+ESXFzBEvq7gVwI8NavNI0d5rdw8EmAYwSQVyCRmtGHwVolr5kl2RMjYOJmGF9/8aALl18QLfyS2mWNzf9iyKVXPpkiqwv8Axlq1xsSG3021I5dxvk/AZon8WeF9AgaCKWMmM48m3TJz2GBxzXN3vxWuZ9W+waFost0+4AOc4YevA4Ge5oA3JPB+oXasuoa5cyK3UKzLx6dcUyDwPoNpGBM7yhQBiaclfrgnHWsWO0+IfiC5lF2ttYWrjG0sSR7jac5+pp9l8Ir1rZ4b7XLl0LDITIBwc85JoA2pNY8IaBCR9otcx5+VDvbjHHH1H51i3fxStrlGh0Cwe6udp2qyt17cAHP510Fh8JPDtoYzJbvcFOnnyFuevTpXV6f4d03TVAtbOGED+4gFAHjsl18UdaAEFrHZxbeRLhCx7+4rgvEXgXVrDVVn1u9jfdhpJizMOegG4V9ZeSn90Vk6x4ds9XUCaJMgbd20Eken0oA+XbbRPDlvbD7Zfme5Afb5KjYcDjr7j8aqaUthBZXcd1pU0jg5glVScg8AcYyPx719KWnw50KCOVJLOOTzl2yZUDcPoOKcPhv4eimgkgsUi8kggISAR6Edx/hQBx3wz8K29zZPd3+mQFyf3TPGNwU846dK9UttKtLVQsVvGgHQKoAqa3tYrZQkMaogGAFHAqxQBGIY1OQuKdwCB3pxooAKraheR6fYy3UxIjiUs2Bk4FWa8o+K3ifJTQLRgZWIknBYqCvOBke4z+FAHD3d+njLxnLqcgmMcbKsCgj5QM8EZ/XNe7aHYR29mjrGFZlG49z9TXC+BvDENvOlylq8cW3I3OOp9ABwK9QjQKuO1ADhwKWiigBCcDNee+MPiMvh/Uo7GK0M0kgIyX2gcZ/pXoTfdNeJ6pa/2z8UDHgPHbgvknIDdP8AOaAMK+17x8JprmVZhbyDMaoGPr2U8dR37Vy+qXvjjWbGa0ZmmhdvnUfxcdOeR34r6YttIgeGNpY1JxyDUg0W1D/LDGM+goA+aLN/H9jbpFGs4xEMblx5ft78fWtiLXfH0VwjCCd45F2urqMocHnPf2r6EOmW5/5ZLgjrikGmwbcbF46cUAfKF3qPiTU/FVvDfmZ7mIkxgpjHuBX0x4ZhuodKgEoIYICQTzXAzWUP/C6yko+VLQFBt4J+ufrxXrsEYEahQABQByPj7Urmx8MXssDhJFjPNeK6NofjR9EtpNNMcSF/Mz0J69a9S+Msktt4OlaEZy6hsHB69v0q/wDDvbdeFLORkIJXJDdc0Aed/wBjfEt7YPJdRZcD5QOR9SPp+tUy/wARLOZYzpd1LKON6sChHQd/xr6ISCPGAoxT/s0eANo4oA8Js7/4lNEY5fD0JZl4LSbdv15q5DefEWKMJNpER7ZWQADj0z/WvbFgRf4RTvLT+6PyoA8JudW8c2r7W0BpQevlycZzXP694s1l4pIbzQbyKQowRmhbHTnJHBr6UaCNhyi/lWVqenwPA++IMu0kj2oA+SrQ30fiG01K3hKOyCQlssuemDnp0r2fw58Tkt4xBqto1s69XU71PuMVS8Gx6drV3qcEcI8gTYVJFBPI5FdXd/DjRbiPzFs0VwSQUJXn14oA67TPENnqFss0NwjoTjIP+cVso4dcg5ryWXwheaPbtJpt1KSSDsOOfqa7nwnqMt3pyLcLiZRhqAOjooooAKKKKAAjNeUfFvSHMdpqkEKtNG2xpCGJA4I6ds16vXI/Ea2a58I3Zjj3vEBIFyB0PuMH6UAWPAmof2j4Ws5eM7AOPaumry34RaqG02TTnJ82JskFcbQexHY+1epUAFFFFABXPeNI5ZfDF2I7eOf5clHJHA7jHJP4iuhqte2iXtpJbuAVcEHIzigDkvh/qIuvDsLi3MK5ICBiQADgYzziuL+I3max44sbWCN3+yBASgY7SxyT6DitGK08X+Ebqa3srAajZs+UkMxyoJ9McU3w14O1O71+bVNbt385nbLeeQp5zwuM45xgntQB6RoVkLHSoIB0VABWnTI02IFHQCn0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABQelFFAHjvxwQQw6ZdFJXIkIAV/l455Fd74Ju1u/DVnMq4DRg4Ncn8cNPmufCUV1Ark28uWKdlI5P+fWr3wm1JL7wjbAbgYhsO45PHrQB6HSZ5xQKWgAoopMc0AKfakIBHPNLRQAUUUUAFFFGaACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK828beBr3VdSj1TTzB58TBgZFyQB1AFek0UAeOx+PtbsporOXRXEiD96VGR+h4/GqsnjfxRqTuLeMWq7tuBAzsOevQ/yr2GXTLKWTzHtozIP4tozQmnW0WPLhRfooFAHher+G9f8bRyo9zOIkXhrkEbj6hVwMj3rY+E3iGaC4m8O33Fxa/KuZd+QOPWvYvs8YHCgV4j440O98HeMIfEGjx3LQ3JJuBFGGVfrigD3FG3AEU6ua8I+JIfEOkx3MeVb7ro3BVvSuloAKKKKAGsoYEEZB6ivHPEGg6loPi+XVdF04NCRl1xhMHk7RnrmvZaaUU9QDQB4TcQfEbX7mGSFBaQN95CxRQPww3b9a1D8KdY1VE/tPXHAXHyxK5Hb+8x9K9iEarjCgYpcAUAcBYfCTw1atulshcNxkynIOPbpXXWOh6fp0ax2tpDCijAEaAVpUYoAYI0AwBin4oooAO1FFFABRRRQAho60tFABRRRQAUUVXu7uKzt3mmcIiDJJoApeINZh0PR7m/l5ESZC56nsPzrxjQ9Hu/GHi+bVL5JGCnzFkU4UHsFIzkD19qb4g1m58fa3JFbS7LS2YJsGSeTxwOpPH0r1bwl4fGkWYLyySSOASXxx7dPrQBuWVosECKFwQMVcoooAKMUUUAMmbZCzHoBmvIPCPl3fxB1KdVfjJwWyFye49eK9P8AEF/Fpui3VxNIqKqHlumfSvIPhFP9p1jVZWDbnl3FuMHnnpwKAPcEA28UtIn3RSlgo5NABikbgU0zJn7wp2QQDQB4/wDEMTaF4/0TXEJMMw+zPnO1ee/1DcdOler2T74FPqAa474q2P2nwXPOhZZbR1nR1AJGOp59q3PCuppqOg2VxGxdZIVO4jGeOtAHP/Fm2abwXeSAHbFsY7Dhh84yQas/Di0S38K2UaoUCoDtLbsZ56961vGNi+o+EtVt42KyPbvtI6ggZ/pWd8NmR/B9g6xGMGPBB7kcZ/HrQB2KjApaKKACikyKWgAqlqcRlsJkUgMyMBn6Vdqrftts5W9EJ/SgDwT4TK0eu6gjAgo5UhjXvEaAQ7cdq8O+Dn+k6jqlwY8K8xwce9e7oMR4oA5vxX+48NXswk8po49wcdiKh8B3Au9DgmLByRyao/E+/ay8FagVYAsmOe+fSmfCuPyfCdqVZiGG7a2cjPbmgD0KigdKKACiiigAqvfWyXdnNA6grIhUg98irFB6UAfPvhidvDHjiS0mkliHnmJlcEKeeAOTzXv8T74w2eteI/FfSYNH1qHWVlECS8gsxI8z2UeuBz+NeieANei1zwzaXCS+YdgVj/tDrQB1tFFFABRRRQAhUN1FAUDpS0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAc546sH1HwfqVvGxVjEWyD6c4/SvMPgtqRNxeWRLbVwwDBvpxkmva7uPzrWWPOCylcjtXz54EaXR/iTcW01wCzyOjKAASc5BNAH0SvSlpkZyo9MU+gAooooAKQjNLRmgAooooAOlFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVk+I9Gg13Q7mwuE3pKhGM457VrUY4oA+c/BfiGXwF4hvNH1RrnyUIGWT7p+p7V9A2N7Fe20c0TBkdQQR3Fcj478BW3iW1ee1SKHUgPknaMNnHIB9q5Hwb4svdG19PDusTOZvuqHQjn2JPT/ADxQB7PRUcUqyJkGpKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooqte3sFhbSXFxKscUalmZjgAUASXFxHbQvLKwVEGWJPQV4H418Xaj4u8Q22l6Y8kdirMroCVYtnHzDg+nFL45+INx4kv4NM0iO5k04uVmaIOhJz6gdOD+ddd8N/Cr2gnuriMxrI2FgOcLjvzzQBpfD/wAGR6FYh5Ubz5Tufcc5x0/Cu/CgDApEUKoAGMU6gAooooAKKKKAMPxcJD4avPKkEbbPvHtXl3wbtDDPqEhlEpaYkkZwDk5xXo3jiWQ+Gr6CKJpJHhYqB3IHFcJ8G45Psl28vMhmJcbQMN34FAHrk0yW1s8shwiKWJz2FePajrmveLfGFzpukai1rZRxDLREOOfUjoecjB7V69eQtPZTRKcMyFQcZ7V4n4R1a28I+JtTstbZbWW4lBjkdcKevBP+cfhQAzW9D8VeEbVNSk8TXVxaRuoKc888Z56Z6+tet+GtTOqaHa3LSpI0iAlkOQT7VU1q/wBPfw7dSyTKYREzblIPAGeOtcp8HWnOhzNuU2jTsYAo4A/T+VAHomrWq3ul3Ns4VlkjZSGGRyMVwPwnuh/Yk9gH3LaTNEDjjHbsOPwr0lhlTXlfhaVLD4k6/pkXl+S7B1WM8KRwRjHB5HQmgD1G5iW4tniblXUgj1BrjPhur2Wm3WlzzCR7S5kRcEcLuOOB0rtVwYwfavOI86N8WpY12+VfweZtwAdw6njrQB6ZWdrOtWWh2LXd7JsjX8Savo25Qa4D4qC8/sMPDFGYF5llOMoM9skdf6d6AKFt4/1nWLm4bTNN821jDeW6xs24joMkgc/pir+k/EbfeW1hrGn3VldTyGNd8TBCeoGff8a2vCsNmuhWgtFUReWMAdq534ovbLosKji6SUSwlACysvOee3r9aAPRUkEi5HSsjxXP9l8K6rP/AM87SVumeimn+HbmS90O0uJV2vJErMPQkVS8cyNF4N1hlOCLSTB9PlNAHl/wMgB0+5kKEO0uc8jPHpXuJ+Vc15D8F4VGhM4i2lnI3HOWAr1xs+TnvQB5p8X5RH4QuEL4yR1HXmtP4YMW8J2I5BEYBB7Vz/xjmK+HBGzEb3AI7n6cGun+HSGLw7aoChQINpXjjFAHbY4paKKACiiigAooooA4/wCIegnWfDzNDEJLm2y8SEAgnvwa85+EesSWmtX2jysE+YyKm3b7HA7c/Wvc5oxLEyH+IYr5/wDFulXHgnxqNZtgxUsgLbc71P3iTwBQB9AowZQQadWXoWpQ6ppkN1A4aORQwI961KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAQjIxXh2qA2fxnhR7ss7Hcq7AAqkdM17lXzt8X0u0+I+n/2WwW7mVVU4OQ2cfyoA99W9giiDPIqjHc4qW3u4LoboZUcf7JzXjWn/DDVNaTz/Emv3s5PIhjkKoo9KVtJf4Y+I9ObTr6eXT76TypbeZ87T6g496APa6KjhbfEr+ozUlAAeKTrS0Y5oAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKO3FAAfeuC8f+Ax4jNtqVjItvqVo25JMZ3L1wa7wccUYoA8h8H+OtU0/Vjo/ih4I2ztjn+4GPHBzXrFtdw3MSvFIrqehU5Fc34u8Ead4lspA9tD9q6q7L3968tutY8SfC55be5MU+mn5rchcKvP3R/nvQB77RXO+EfESeI9Dt79MjzFGQRjBroqACiiigAooooAKKKKACijtSbh3oAWioZbqKEZdgB6k1mX3ifSNORnu9QtoQoyQ8gBoA2aY8qRjLMAK8t1T406YJJodGs7nUnjBLPGu1B+J5x+FcVrV34x8YQXb3V+2m28OcWseUJOM4zxu498UAer+KPiToPhlCs9yJrn+GCH5nP19PxrxzXfFeqeOb+Czu9Ri0+ynkA+xrLhth/vY5yfetT4baDp955iTwv52AxaVQTID33YJro/HfgJ5bSPUdGRUuoCp8uMY3gf4A0AbfhHwdBpUcJR1EaA4RR97Pqe9d/DEsaAKBj2rzH4a+LZdVR7a9lthMpwsaONwA7Yr1FDkAjFADqKKKACiiigAooooA434kSLF4Q1Bvl3NCUGWCjJ9zXM/ByPy9FIDpJ8331B5+tbHxZvUsvCFw7xrIGO3axIz+VUfhKmNJY+V5cZclFB4UegoA9MByOKy9Y8OaVrtv5Oo2UNwm4Nh1zyK1Fp1AHk198FbW5u2Carcx2Mjl2tx0HOcL2A7dOleiaHodroWmQ2Nom2KJQoHetXFGKAGkcGvI4oxZ/HC+KBV+0W6ltxJJOByOMdvXtXrrdK8lvrdrr40F2KqsFuuMMAxyPzI5oA9WiOYwDivKvH7f2d8SvCt4MJ5pkhZy2MjI4/8eNeqQ/6sD2rx34zSKPEXhbEsYeOd2AJIOcpj8OKAPYbVt8Kn2pmoWEGpWMtpcorxSrtZSAR+tRaS5axi3HLbRk1foA8v03wz4r8JXd0unNb32nytujikfZ5XHOB2zz+NUJtG8X+KdWifVbOOysiSrxq4J25POcZz36d69fIB6ik2gHOKAK9larZ2scCKAkahQB2Fc18Rbz7F4H1SVwOYtg43ZyQOnfrXXVwPxbVpPA1zGhjDeYmC/Tr+v0oApfCazW28LWxXb8/zHb78/hXo7DKHPFcf4BhWLw7ZqoAUIDjGO1di/Kc9PegDxn4zNGBYpIygFuVZsA+h/Miu38CxsuhwK2wsqgZQmuA+NLLLqOj242lmf7uRzyBXpnhCLZo8A8sIdgyBQB0g6UtIOlLQAUUhz2pec+1ABRRRQAVynj7Rf7X8N3KRopl24BKk/wAufeurpCoIwQDQB4x8NNcudA1Q+GNVZExnysuCc9x1r2dWDDINebfEnwxFcaadTsmhtLq2PmCQ7UyRyDk8DmsvwL8VrW8MelatOF1FTtYqMo2O+RxQB69RUUM6TKGRgRjqKloAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAIbqdLa2kmc4VFJJzXzlpl7F4s+M0l4VHkwkugycjHHOa734y+OLPRtCm0eOUtfXIGYwP4M85PavFPBcXiW51C4k8MWu15WAaZ8N5Y9MmgD6Y1zxHpvhnRjc3soGOEjU5Zz6Ad64nQNC1fxtrUXiPXyYbeM/6LZquMLnILe/frSaR8Jrm/u11DxVqc1/OGDJHvIVPYV6vZ2sdpbrFGMKowPpQBNGuyNVxjAp9JgdaWgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAry341yxx+F4oXQN50wUg+nWvUq8h+M80qTaOgO1GlIzvZf1H+FAG98MbSK38LW8cb7geT8wPX3FbHifVNW0SIXdlbC7g6OnAMY9c9xWL8Mk8rS5sNuXzTgiXzM/jWp8RtSOm+C9RnRdzmPYBkjrx2oA8+0T4620kc66tbvFMpwPJXcP51pQ/GzTmUM8ZXPCocFjjrnB47cYrK+FHh6C7spZLq1Rmb74kGck8967+T4Y+FZpzO+kQGQnJwCB+WcUAYH/C5tMMiFIS8JxudW5XIzyKuWvxa0ie9MTB1jwT5nYfX0rQk+FnhKRNraNBz/dyP1Bqm/wc8JPgNYSFR0H2mTj/AMeoA1U+IegSSpGL2MblLAswA49zWRd/GTwpatsF20jdD5abgD25HFKnwd8J7gWsGIUbQDO/TrzzzWhH8MfCqQpF/ZMJCnOSSTn65oA5K4+NaXhMOiaRc3UxOEMmEX3z9BWKviz4laope1isokcEqNvvwOfwr2K38NaXbBRFZxLtORhRWgtnCmNsYGKAPnibTfHHiC4SHVr6+kgYgukEe1VyPwz2/OrVp8I52mEksPnBehdmBP1BBFfQC20S9EFPEarnAHNAHnnhv4bWWnWXlXSCYMPmRhx34x0xya6q78P2s+mTWQhQRyJtxt46Vt4ooA+f7ayv/h54x23Twva3IBZlkKKuSBkKele1WlxFeQKyOrqwBBByDWF8QPCMXiTSHeO2SS+hQ+ST/Lr/ADryTwz421HwhdXFprZvQI2IdJEDZ5xweMfmRxQB03i7Rm8I+J4vENjAxtZJAZ9spyGOc4XGMHjnNeo+H9TTVdLguowQsqBgG61414y+JVj4h05dJ0lLuSaV1DMEwAM8jGcn6e1ereDNPGmeHrW3UMAEHBBGD347fSgDpqKQHNLQAUUUA5oAKKKDQB5d8Y7/AMnw9Cik4kl2/KMk8HpyK0fhlaNb+HomfdlxnkYrA+M8wj061QjAably5G0Y6iup+HWz/hHbfYxZcZzQB2oGBS0dqKACiiigBkjhUYnoBXlPhvfrPxC1rVD5bRRyG3RkOfukY/ka0vij4wj0jTRpVo4bUrzCJGOwJxnpVr4feHl0HRokKf6RKA8zddzkcnNAHbJhYyelfP3xkvTfeNrWGEyuljbgyBOiszDHfnqO1e5avqcOkaXc39y+2GCMyMfYV8vHWJNY183kqP5moXZnYIfuop+XPtn3/hoA+oPDrbtJtzz/AKscEYxxWvWR4dDrpNuJCC4QZwcjpWvQAUUUUAITgZNeZ/GuZk8AzbGKt50eGHY5r0xvunNeX/GCUzeG5LXA2E5x7gUAbvw7Yy+FtPdydzQLuBHtXYv9yuW8CR+V4asVCbP3K8fhXTynCE+1AHiXxMFvJ450pZIpGKgAYbAOTzXrmgxLHYRqoKgDjNeJeNbqaf4tWtuJFEaou7Jwe5H64r3LSc/Yoic/dFAGjRRRQAUUd6KACiiigApCcUtch8QPGEPhTQmmLETyHbHhd2PqMigDzn4veJ5bu4bSYWk+zJwUQ43sM9+T1H04rm9J+E92fDaarMkjXTjzDAnDBcduDz3xit74eeGJfF2sy+J9ZQsqvi2jI2huepXJ9u9e2kRWtuxYqscY5zxigDwDQPGXiDwXGyXEcuoaYkm1ssd8Ptz/APq+le4eHfFOn+IrBLqzmDA8FTwVPoRXj3jIHxZrc8dhGbaEfKJEPzSkd9vcVRvPA3iHwcbS+0m+mUkbpnjjdgTjqyjIP40AfRYIPQ0teM+D/i23nrp3iQrDcY4nwArfUDocV6xY6raajCkttMkqOMhkbINAF6ikDA9DS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTXYKhJPSlJwK8u+KfxHttAsm0ewIuNTuVKbEbmMHucd/SgDyr4k3/8AwlvxHWxstr7XEOPLAz65IPP6V9AeD/DltoWi29tHEqbUGcDqa88+Dvglra0fWtRgYXU5yokXBUV7QiBVAHSgBcYpaKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArjviJ4YbxFoX+jxB7y3YSRYA3HHUAnpmuxooA+eND8eXPhO5ayudNlhjMzNNHIeUJ64PcDHpS+MfGzeOHh03T4m+wo4Msjgjce46jGPfrXvU+l2VyzNNbRSFhglkByKz4PCml2lx51tbrAS+91iG1XPuKAMrwH4dTRNIQDfuf5jubOPTHtXY01VCDCjAp1ABRRRQAUUUUAFFFBoAKKKKACiiigAPNc5rvgrQtfmSfULBJpU4BJI49ODXR0UAcBZfDHQbS8S7FnskVy6qJDgZ46fStDW/GWleG0iSVy5ZtuF7Duam8Z+JrXQdJmMlwYZ2Q+XhC3NYPhjwlHeJHquqg3E0igpHIvES9cAeueaAJ5viro8chjEdwTtVlYptU7unJ6fjU1l8S9LuGYTn7NGrbPMdxgn/PrWjrGmaVZ6a8k9rG0cI3AFecgYGMflXlCeCG8bu18IRp0AI8oqN24eu3oO2KAPQ5Piz4WilMX9oKxDFdwBxkenHP1HFVZfizpS2UV1HBcywyMRuRRgY9zXIX3wk02x01pjfuJflJluDnBAxwBjnFVPDmh6Ba3cfm6nLcsrMzI6bUZyeoBGfwFAHrmkeM9I1oL9luQWPRDwa6IMHFePax4ORAt/ody0LwfOYwzNk9eBng11/gnxC+q2EgmlSSSFyhZQQD+fegDkPjikv8AZVvsTcsjEOTjaBj+db3wpYDwrZxhydsYPPoaPipGlx4ZmXIDhSVwMnPtWH4H8XaVYaPZW8lyiyrEqsAp/oKAPYRS1zdt4y0eV2j+2orL1D5X+f1rQj8QabMf3d7A30cUAalQXcy29s8rttVFLEnsKpXeu2NpEZJbmNUHcsK8q8R+L73xfI+m6QG+ylgC4I2svct/QUAVbCJPGHj+81h1ka0tyogDD5D23Zz7V6vZuxiUqCFA4I71ieGNEWy0uO3djlQATk5JrS1zWLLw9pE17dyCOC3jLE9z6CgDhvjF4oistC/sSNt15qLKgjU8hN3JP16fjXlngfSxdaxOfJaSRR5UAldcjtk/TAxVVdWPibxnc6zeFwS+63i3btpH3RjqQOOldt4DtHXX7uzeQSSo6uXKksOmevA6e9AHuOhWv2PTLe3yT5cYXJPtWpVS1KpEoyM4q0CCKAFooooARuleSfGKbZpcMO1h50oUMDjBz1r1osOfavI/ivcR3Os6Dp6fO5nMjgdAg9fx/lQB3XhbbHpUEa5+RAP0rXvZlW2ZmOB+Vcbpuvw21gXWWMckBc8gjrXM+MfiPb2VqUiuYmlbIEQyxb8ulAHLeIJI7740wIJjtUIQFUnkf5/WvoHTwFtkyOa+dfA2kalrfi19beF4lZg+5c4bkdz9OlfRtpGy26buDjmgC1RRRQAUUUUAFFFFACE4rwD4i6nPc+Njpk1yfKlmSNleAYVOcYznPJ64/SvoCvOPiB4GbVLuPW7Qb7uEjcrn+Edlz0oA6vRba203SoooEVUVflCgD8q4jx74whknk0eC8SKEIfPkjAkYt3QDt/n3rL1P4h6lp+k3FsmmtFdJGNrO2RzxkAc+ntWL4F8EarrZS71gSC0di5jYjD85zggn+VAHcfDvTYNjzwRbISdwzbmMnPPf+lejeUhXaVBHvUNjZQ2NskEKBUUYAA6VZoA5TxF8P9E8Rw+XdWwQ7t2+L5Tnvn1rzK+8F+LPAU8l74ene6t2bHlld5Cj2xx+Fe8UhUHrQB45oHxheAC28SafNZXAbaG28MR14PSvRdH8W6RrKqbO9jkLDcFDcge47VJrfhTSNetmgvrKKQMMZ2jI+hry3xD8HpbGeS+8O3LxOoBjiiAVwe/Pf6cUAe2BgRkHNLXzraeNvG/hW98vVy91bg874vmB9OAK9E0P4vaBqUaC5uBay45WXgfnQB6NRWXp+v6ZqW4Wd7BPtxny3BxWmGU9CKAFooooAKKKCcUAFFJketGR60ALRSZFMeeNBlnUD60ASUhIHWuV1j4ieGNGjka61e13IM7EkDM3sAO9eX6h8QvFHjbWF0Xw3ANOtpAS0zEO+z1P936daANv4pfEG7sLiLRPDt4BqEjYl2JuaMUzwF8MJYr/APt7xBJ9qv3+Zc8qufb1rX8DfDGLQ5Dfam4u9QZtxlOT/OvSkQIgUDAFADIYEhUKigKO1S0UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRzmigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopCcUtABRRRQAU122oW9BmnVBeRvLZzRxuUdkIDDqDQB5lp8Fx4p8X315c3E62dpN5aW8i4DEE/pz0r0y3iWJMKAMdK8j8L6zd+FtVudO1oBFlmLrOzg4JOMHvj0r1iC9ilQMrqQQORQBxXjm4N/qlhoUYyJn3z8sMIPp9O9dZZWkdvaoiIqoqjAAxgCuN8Y3KaX4o03VH2+WcxyPgZAJAHcevvXa2lzHPbIVYEEfnQB5l4quJ9cuL3yrhktrBirwKSBIVIJJJHH1FcBJcajd+Rc2cX/EvjGwOriVl9eSK9A8TB9A8STNc29t/Z2qN5X7r72ccEr375PTj8+O3aj4aWa0gtTc2Vw37uZSXVQcBQF3dvY+lAHT/DvV5r+7u7OZxIygPvyvzA9OAOOK2NGt5dL8cXlksyCCZTOkWQOvXAznrnnHeoPh5ol3psM1zfCLfJ90LGFIX0J71Jb36ah8SJ/LlXybWFRuCg7jzkZ9OaAOm1/w8uuaVcWc6qyyqeT2rx+7+D9ylwxhu2hBPygZIB+mc174L2FU5kX865PxH448P6KB9puPNm7RxJuJ59enb17UAeZD4deKEDbLq0kj6BZEznHrnr0qhrGna1oVm8+oQWqLtz8km3OOcAd+nSusm8da3rl39h0S1jhLtt84kOV5644GMZp+l+AtZ1TWTe65M2ApUIspcN055zgcdPegDymLRvEPie6DWlvKsIPzHc3AP8J/Lt717D4K8HS6HGjTA+a2N/J5Nd3pui2mlRiGKJIlJ4CjqT1NWb26ttPTzZpUjTbuJY4GB1NAFa7voNKtWnuZUijQZZ3OAPqa+ePHnje88YasttbRFtMtpOEjyzSEH7/A6f5711/jHV9T+IGoDw9oihLIMHmmZseYAcg4646H8RXUeD/hpFpGJ70pPcFt2SgO04xwev8A+vpQB4pothrVpfw3jaTclQWIl8snGe9dRb6xq2k3dxc/ZngncAnMf3+ccYPJ5r6CTTIEIXy12g56U+TSLWfiSFGGeMigDxS2+JOpQuqTz26sUVtsgZTk9QePpXS2XxNYRRNLJBLuXLbGHHX361383hrTbhcS2sLfVBWXP8PPDc+7fpVsdxyfkHNAGMfihZQSBbhkXI6hhjP1qRPirocinZcKSOvP6fyp1x8IPCk5UnTVUr02Ow/rUSfB3w0kBiWKZFJz8spz+dAEsnxM8PvF/wAhCJWY4wxwRXifjnxLHdeL4ryxnW8hVSqKhO7cc55/pXqOpfBHTJgDaXM0XB+V8MD9as+HfhLpmjNHLOi3EyfKrMv3aAPJNB0rxV4kLQ2pNnCW+Z5Mg47gc16f4d+EFhZqsl9/pM27cSxOM/jXpdppNtaALFGigdgK0FUUAZunaNbadGqQxKgxwAK1BwMUYpaACiiigAooooAKKKKACggEYIyKKKAKUukafNMJntIWlAxuKDNWY4UiGEUAe1SUUAFFFFABRRRQAUhANLRQBTu9Ms70AXFvHJg5G5Qa8z8SfCKzup3udPjjA2sPKcexxhuufrXrFFAHy5N4Q1TR1WSGa806dDiRmf5XGOMMMYPPT/Ctm21vx3pKCdNRW4BbcUl4IBOOjV9A3Vha3sLRXECSxt1V1yDWO/gzQ5GJOn2/IwcoORQB5tb/ABY1vTmA1fTbdo1GZHhlGV6Dkc+tS6h8c9Oj025VLaVbwDCRv0I9c12E3w10Sa5LNAPJP/LIcDPrx35rB8QfC3Sk069ubaFDKsDBN8QbHH0yTQB1PgTxHL4l8O29/NEEdx0Gfz5rqeK88+E11NN4St/O270Jj4GOAcV6GfXvQB498UfGGo+GfFFj9gDuSikxjJDDOMdcD69ax5PjN4jjuWtx4fiSULkBpi3b2wP1qv8AFbF58RrO1QkOYFQEHBGSeR713Wk/CzQjpQW4tS00q5kkLksTj1PNAHn83xT8Y3SsVOn2cT5UMQSQfz61yl/qeu6nEkl34kv5mlXKW0CuN2Tj1xg+tfQ1j8PdAsYfLSwhcFs5dQT9PpWrH4Z0iOUSrYQBwRg7BxigDwnwz8HL7U5o7jUkSGA4bY65Yggcdua9t8P+ENJ8Ow7LCyihz95lHJ+prfSNUGFAAp1ACAADApaKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSY4xS0UAc5r3hHTdaBea3UuevbPvx3rirjwjr2hzJLpupXrwg8Q53BQBxnJ79+K9YprIGUgjOaAPDNb1PxBf6fd2OqaNHdIn3HZgjZ52nGeO361m+FPibPokq2OqWF3FZLgJK53CMHoM+le8XOl21yuJoUfnPIrndf+Hmia/DHHc2igocq68Ef4/jQBFff2X4y0MqsqTwyqMNG344yOledXmkeJ/D8cQsXV4FYhvNcuuOMfTv0FbFx8OdV8O2bHw9qV6SPuw71C+vPT6cVjw6x8QLOTypdLS7jTAPnL5bN+vP4CgCOLxX4xuLVo30nZBICPOtkZic5HHPHY5pdC+H+orElxcRsWn3NNH9oZX5IIPoCKlPjrxDbMRP4aZIwCQAG3NgjoMe/61YPxTvYYVkOjqrM5QI7spJGAQRt96AEl+G+pSyKqXcqxA5xLKSxXGNucfr798c7enfC/To5TJetLO4AVNzk7FByFHtmqB+LhjSLzdDuE81tm8uMA8jnj2NSN8Vbsp5MHh27e8JIKg/JtHG4NjkcelAHotlpNvbRqqRKu3oQKvuYYEyzBVAySeAK8oHjrxjeSE2egpFEEDATElm57Y+uaqQ6H4v8asH166uLKzddptY22fXp1/H1oA6rxF8R9HsyyadINQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "781" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:48 GMT" + ], + "Etag": [ + "CM3t2Nm1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-SOrrWe29xeIejVEYa8S-JTMY083mInEUGz7PbH9hIofeaKcYgFswrM3jRXnSRQuk" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDY4MDI1MDM3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2ODAyNTAzNyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2ODAyNTAzNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiaW1hZ2UvanBlZyIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjM4NDMwIiwibWQ1SGFzaCI6Ill0US9vZzV3djZIOXNpVVEwY0JnMGc9PSIsImNyYzMyYyI6IitEWE5MUT09IiwiZXRhZyI6IkNNM3QyTm0xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDguMDI3WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ4LjAyN1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDguMDI3WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ4LjAyN1oifQ==" + } + }, + { + "ID": "0a508361d862b22d", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:48 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:48 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876468025037" + ], + "X-Goog-Hash": [ + "crc32c=+DXNLQ==", + "md5=YtQ/og5wv6H9siUQ0cBg0g==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "38430" + ], + "X-Guploader-Uploadid": [ + "ABgVH89y4GbO1_fWLK8ac1H4R03rAvJboA42348txi4NNG09gf5xIp8N6gGbBAboTzJL2n2c" + ] + }, + "Body": "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + } + }, + { + "ID": "4bce9ed1de2e6d1b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "781" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:48 GMT" + ], + "Etag": [ + "CM3t2Nm1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_XW85ONw-m1yjFiTJEnNah38vam6829g_Khy0dNBIqIr-X7UqJJHMcqfcJ48vvnA4" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDY4MDI1MDM3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2ODAyNTAzNyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2ODAyNTAzNyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiaW1hZ2UvanBlZyIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjM4NDMwIiwibWQ1SGFzaCI6Ill0US9vZzV3djZIOXNpVVEwY0JnMGc9PSIsImNyYzMyYyI6IitEWE5MUT09IiwiZXRhZyI6IkNNM3QyTm0xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDguMDI3WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ4LjAyN1oiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDguMDI3WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ4LjAyN1oifQ==" + } + }, + { + "ID": "b6f084d05cb13c20", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:48 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88ic1yjOnXIaLG_66OSOOyL8WRX1n_Im84J1xjsPI1duw_UBSSnOKRYhyjlOte7Mcg" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/a_small_text_file_gets_a_ContentType.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/a_small_text_file_gets_a_ContentType.replay new file mode 100644 index 000000000..8ef3cb9ef --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/a_small_text_file_gets_a_ContentType.replay @@ -0,0 +1,298 @@ +{ + "Initial": "AQAAAA7gDLyyFJ+7zgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "8eef3549c490b8f4", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibmFtZSI6ImJsb2ItZm9yLXJlYWRpbmcifQo=", + "VGhpcyBpcyBhIHRleHQgZmlsZS4=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:46 GMT" + ], + "Etag": [ + "CMuChdm1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-RTYRfk_vhcZdTxO5ek9UUEGIJ1RiusP5jI3Bg5yvPSV8pGjHDfdqjmUnEnxb8R3o_" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDY2NjUxNDY3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2NjY1MTQ2NyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2NjY1MTQ2NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjIwIiwibWQ1SGFzaCI6IlB6TUpNU3pESmtvVGliTFNZOTdPalE9PSIsImNyYzMyYyI6Im5ITUdVdz09IiwiZXRhZyI6IkNNdUNoZG0xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDYuNjU0WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ2LjY1NFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDYuNjU0WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ2LjY1NFoifQ==" + } + }, + { + "ID": "cd72feb498054441", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "20" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:46 GMT" + ], + "Etag": [ + "\"3f3309312cc3264a1389b2d263dece8d\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:46 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876466651467" + ], + "X-Goog-Hash": [ + "crc32c=nHMGUw==", + "md5=PzMJMSzDJkoTibLSY97OjQ==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "20" + ], + "X-Guploader-Uploadid": [ + "ABgVH88ojF_LUTrTrTA-WnOafmSV8EkO5zknHEl-y3ZFnVm3xI5ij8MP25eBfEGZMuuJnio" + ] + }, + "Body": "VGhpcyBpcyBhIHRleHQgZmlsZS4=" + } + }, + { + "ID": "571dce782aa63d92", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:46 GMT" + ], + "Etag": [ + "CMuChdm1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-J8rr6tXzJNUdX--R-AekiaXdWXWgUVWaBkHFZQmm4O7m9gdwJpfcplVzfJByuJeZw" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDY2NjUxNDY3Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2NjY1MTQ2NyZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2NjY1MTQ2NyIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjIwIiwibWQ1SGFzaCI6IlB6TUpNU3pESmtvVGliTFNZOTdPalE9PSIsImNyYzMyYyI6Im5ITUdVdz09IiwiZXRhZyI6IkNNdUNoZG0xeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDYuNjU0WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ2LjY1NFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDYuNjU0WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA3OjQ2LjY1NFoifQ==" + } + }, + { + "ID": "14cc88c65280e610", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:46 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_1AU_DpmyzpcBX1BVIZRB99J46SoC3izm6YYza_484OXcioYHhCW7RwMc-yT5xwqY" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/invalid_ContentType_fails.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/invalid_ContentType_fails.replay new file mode 100644 index 000000000..1341e9ccf --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/invalid_ContentType_fails.replay @@ -0,0 +1,92 @@ +{ + "Initial": "AQAAAA7gDLyuHWmpAgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "c6a8aae0a3469ac5", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "204" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:42 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH89tnXyUDwYfriDxUrDjRhhIZJuIXsEM-4TUHzuKEsiDL_gbwTw2_z0SB3_xlJBuqeM" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9ibG9iLWZvci1yZWFkaW5nPC9EZXRhaWxzPjwvRXJyb3I+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay new file mode 100644 index 000000000..705f76906 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay @@ -0,0 +1,239 @@ +{ + "Initial": "AQAAAA7gDLytNJgcTgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "b5c436b6670c6d6e", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibmFtZSI6ImJsb2ItZm9yLXJlYWRpbmcifQo=", + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "792" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:42 GMT" + ], + "Etag": [ + "CK7h89a1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_IgZ7xIlY8e0ZeCbyPP0SAuIpT52GTvREI1nS_6Ug_KRPY0EuAPiBHUQnh7wB7HcN1" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDYyMTc0MzgyIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2MjE3NDM4MiZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2MjE3NDM4MiIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjAiLCJtZDVIYXNoIjoiMUIyTTJZOEFzZ1RwZ0FtWTdQaENmZz09IiwiY3JjMzJjIjoiQUFBQUFBPT0iLCJldGFnIjoiQ0s3aDg5YTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0Mi4xNzdaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDIuMTc3WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0Mi4xNzdaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NDIuMTc3WiJ9" + } + }, + { + "ID": "c64b8e2cfc0e3395", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:42 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:42 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876462174382" + ], + "X-Goog-Hash": [ + "crc32c=AAAAAA==", + "md5=1B2M2Y8AsgTpgAmY7PhCfg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "0" + ], + "X-Guploader-Uploadid": [ + "ABgVH88cL18WvEOnQSAa3lve2mdbb5VECP69Qkus8bfZM4sThk1qaEHyulyQcjGDXnnwPBWU" + ] + }, + "Body": "" + } + }, + { + "ID": "37116dd60f7857a2", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:42 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89sm0wQh5gP1Kn1qxXTgxj39wDpt_maVEFxQT824cBTA8x3mqnoH1hXLOgBFilYMkM5" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob.replay new file mode 100644 index 000000000..878c54402 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob.replay @@ -0,0 +1,239 @@ +{ + "Initial": "AQAAAA7gDLytEhYOqgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "058f6ef8731d1f11", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibmFtZSI6ImJsb2ItZm9yLXJlYWRpbmcifQo=", + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "792" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:41 GMT" + ], + "Etag": [ + "CK370Na1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH898mAILlijE64jz3kHtOOuzPpMUUE2YGgsYhgMQPhUAySa19x8QjiJ-1jM7rj8ce8f1" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDYxNjA0MjY5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2MTYwNDI2OSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2MTYwNDI2OSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjAiLCJtZDVIYXNoIjoiMUIyTTJZOEFzZ1RwZ0FtWTdQaENmZz09IiwiY3JjMzJjIjoiQUFBQUFBPT0iLCJldGFnIjoiQ0szNzBOYTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0MS42MDZaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDEuNjA2WiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0MS42MDZaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NDEuNjA2WiJ9" + } + }, + { + "ID": "6f53a16113d78d2b", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:41 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:41 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876461604269" + ], + "X-Goog-Hash": [ + "crc32c=AAAAAA==", + "md5=1B2M2Y8AsgTpgAmY7PhCfg==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "0" + ], + "X-Guploader-Uploadid": [ + "ABgVH88xdLDqWnqMRHm7oq1Zr11j5mZjAZlGEditX3vjcoEbTbDyuIchr6huEVSHBKGfas8" + ] + }, + "Body": "" + } + }, + { + "ID": "2d06c33e84357156", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:41 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89QsJhHCrgePl1XNwbUzQ01RoT_UGE8I90GVfINYdFJP__062vVA8JfbPTaJ90245sx" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/write_to_empty_key_fails.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/write_to_empty_key_fails.replay new file mode 100644 index 000000000..54c9d2fde --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/write_to_empty_key_fails.replay @@ -0,0 +1,97 @@ +{ + "Initial": "AQAAAA7gDLytAith6wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "a96bb86c98342cc9", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04In0K", + "" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "127" + ], + "Content-Type": [ + "text/html; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:41 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-b3r3Tk1HFJ56AMLUWwFuVJBjBYAcFuCuwEB7Lm0PPazIeL3qlN7H_0nhhFu5_J7Lj" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDAsIm1lc3NhZ2UiOiJObyBvYmplY3QgbmFtZSIsImVycm9ycyI6W3sibWVzc2FnZSI6Ik5vIG9iamVjdCBuYW1lIiwiZG9tYWluIjoiZ2xvYmFsIiwicmVhc29uIjoicmVxdWlyZWQifV19fQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay new file mode 100644 index 000000000..525ccc602 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestConformance/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay @@ -0,0 +1,298 @@ +{ + "Initial": "AQAAAA7gDLywCDfySwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "bd29bda974833828", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026name=blob-for-reading\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJhcHBsaWNhdGlvbi9qc29uIiwibmFtZSI6ImJsb2ItZm9yLXJlYWRpbmcifQo=", + "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "786" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:44 GMT" + ], + "Etag": [ + "CMfQgdi1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH895xNVy1K5ncvvy5S0wzD4UMmsbr5d9Lk8msCcAhnoIPO8QfdEj3tN5PSCEgivXSA4" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDY0NDk4NzU5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2NDQ5ODc1OSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2NDQ5ODc1OSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vanNvbiIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjYzNTQiLCJtZDVIYXNoIjoiRDJwOG4vUFQxM0M0OS9vWndxNFowQT09IiwiY3JjMzJjIjoidGR3cmdRPT0iLCJldGFnIjoiQ01mUWdkaTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0NC41MDFaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDQuNTAxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0NC41MDFaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NDQuNTAxWiJ9" + } + }, + { + "ID": "b7055a973258b142", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:44 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:07:44 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876464498759" + ], + "X-Goog-Hash": [ + "crc32c=tdwrgQ==", + "md5=D2p8n/PT13C49/oZwq4Z0A==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "6354" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_QCz964oE5xdDibDY_tlmeL6qxiT8qIjt4jRNFMzXr-k1cqHkN0_bMbzM-wMCCd2c" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "e065d30083bc6816", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "786" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:44 GMT" + ], + "Etag": [ + "CMfQgdi1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-LSQQfL2jkrGPqh3dC9rL7Sxfmnqf1gG1wevGOsby2tUnLmp6iZJ3p943lzqbCqAp8" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvYmxvYi1mb3ItcmVhZGluZy8xNzUyODc2NDY0NDk4NzU5Iiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL2Jsb2ItZm9yLXJlYWRpbmciLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9ibG9iLWZvci1yZWFkaW5nP2dlbmVyYXRpb249MTc1Mjg3NjQ2NDQ5ODc1OSZhbHQ9bWVkaWEiLCJuYW1lIjoiYmxvYi1mb3ItcmVhZGluZyIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjQ2NDQ5ODc1OSIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoiYXBwbGljYXRpb24vanNvbiIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjYzNTQiLCJtZDVIYXNoIjoiRDJwOG4vUFQxM0M0OS9vWndxNFowQT09IiwiY3JjMzJjIjoidGR3cmdRPT0iLCJldGFnIjoiQ01mUWdkaTF4NDRERUFFPSIsInRpbWVDcmVhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0NC41MDFaIiwidXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDc6NDQuNTAxWiIsInRpbWVTdG9yYWdlQ2xhc3NVcGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowNzo0NC41MDFaIiwidGltZUZpbmFsaXplZCI6IjIwMjUtMDctMThUMjI6MDc6NDQuNTAxWiJ9" + } + }, + { + "ID": "ab5b1d760552a6f9", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/blob-for-reading?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:07:44 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89IbX-w6670-yVv47hSkttSTIwKUHnZFn5D52Aj1zJk6rpJ9Yl7B5J06JBFvnLgoT0T" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestOpenBucket/empty_bucket_name_results_in_error.replay b/go-cloud/blob/gcsblob/testdata/TestOpenBucket/empty_bucket_name_results_in_error.replay new file mode 100644 index 000000000..e7ed20cc9 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestOpenBucket/empty_bucket_name_results_in_error.replay @@ -0,0 +1,39 @@ +{ + "Initial": "AQAAAA7gDLzYEsRilwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestOpenBucket/success.replay b/go-cloud/blob/gcsblob/testdata/TestOpenBucket/success.replay new file mode 100644 index 000000000..2178d019e --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestOpenBucket/success.replay @@ -0,0 +1,39 @@ +{ + "Initial": "AQAAAA7gDLzYEtGkJQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/gcsblob/testdata/TestPreconditions.replay b/go-cloud/blob/gcsblob/testdata/TestPreconditions.replay new file mode 100644 index 000000000..04f689fb3 --- /dev/null +++ b/go-cloud/blob/gcsblob/testdata/TestPreconditions.replay @@ -0,0 +1,655 @@ +{ + "Initial": "AQAAAA7gDLzYIxMIZgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Expires$", + "^Signature$", + "^X-Goog-Gcs-Idempotency-Token$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^Expires$", + "^Signature$" + ], + "RemoveParams": null + }, + "Entries": [ + { + "ID": "512ef1b86505294b", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026ifGenerationMatch=-999\u0026name=precondition-key\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsIm5hbWUiOiJwcmVjb25kaXRpb24ta2V5In0K", + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 412, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "276" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:24 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH89YuStmd6uAYTCWf8a-d2r3Pk8n30_PFEqikS7NSUqNAFk7VJt0Bt2qWMVZaN9wnHUDWJTFTBk" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MTIsIm1lc3NhZ2UiOiJBdCBsZWFzdCBvbmUgb2YgdGhlIHByZS1jb25kaXRpb25zIHlvdSBzcGVjaWZpZWQgZGlkIG5vdCBob2xkLiIsImVycm9ycyI6W3sibWVzc2FnZSI6IkF0IGxlYXN0IG9uZSBvZiB0aGUgcHJlLWNvbmRpdGlvbnMgeW91IHNwZWNpZmllZCBkaWQgbm90IGhvbGQuIiwiZG9tYWluIjoiZ2xvYmFsIiwicmVhc29uIjoiY29uZGl0aW9uTm90TWV0IiwibG9jYXRpb25UeXBlIjoiaGVhZGVyIiwibG9jYXRpb24iOiJJZi1NYXRjaCJ9XX19" + } + }, + { + "ID": "ced8d30b15fb7304", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/upload/storage/v1/b/go-cloud-blob-test-bucket/o?alt=json\u0026ifGenerationMatch=0\u0026name=precondition-key\u0026prettyPrint=false\u0026projection=full\u0026uploadType=multipart", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "multipart/related", + "BodyParts": [ + "eyJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiY29udGVudFR5cGUiOiJ0ZXh0L3BsYWluOyBjaGFyc2V0PXV0Zi04IiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsIm5hbWUiOiJwcmVjb25kaXRpb24ta2V5In0K", + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:25 GMT" + ], + "Etag": [ + "CPy3qeu1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88Mubvdb4vlcR1MzGNvrbjshSrAAjQxun0bK2xTIWgvYklwk34v-fJsoGlRI3bkPu6IRd5kJs8" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvcHJlY29uZGl0aW9uLWtleS8xNzUyODc2NTA0OTk2ODYwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3ByZWNvbmRpdGlvbi1rZXkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9wcmVjb25kaXRpb24ta2V5P2dlbmVyYXRpb249MTc1Mjg3NjUwNDk5Njg2MCZhbHQ9bWVkaWEiLCJuYW1lIjoicHJlY29uZGl0aW9uLWtleSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjUwNDk5Njg2MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjExIiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsImNyYzMyYyI6InlaUmxxZz09IiwiZXRhZyI6IkNQeTNxZXUxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjQuOTk4WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjI0Ljk5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjQuOTk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjI0Ljk5OFoifQ==" + } + }, + { + "ID": "e21c24c34c4a62bc", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/precondition-key?generation=999999", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "204" + ], + "Content-Type": [ + "application/xml; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:25 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "X-Guploader-Uploadid": [ + "ABgVH89Q7wt5WGf-cHKSUBQnzLZynqbTiwzRCJmGcnSzg-nIdH5nIusjU_YniQBd5t10jek" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz48RXJyb3I+PENvZGU+Tm9TdWNoS2V5PC9Db2RlPjxNZXNzYWdlPlRoZSBzcGVjaWZpZWQga2V5IGRvZXMgbm90IGV4aXN0LjwvTWVzc2FnZT48RGV0YWlscz5ObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9wcmVjb25kaXRpb24ta2V5PC9EZXRhaWxzPjwvRXJyb3I+" + } + }, + { + "ID": "2e08da19d2fe4ba2", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/precondition-key?alt=json\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "private, max-age=0, must-revalidate, no-transform" + ], + "Content-Length": [ + "793" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:25 GMT" + ], + "Etag": [ + "CPy3qeu1x44DEAE=" + ], + "Expires": [ + "CLEARED" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_K5f2C8qwYHKkP_RLrIwtjKiygZ8njNDmrNx2l1s5tjhiA8FKyoCJ_hVXk8AtkQU4" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvcHJlY29uZGl0aW9uLWtleS8xNzUyODc2NTA0OTk2ODYwIiwic2VsZkxpbmsiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3ByZWNvbmRpdGlvbi1rZXkiLCJtZWRpYUxpbmsiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vZG93bmxvYWQvc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9wcmVjb25kaXRpb24ta2V5P2dlbmVyYXRpb249MTc1Mjg3NjUwNDk5Njg2MCZhbHQ9bWVkaWEiLCJuYW1lIjoicHJlY29uZGl0aW9uLWtleSIsImJ1Y2tldCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQiLCJnZW5lcmF0aW9uIjoiMTc1Mjg3NjUwNDk5Njg2MCIsIm1ldGFnZW5lcmF0aW9uIjoiMSIsImNvbnRlbnRUeXBlIjoidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOCIsInN0b3JhZ2VDbGFzcyI6IlJFR0lPTkFMIiwic2l6ZSI6IjExIiwibWQ1SGFzaCI6IlhyWTd1K0FlN3RDVHl5SzdqMXJOd3c9PSIsImNyYzMyYyI6InlaUmxxZz09IiwiZXRhZyI6IkNQeTNxZXUxeDQ0REVBRT0iLCJ0aW1lQ3JlYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjQuOTk4WiIsInVwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjI0Ljk5OFoiLCJ0aW1lU3RvcmFnZUNsYXNzVXBkYXRlZCI6IjIwMjUtMDctMThUMjI6MDg6MjQuOTk4WiIsInRpbWVGaW5hbGl6ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjI0Ljk5OFoifQ==" + } + }, + { + "ID": "49c1a310a2bd76b4", + "Request": { + "Method": "GET", + "URL": "https://storage.googleapis.com/go-cloud-blob-test-bucket/precondition-key?generation=1752876504996860", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "private, max-age=0" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:25 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Expires": [ + "CLEARED" + ], + "Last-Modified": [ + "Fri, 18 Jul 2025 22:08:24 GMT" + ], + "Server": [ + "UploadServer" + ], + "X-Goog-Generation": [ + "1752876504996860" + ], + "X-Goog-Hash": [ + "crc32c=yZRlqg==", + "md5=XrY7u+Ae7tCTyyK7j1rNww==" + ], + "X-Goog-Metageneration": [ + "1" + ], + "X-Goog-Storage-Class": [ + "REGIONAL" + ], + "X-Goog-Stored-Content-Encoding": [ + "identity" + ], + "X-Goog-Stored-Content-Length": [ + "11" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_wJIf6vfOhyH4MjeKfP1_x6KPq7G_GMBmDZ76f9OrjiRJ1-ss_MnJWuh0P_D-MdTM" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "79c2b37dae102e52", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/precondition-key/rewriteTo/b/go-cloud-blob-test-bucket/o/precondition-key2?alt=json\u0026ifGenerationMatch=-999\u0026prettyPrint=false\u0026projection=full", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 412, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "276" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:25 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-hz-F3xyPwGGJFR4GfblbzEsARalXHIffsBAPMbP91P52pThwnnrG_9RZyMCvHwhWKdmS5Z0g" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MTIsIm1lc3NhZ2UiOiJBdCBsZWFzdCBvbmUgb2YgdGhlIHByZS1jb25kaXRpb25zIHlvdSBzcGVjaWZpZWQgZGlkIG5vdCBob2xkLiIsImVycm9ycyI6W3sibWVzc2FnZSI6IkF0IGxlYXN0IG9uZSBvZiB0aGUgcHJlLWNvbmRpdGlvbnMgeW91IHNwZWNpZmllZCBkaWQgbm90IGhvbGQuIiwiZG9tYWluIjoiZ2xvYmFsIiwicmVhc29uIjoiY29uZGl0aW9uTm90TWV0IiwibG9jYXRpb25UeXBlIjoiaGVhZGVyIiwibG9jYXRpb24iOiJJZi1NYXRjaCJ9XX19" + } + }, + { + "ID": "f526b45c244df945", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/precondition-key/rewriteTo/b/go-cloud-blob-test-bucket/o/precondition-key2?alt=json\u0026prettyPrint=false\u0026projection=full\u0026sourceGeneration=9999999", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "215" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:25 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH88j7DUQgkjkLqKQjBtljUZwF5evbeT424MJ8vBCvEdHa9l3K72kbF-mOB4V44W6Hb4pHD74bgk" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjo0MDQsIm1lc3NhZ2UiOiJObyBzdWNoIG9iamVjdDogZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9wcmVjb25kaXRpb24ta2V5IiwiZXJyb3JzIjpbeyJtZXNzYWdlIjoiTm8gc3VjaCBvYmplY3Q6IGdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvcHJlY29uZGl0aW9uLWtleSIsImRvbWFpbiI6Imdsb2JhbCIsInJlYXNvbiI6Im5vdEZvdW5kIn1dfX0=" + } + }, + { + "ID": "cb3d7bb65a2cb992", + "Request": { + "Method": "POST", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/precondition-key/rewriteTo/b/go-cloud-blob-test-bucket/o/precondition-key2?alt=json\u0026ifGenerationMatch=0\u0026prettyPrint=false\u0026projection=full\u0026sourceGeneration=1752876504996860", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "3" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "e30K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "900" + ], + "Content-Type": [ + "application/json; charset=UTF-8" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:25 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8-i6rv57ca1zCYbsWPQxugKxjBe3Fl_YEPEIhUhaKXa3rkq-6IPLpxcD_RMFbXWf4R1qwc08RA" + ] + }, + "Body": "eyJraW5kIjoic3RvcmFnZSNyZXdyaXRlUmVzcG9uc2UiLCJ0b3RhbEJ5dGVzUmV3cml0dGVuIjoiMTEiLCJvYmplY3RTaXplIjoiMTEiLCJkb25lIjp0cnVlLCJyZXNvdXJjZSI6eyJraW5kIjoic3RvcmFnZSNvYmplY3QiLCJpZCI6ImdvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvcHJlY29uZGl0aW9uLWtleTIvMTc1Mjg3NjUwNTc3NjY0OCIsInNlbGZMaW5rIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vc3RvcmFnZS92MS9iL2dvLWNsb3VkLWJsb2ItdGVzdC1idWNrZXQvby9wcmVjb25kaXRpb24ta2V5MiIsIm1lZGlhTGluayI6Imh0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9kb3dubG9hZC9zdG9yYWdlL3YxL2IvZ28tY2xvdWQtYmxvYi10ZXN0LWJ1Y2tldC9vL3ByZWNvbmRpdGlvbi1rZXkyP2dlbmVyYXRpb249MTc1Mjg3NjUwNTc3NjY0OCZhbHQ9bWVkaWEiLCJuYW1lIjoicHJlY29uZGl0aW9uLWtleTIiLCJidWNrZXQiOiJnby1jbG91ZC1ibG9iLXRlc3QtYnVja2V0IiwiZ2VuZXJhdGlvbiI6IjE3NTI4NzY1MDU3NzY2NDgiLCJtZXRhZ2VuZXJhdGlvbiI6IjEiLCJjb250ZW50VHlwZSI6InRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgiLCJzdG9yYWdlQ2xhc3MiOiJSRUdJT05BTCIsInNpemUiOiIxMSIsIm1kNUhhc2giOiJYclk3dStBZTd0Q1R5eUs3ajFyTnd3PT0iLCJjcmMzMmMiOiJ5WlJscWc9PSIsImV0YWciOiJDSWlFMmV1MXg0NERFQUU9IiwidGltZUNyZWF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjI1Ljc3OVoiLCJ1cGRhdGVkIjoiMjAyNS0wNy0xOFQyMjowODoyNS43NzlaIiwidGltZVN0b3JhZ2VDbGFzc1VwZGF0ZWQiOiIyMDI1LTA3LTE4VDIyOjA4OjI1Ljc3OVoiLCJ0aW1lRmluYWxpemVkIjoiMjAyNS0wNy0xOFQyMjowODoyNS43NzlaIn19" + } + }, + { + "ID": "c3dd07ce5f37465a", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/precondition-key2?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:25 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_6lF95uIkAab3Z-zPJZ0FybWP12Vj-Pp5a7Gri40vNMKg0WMFQIXEiJycTLj1fqx9J3XWCygI" + ] + }, + "Body": "" + } + }, + { + "ID": "a49fcb9a8997fdc7", + "Request": { + "Method": "DELETE", + "URL": "https://storage.googleapis.com/storage/v1/b/go-cloud-blob-test-bucket/o/precondition-key?alt=json\u0026prettyPrint=false", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Goog-Gcs-Idempotency-Token": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, max-age=0, must-revalidate" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Fri, 18 Jul 2025 22:08:26 GMT" + ], + "Expires": [ + "CLEARED" + ], + "Pragma": [ + "no-cache" + ], + "Server": [ + "UploadServer" + ], + "Vary": [ + "Origin", + "X-Origin" + ], + "X-Guploader-Uploadid": [ + "ABgVH8_EPYU1xZW_SJyWzjAVr5AK2_xiyw87fofXxJ7MG3lo6_sC4PkH2SwgP9_mQeiVz23WPR3AWZc" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/memblob/example_test.go b/go-cloud/blob/memblob/example_test.go new file mode 100644 index 000000000..1b1b190b9 --- /dev/null +++ b/go-cloud/blob/memblob/example_test.go @@ -0,0 +1,72 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 memblob_test + +import ( + "context" + "fmt" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/memblob" +) + +func ExampleOpenBucket() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Create an in-memory bucket. + bucket := memblob.OpenBucket(nil) + defer bucket.Close() + + // Now we can use bucket to read or write files to the bucket. + err := bucket.WriteAll(ctx, "my-key", []byte("hello world"), nil) + if err != nil { + log.Fatal(err) + } + data, err := bucket.ReadAll(ctx, "my-key") + if err != nil { + log.Fatal(err) + } + fmt.Println(string(data)) + + // Output: + // hello world +} + +func Example_openBucketFromURL() { + // blob.OpenBucket creates a *blob.Bucket from a URL. + b, err := blob.OpenBucket(context.Background(), "mem://") + if err != nil { + log.Fatal(err) + } + defer b.Close() + + // Now we can use b to read or write files to the container. + ctx := context.Background() + err = b.WriteAll(ctx, "my-key", []byte("hello world"), nil) + if err != nil { + log.Fatal(err) + } + data, err := b.ReadAll(ctx, "my-key") + if err != nil { + log.Fatal(err) + } + fmt.Println(string(data)) + + // Output: + // hello world +} diff --git a/go-cloud/blob/memblob/memblob.go b/go-cloud/blob/memblob/memblob.go new file mode 100644 index 000000000..70e042000 --- /dev/null +++ b/go-cloud/blob/memblob/memblob.go @@ -0,0 +1,429 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 memblob provides an in-memory blob implementation. +// Use OpenBucket to construct a *blob.Bucket. +// +// # URLs +// +// For blob.OpenBucket memblob registers for the scheme "mem". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// memblob does not support any types for As. +package memblob // import "gocloud.dev/blob/memblob" + +import ( + "bytes" + "context" + "crypto/md5" + "errors" + "fmt" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "hash" + "io" + "net/url" + "sort" + "strings" + "sync" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +const defaultPageSize = 1000 + +var ( + errNotFound = errors.New("blob not found") + errNotImplemented = errors.New("not implemented") +) + +func init() { + blob.DefaultURLMux().RegisterBucket(Scheme, &URLOpener{}) +} + +// Scheme is the URL scheme memblob registers its URLOpener under on +// blob.DefaultMux. +const Scheme = "mem" + +// URLOpener opens URLs like "mem://". +// +// The following query parameters are supported: +// - nomd5: Sets Options.MD5 to true; no value expected (e.g., "memblob://?nomd5"). +type URLOpener struct{} + +// OpenBucketURL opens a blob.Bucket based on u. +func (*URLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) { + opts := Options{} + for param := range u.Query() { + if param == "nomd5" { + opts.NoMD5 = true + continue + } + return nil, fmt.Errorf("open bucket %v: invalid query parameter %q", u, param) + } + return OpenBucket(&opts), nil +} + +// Options sets options for constructing a *blob.Bucket backed by memory. +type Options struct { + // Set to true to disable MD5 hashing. The MD5 Attribute won't be available, + // but improves write performance. + NoMD5 bool +} + +type blobEntry struct { + Content []byte + Attributes *driver.Attributes +} + +type bucket struct { + options Options + + mu sync.Mutex + blobs map[string]*blobEntry +} + +// openBucket creates a driver.Bucket backed by memory. +func openBucket(opts *Options) driver.Bucket { + if opts == nil { + opts = &Options{} + } + return &bucket{ + options: *opts, + blobs: map[string]*blobEntry{}, + } +} + +// OpenBucket creates a *blob.Bucket backed by memory. +func OpenBucket(opts *Options) *blob.Bucket { + return blob.NewBucket(openBucket(opts)) +} + +func (b *bucket) Close() error { + return nil +} + +func (b *bucket) ErrorCode(err error) gcerrors.ErrorCode { + switch err { + case errNotFound: + return gcerrors.NotFound + case errNotImplemented: + return gcerrors.Unimplemented + default: + return gcerrors.Unknown + } +} + +// ListPaged implements driver.ListPaged. +// The implementation largely mirrors the one in fileblob. +func (b *bucket) ListPaged(ctx context.Context, opts *driver.ListOptions) (*driver.ListPage, error) { + b.mu.Lock() + defer b.mu.Unlock() + + // pageToken is a returned NextPageToken, set below; it's the last key of the + // previous page. + var pageToken string + if len(opts.PageToken) > 0 { + pageToken = string(opts.PageToken) + } + pageSize := opts.PageSize + if pageSize == 0 { + pageSize = defaultPageSize + } + + var keys []string + for key := range b.blobs { + keys = append(keys, key) + } + sort.Strings(keys) + + // If opts.Delimiter != "", lastPrefix contains the last "directory" key we + // added. It is used to avoid adding it again; all files in this "directory" + // are collapsed to the single directory entry. + var lastPrefix string + var result driver.ListPage + for _, key := range keys { + // Skip keys that don't match the Prefix. + if !strings.HasPrefix(key, opts.Prefix) { + continue + } + + entry := b.blobs[key] + obj := &driver.ListObject{ + Key: key, + ModTime: entry.Attributes.ModTime, + Size: entry.Attributes.Size, + MD5: entry.Attributes.MD5, + } + + // If using Delimiter, collapse "directories". + if opts.Delimiter != "" { + // Strip the prefix, which may contain Delimiter. + keyWithoutPrefix := key[len(opts.Prefix):] + // See if the key still contains Delimiter. + // If no, it's a file and we just include it. + // If yes, it's a file in a "sub-directory" and we want to collapse + // all files in that "sub-directory" into a single "directory" result. + if idx := strings.Index(keyWithoutPrefix, opts.Delimiter); idx != -1 { + prefix := opts.Prefix + keyWithoutPrefix[0:idx+len(opts.Delimiter)] + // We've already included this "directory"; don't add it. + if prefix == lastPrefix { + continue + } + // Update the object to be a "directory". + obj = &driver.ListObject{ + Key: prefix, + IsDir: true, + } + lastPrefix = prefix + } + } + + // If there's a pageToken, skip anything before it. + if pageToken != "" && obj.Key <= pageToken { + continue + } + + // If we've already got a full page of results, set NextPageToken and return. + if len(result.Objects) == pageSize { + result.NextPageToken = []byte(result.Objects[pageSize-1].Key) + return &result, nil + } + result.Objects = append(result.Objects, obj) + } + return &result, nil +} + +// As implements driver.As. +func (b *bucket) As(i any) bool { return false } + +// As implements driver.ErrorAs. +func (b *bucket) ErrorAs(err error, i any) bool { return false } + +// Attributes implements driver.Attributes. +func (b *bucket) Attributes(ctx context.Context, key string) (*driver.Attributes, error) { + b.mu.Lock() + defer b.mu.Unlock() + + entry, found := b.blobs[key] + if !found { + return nil, errNotFound + } + return entry.Attributes, nil +} + +// NewRangeReader implements driver.NewRangeReader. +func (b *bucket) NewRangeReader(ctx context.Context, key string, offset, length int64, opts *driver.ReaderOptions) (driver.Reader, error) { + b.mu.Lock() + defer b.mu.Unlock() + + entry, found := b.blobs[key] + if !found { + return nil, errNotFound + } + + if opts.BeforeRead != nil { + if err := opts.BeforeRead(func(any) bool { return false }); err != nil { + return nil, err + } + } + r := bytes.NewReader(entry.Content) + if offset > 0 { + if _, err := r.Seek(offset, io.SeekStart); err != nil { + return nil, err + } + } + var ior io.Reader = r + if length >= 0 { + ior = io.LimitReader(r, length) + } + return &reader{ + r: ior, + attrs: driver.ReaderAttributes{ + ContentType: entry.Attributes.ContentType, + ModTime: entry.Attributes.ModTime, + Size: entry.Attributes.Size, + }, + }, nil +} + +type reader struct { + r io.Reader + attrs driver.ReaderAttributes +} + +func (r *reader) Read(p []byte) (int, error) { + return r.r.Read(p) +} + +func (r *reader) Download(w io.Writer) error { + // This should always work because r.r was created from a bytes.Reader. + // It's only not a WriterTo when we wrap it with a LimitReader, + // which is guaranteed not to happen by the driver interface. + _, err := r.r.(io.WriterTo).WriteTo(w) + return err +} + +func (r *reader) Close() error { + return nil +} + +func (r *reader) Attributes() *driver.ReaderAttributes { + return &r.attrs +} + +func (r *reader) As(i any) bool { return false } + +// NewTypedWriter implements driver.NewTypedWriter. +func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType string, opts *driver.WriterOptions) (driver.Writer, error) { + if key == "" { + return nil, errors.New("invalid key (empty string)") + } + b.mu.Lock() + defer b.mu.Unlock() + + if opts.BeforeWrite != nil { + if err := opts.BeforeWrite(func(any) bool { return false }); err != nil { + return nil, err + } + } + md := map[string]string{} + for k, v := range opts.Metadata { + md[k] = v + } + + var md5hash hash.Hash + if !b.options.NoMD5 { + md5hash = md5.New() + } + return &writer{ + ctx: ctx, + b: b, + key: key, + contentType: contentType, + metadata: md, + opts: opts, + md5hash: md5hash, + ifNotExist: opts.IfNotExist, + }, nil +} + +type writer struct { + ctx context.Context + b *bucket + key string + contentType string + metadata map[string]string + opts *driver.WriterOptions + buf bytes.Buffer + // We compute the MD5 hash so that we can store it with the file attributes, + // not for verification. May be null if disabled via Options.NoMD5. + md5hash hash.Hash + ifNotExist bool +} + +func (w *writer) Write(p []byte) (n int, err error) { + if w.md5hash != nil { + if _, err := w.md5hash.Write(p); err != nil { + return 0, err + } + } + return w.buf.Write(p) +} + +func (w *writer) Upload(r io.Reader) error { + _, err := w.buf.ReadFrom(r) + return err +} + +func (w *writer) Close() error { + // Check if the write was cancelled. + if err := w.ctx.Err(); err != nil { + return err + } + + var md5sum []byte + if w.md5hash != nil { + md5sum = w.md5hash.Sum(nil) + } + content := w.buf.Bytes() + now := time.Now() + entry := &blobEntry{ + Content: content, + Attributes: &driver.Attributes{ + CacheControl: w.opts.CacheControl, + ContentDisposition: w.opts.ContentDisposition, + ContentEncoding: w.opts.ContentEncoding, + ContentLanguage: w.opts.ContentLanguage, + ContentType: w.contentType, + Metadata: w.metadata, + Size: int64(len(content)), + CreateTime: now, + ModTime: now, + MD5: md5sum, + ETag: fmt.Sprintf("\"%x-%x\"", now.UnixNano(), len(content)), + }, + } + w.b.mu.Lock() + defer w.b.mu.Unlock() + if prev := w.b.blobs[w.key]; prev != nil { + if w.ifNotExist { + err := fmt.Errorf("a blob already exists for key %q", w.key) + return gcerr.New(gcerrors.FailedPrecondition, err, 1, "IfNotExist precondition failed") + } + entry.Attributes.CreateTime = prev.Attributes.CreateTime + } + w.b.blobs[w.key] = entry + return nil +} + +// Copy implements driver.Copy. +func (b *bucket) Copy(ctx context.Context, dstKey, srcKey string, opts *driver.CopyOptions) error { + b.mu.Lock() + defer b.mu.Unlock() + + if opts.BeforeCopy != nil { + if err := opts.BeforeCopy(func(any) bool { return false }); err != nil { + return err + } + } + v := b.blobs[srcKey] + if v == nil { + return errNotFound + } + b.blobs[dstKey] = v + return nil +} + +// Delete implements driver.Delete. +func (b *bucket) Delete(ctx context.Context, key string) error { + b.mu.Lock() + defer b.mu.Unlock() + + if b.blobs[key] == nil { + return errNotFound + } + delete(b.blobs, key) + return nil +} + +func (b *bucket) SignedURL(ctx context.Context, key string, opts *driver.SignedURLOptions) (string, error) { + return "", errNotImplemented +} diff --git a/go-cloud/blob/memblob/memblob_test.go b/go-cloud/blob/memblob/memblob_test.go new file mode 100644 index 000000000..71fa7ad55 --- /dev/null +++ b/go-cloud/blob/memblob/memblob_test.go @@ -0,0 +1,104 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 memblob + +import ( + "context" + "net/http" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/blob/drivertest" +) + +type harness struct { + prefix string +} + +func newHarness(ctx context.Context, t *testing.T, prefix string) (drivertest.Harness, error) { + t.Helper() + + return &harness{prefix: prefix}, nil +} + +func (h *harness) HTTPClient() *http.Client { + return nil +} + +func (h *harness) MakeDriver(ctx context.Context) (driver.Bucket, error) { + drv := openBucket(nil) + if h.prefix == "" { + return drv, nil + } + return driver.NewPrefixedBucket(drv, h.prefix), nil +} + +func (h *harness) MakeDriverForNonexistentBucket(ctx context.Context) (driver.Bucket, error) { + // Does not make sense for this driver. + return nil, nil +} + +func (h *harness) Close() {} + +func TestConformance(t *testing.T) { + newHarnessNoPrefix := func(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return newHarness(ctx, t, "") + } + drivertest.RunConformanceTests(t, newHarnessNoPrefix, nil) +} + +func TestConformanceWithPrefix(t *testing.T) { + const prefix = "some/prefix/dir/" + newHarnessWithPrefix := func(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return newHarness(ctx, t, prefix) + } + drivertest.RunConformanceTests(t, newHarnessWithPrefix, nil) +} + +func BenchmarkMemblob(b *testing.B) { + drivertest.RunBenchmarks(b, OpenBucket(nil)) +} + +func TestOpenBucketFromURL(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"mem://", false}, + // NoMD5. + {"mem://?nomd5", false}, + // With prefix. + {"mem://?prefix=foo/bar", false}, + // Invalid parameter. + {"mem://?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + b, err := blob.OpenBucket(ctx, test.URL) + if b != nil { + defer b.Close() + } + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + } +} diff --git a/go-cloud/blob/otel_test.go b/go-cloud/blob/otel_test.go new file mode 100644 index 000000000..fb20e2fda --- /dev/null +++ b/go-cloud/blob/otel_test.go @@ -0,0 +1,115 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 blob_test + +import ( + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/memblob" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/oteltest" + "testing" +) + +func TestOpenTelemetry(t *testing.T) { + ctx := t.Context() + + te := oteltest.NewTestExporter(t, blob.OpenTelemetryViews) + defer func() { _ = te.Shutdown(ctx) }() + + bytes := []byte("hello world") + b := memblob.OpenBucket(nil) + defer func() { _ = b.Close() }() + + if err := b.WriteAll(ctx, "key", bytes, nil); err != nil { + t.Fatal(err) + } + if _, err := b.ReadAll(ctx, "key"); err != nil { + t.Fatal(err) + } + if _, err := b.Attributes(ctx, "key"); err != nil { + t.Fatal(err) + } + if _, _, err := b.ListPage(ctx, blob.FirstPageToken, 3, nil); err != nil { + t.Fatal(err) + } + if err := b.Delete(ctx, "key"); err != nil { + t.Fatal(err) + } + if _, err := b.ReadAll(ctx, "noSuchKey"); err == nil { + t.Fatal("got nil, want error") + } + + const driver = "gocloud.dev/blob/memblob" + + spans := te.GetSpans() + metrics := te.GetMetrics(ctx) + + diff := oteltest.Diff(spans.Snapshots(), metrics, "gocloud.dev/blob", driver, []oteltest.Call{ + {Method: "NewWriter", Code: gcerrors.OK}, + {Method: "NewRangeReader", Code: gcerrors.OK}, + {Method: "Attributes", Code: gcerrors.OK}, + {Method: "ListPage", Code: gcerrors.OK}, + {Method: "Delete", Code: gcerrors.OK}, + {Method: "NewRangeReader", Code: gcerrors.NotFound}, + }) + if diff != "" { + t.Error(diff) + } + + // Find and verify the bytes read/written metrics. + var sawRead, sawWritten bool + providerAttr := attribute.Key("gocdk_provider") + + for _, sm := range metrics { + + for _, data := range sm.Metrics { + + switch data.Name { + case "gocloud.dev/blob/bytes_read": + if sawRead { + continue + } + sawRead = true + case "gocloud.dev/blob/bytes_written": + if sawWritten { + continue + } + sawWritten = true + default: + continue + } + + providerVal, ok := sm.Scope.Attributes.Value(providerAttr) + if !ok || providerVal.AsString() != driver { + t.Errorf("provider tags for %s is : %s instead of :%s", data.Name, providerVal.AsString(), driver) + continue + } + sd, ok := data.Data.(metricdata.Sum[int64]) + if !ok { + t.Errorf("%s: data is %T, want SumData", data.Name, data.Data) + continue + } + if got := int(sd.DataPoints[0].Value); got < len(bytes) { + t.Errorf("%s: got %d, want at least %d", data.Name, got, len(bytes)) + } + + if sawRead && sawWritten { + return + } + } + } +} diff --git a/go-cloud/blob/s3blob/example_test.go b/go-cloud/blob/s3blob/example_test.go new file mode 100644 index 000000000..0b5b1161f --- /dev/null +++ b/go-cloud/blob/s3blob/example_test.go @@ -0,0 +1,60 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 s3blob_test + +import ( + "context" + "log" + + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/s3blob" +) + +func ExampleOpenBucket() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Establish a AWS Config. + // See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info. + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + log.Fatal(err) + } + + // Create a *blob.Bucket. + client := s3.NewFromConfig(cfg) + bucket, err := s3blob.OpenBucket(ctx, client, "my-bucket", nil) + if err != nil { + log.Fatal(err) + } + defer bucket.Close() +} + +func Example_openBucketFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/blob/s3blob" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // blob.OpenBucket creates a *blob.Bucket from a URL. + bucket, err := blob.OpenBucket(ctx, "s3://my-bucket?region=us-west-1") + if err != nil { + log.Fatal(err) + } + defer bucket.Close() +} diff --git a/go-cloud/blob/s3blob/s3blob.go b/go-cloud/blob/s3blob/s3blob.go new file mode 100644 index 000000000..d105f0671 --- /dev/null +++ b/go-cloud/blob/s3blob/s3blob.go @@ -0,0 +1,917 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 s3blob provides a blob implementation that uses S3. Use OpenBucket +// to construct a *blob.Bucket. +// +// # URLs +// +// For blob.OpenBucket, s3blob registers for the scheme "s3". +// The default URL opener will use an AWS session with the default credentials +// and configuration. +// +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # Escaping +// +// Go CDK supports all UTF-8 strings; to make this work with services lacking +// full UTF-8 support, strings must be escaped (during writes) and unescaped +// (during reads). The following escapes are performed for s3blob: +// - Blob keys: ASCII characters 0-31 are escaped to "__0x__". +// Additionally, the "/" in "../" is escaped in the same way. +// - Metadata keys: Escaped using URL encoding, then additionally "@:=" are +// escaped using "__0x__". These characters were determined by +// experimentation. +// - Metadata values: Escaped using URL encoding. +// +// # As +// +// s3blob exposes the following types for As: +// - Bucket: *s3.Client +// - Error: any error type returned by the service, notably smithy.APIError +// - ListObject: types.Object for objects, types.CommonPrefix for "directories" +// - ListOptions.BeforeList: *s3.ListObjectsV2Input or *[]func(*s3.Options), or *s3.ListObjectsInput +// when Options.UseLegacyList == true +// - Reader: s3.GetObjectOutput +// - ReaderOptions.BeforeRead: *s3.GetObjectInput or *[]func(*s3.Options) +// - Attributes: s3.HeadObjectOutput +// - CopyOptions.BeforeCopy: s3.CopyObjectInput +// - WriterOptions.BeforeWrite: *s3.PutObjectInput, *s3manager.Uploader +// - SignedURLOptions.BeforeSign: *s3.GetObjectInput, when Options.Method == http.MethodGet, or +// *s3.PutObjectInput, when Options.Method == http.MethodPut + +package s3blob // import "gocloud.dev/blob/s3blob" + +import ( + "context" + "encoding/base64" + "encoding/hex" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + + "github.com/aws/aws-sdk-go-v2/aws" + s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/aws/smithy-go" + "github.com/google/wire" + gcaws "github.com/DataDog/iceberg-go/go-cloud/aws" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/escape" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +const defaultPageSize = 1000 + +func init() { + blob.DefaultURLMux().RegisterBucket(Scheme, new(urlSessionOpener)) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + Dial, +) + +// Dial gets an AWS S3 service client using the AWS SDK V2. +func Dial(cfg aws.Config) *s3.Client { + return s3.NewFromConfig(cfg) +} + +type urlSessionOpener struct{} + +func (o *urlSessionOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) { + opener := &URLOpener{} + return opener.OpenBucketURL(ctx, u) +} + +// Scheme is the URL scheme s3blob registers its URLOpener under on +// blob.DefaultMux. +const Scheme = "s3" + +// URLOpener opens S3 URLs like "s3://mybucket". +// +// The URL host is used as the bucket name. +// +// See https://pkg.go.dev/gocloud.dev/aws#V2ConfigFromURLParams. +// +// The following S3-specific query options are also supported: +// - ssetype: The type of server side encryption used (AES256, aws:kms, aws:kms:dsse) +// - kmskeyid: The KMS key ID for server side encryption +// - accelerate: A value of "true" uses the S3 Transfer Accleration endpoints +// - use_path_style: A value of true sets the UsePathStyle option. +// - s3ForcePathStyle: Same as use_path_style, for backwards compatibility with V1. +// - disable_https: A value of true disables HTTPS in the Endpoint options. +type URLOpener struct { + // Options specifies the options to pass to OpenBucket. + Options Options +} + +const ( + sseTypeParamKey = "ssetype" + kmsKeyIdParamKey = "kmskeyid" + accelerateParamKey = "accelerate" + usePathStyleParamKey = "use_path_style" + legacyUsePathStyleParamKey = "s3ForcePathStyle" // for backwards compatibility + disableHTTPSParamKey = "disable_https" +) + +func toServerSideEncryptionType(value string) (types.ServerSideEncryption, error) { + for _, sseType := range types.ServerSideEncryptionAes256.Values() { + if strings.EqualFold(string(sseType), value) { + return sseType, nil + } + } + return "", fmt.Errorf("%q is not a valid value for %q", value, sseTypeParamKey) +} + +// OpenBucketURL opens a blob.Bucket based on u. +func (o *URLOpener) OpenBucketURL(ctx context.Context, u *url.URL) (*blob.Bucket, error) { + q := u.Query() + + if sseTypeParam := q.Get(sseTypeParamKey); sseTypeParam != "" { + q.Del(sseTypeParamKey) + + sseType, err := toServerSideEncryptionType(sseTypeParam) + if err != nil { + return nil, err + } + + o.Options.EncryptionType = sseType + } + + if kmsKeyID := q.Get(kmsKeyIdParamKey); kmsKeyID != "" { + q.Del(kmsKeyIdParamKey) + o.Options.KMSEncryptionID = kmsKeyID + } + + accelerate := false + if accelerateParam := q.Get(accelerateParamKey); accelerateParam != "" { + q.Del(accelerateParamKey) + var err error + accelerate, err = strconv.ParseBool(accelerateParam) + if err != nil { + return nil, fmt.Errorf("invalid value for %q: %v", accelerateParamKey, err) + } + } + + opts := []func(*s3.Options){ + func(o *s3.Options) { + o.UseAccelerate = accelerate + }, + } + if disableHTTPSParam := q.Get(disableHTTPSParamKey); disableHTTPSParam != "" { + q.Del(disableHTTPSParamKey) + value, err := strconv.ParseBool(disableHTTPSParam) + if err != nil { + return nil, fmt.Errorf("invalid value for %q: %v", disableHTTPSParamKey, err) + } + opts = append(opts, func(o *s3.Options) { + o.EndpointOptions.DisableHTTPS = value + }) + } + for _, key := range []string{usePathStyleParamKey, legacyUsePathStyleParamKey} { + if usePathStyleParam := q.Get(key); usePathStyleParam != "" { + q.Del(key) + value, err := strconv.ParseBool(usePathStyleParam) + if err != nil { + return nil, fmt.Errorf("invalid value for %q: %v", key, err) + } + opts = append(opts, func(o *s3.Options) { + o.UsePathStyle = value + }) + } + } + + cfg, err := gcaws.V2ConfigFromURLParams(ctx, q) + if err != nil { + return nil, fmt.Errorf("open bucket %v: %v", u, err) + } + client := s3.NewFromConfig(cfg, opts...) + + return OpenBucket(ctx, client, u.Host, &o.Options) +} + +// Options sets options for constructing a *blob.Bucket backed by fileblob. +type Options struct { + // UseLegacyList forces the use of ListObjects instead of ListObjectsV2. + // Some S3-compatible services (like CEPH) do not currently support + // ListObjectsV2. + UseLegacyList bool + + // EncryptionType sets the encryption type headers when making write or + // copy calls. This is required if the bucket has a restrictive bucket + // policy that enforces a specific encryption type + EncryptionType types.ServerSideEncryption + + // KMSEncryptionID sets the kms key id header for write or copy calls. + // This is required when a bucket policy enforces the use of a specific + // KMS key for uploads + KMSEncryptionID string +} + +// openBucket returns an S3 Bucket. +func openBucket(ctx context.Context, client *s3.Client, bucketName string, opts *Options) (*bucket, error) { + if bucketName == "" { + return nil, errors.New("s3blob.OpenBucket: bucketName is required") + } + if opts == nil { + opts = &Options{} + } + if client == nil { + return nil, errors.New("s3blob.OpenBucket: client is required") + } + return &bucket{ + name: bucketName, + client: client, + useLegacyList: opts.UseLegacyList, + kmsKeyId: opts.KMSEncryptionID, + encryptionType: opts.EncryptionType, + }, nil +} + +// OpenBucket returns a *blob.Bucket backed by S3, using AWS SDK v2. +func OpenBucket(ctx context.Context, client *s3.Client, bucketName string, opts *Options) (*blob.Bucket, error) { + drv, err := openBucket(ctx, client, bucketName, opts) + if err != nil { + return nil, err + } + return blob.NewBucket(drv), nil +} + +var OpenBucketV2 = OpenBucket + +// reader reads an S3 object. It implements io.ReadCloser. +type reader struct { + body io.ReadCloser + attrs driver.ReaderAttributes + raw *s3.GetObjectOutput +} + +func (r *reader) Read(p []byte) (int, error) { + return r.body.Read(p) +} + +// Close closes the reader itself. It must be called when done reading. +func (r *reader) Close() error { + return r.body.Close() +} + +func (r *reader) As(i any) bool { + p, ok := i.(*s3.GetObjectOutput) + if !ok { + return false + } + *p = *r.raw + return true +} + +func (r *reader) Attributes() *driver.ReaderAttributes { + return &r.attrs +} + +// writer writes an S3 object, it implements io.WriteCloser. +type writer struct { + // Ends of an io.Pipe, created when the first byte is written. + pw *io.PipeWriter + pr *io.PipeReader + + // Alternatively, upload is set to true when Upload was + // used to upload data. + upload bool + + ctx context.Context + uploader *s3manager.Uploader + req *s3.PutObjectInput + + donec chan struct{} // closed when done writing + // The following fields will be written before donec closes: + err error +} + +// Write appends p to w.pw. User must call Close to close the w after done writing. +func (w *writer) Write(p []byte) (int, error) { + // Avoid opening the pipe for a zero-length write; + // the concrete can do these for empty blobs. + if len(p) == 0 { + return 0, nil + } + if w.pw == nil { + // We'll write into pw and use pr as an io.Reader for the + // Upload call to S3. + w.pr, w.pw = io.Pipe() + w.open(w.pr, true) + } + return w.pw.Write(p) +} + +// Upload reads from r. Per the driver, it is guaranteed to be the only +// write call for this writer. +func (w *writer) Upload(r io.Reader) error { + w.upload = true + w.open(r, false) + return nil +} + +// r may be nil if we're Closing and no data was written. +// If closePipeOnError is true, w.pr will be closed if there's an +// error uploading to S3. +func (w *writer) open(r io.Reader, closePipeOnError bool) { + // This goroutine will keep running until Close, unless there's an error. + go func() { + defer close(w.donec) + + if r == nil { + // AWS doesn't like a nil Body. + r = http.NoBody + } + var err error + w.req.Body = r + _, err = w.uploader.Upload(w.ctx, w.req) + if err != nil { + if closePipeOnError { + w.pr.CloseWithError(err) + } + w.err = err + } + }() +} + +// Close completes the writer and closes it. Any error occurring during write +// will be returned. If a writer is closed before any Write is called, Close +// will create an empty file at the given key. +func (w *writer) Close() error { + if !w.upload { + if w.pr != nil { + defer w.pr.Close() + } + if w.pw == nil { + // We never got any bytes written. We'll write an http.NoBody. + w.open(nil, false) + } else if err := w.pw.Close(); err != nil { + return err + } + } + <-w.donec + return w.err +} + +// bucket represents an S3 bucket and handles read, write and delete operations. +type bucket struct { + name string + client *s3.Client + useLegacyList bool + + encryptionType types.ServerSideEncryption + kmsKeyId string +} + +func (b *bucket) Close() error { + return nil +} + +func (b *bucket) ErrorCode(err error) gcerrors.ErrorCode { + var code string + var ae smithy.APIError + var oe *smithy.OperationError + if errors.As(err, &oe) && strings.Contains(oe.Error(), "301") { + // AWS returns an OperationError with a missing redirect for invalid buckets. + code = "NoSuchBucket" + } else if errors.As(err, &ae) { + code = ae.ErrorCode() + } else { + return gcerrors.Unknown + } + switch { + case code == "NoSuchBucket" || code == "NoSuchKey" || code == "NotFound" || code == "ObjectNotInActiveTierError": + return gcerrors.NotFound + case code == "PreconditionFailed": + return gcerrors.FailedPrecondition + default: + return gcerrors.Unknown + } +} + +// ListPaged implements driver.ListPaged. +func (b *bucket) ListPaged(ctx context.Context, opts *driver.ListOptions) (*driver.ListPage, error) { + pageSize := opts.PageSize + if pageSize == 0 { + pageSize = defaultPageSize + } + in := &s3.ListObjectsV2Input{ + Bucket: aws.String(b.name), + MaxKeys: aws.Int32(int32(pageSize)), + } + if len(opts.PageToken) > 0 { + in.ContinuationToken = aws.String(string(opts.PageToken)) + } + if opts.Prefix != "" { + in.Prefix = aws.String(escapeKey(opts.Prefix)) + } + if opts.Delimiter != "" { + in.Delimiter = aws.String(escapeKey(opts.Delimiter)) + } + resp, err := b.listObjects(ctx, in, opts) + if err != nil { + return nil, err + } + page := driver.ListPage{} + if resp.NextContinuationToken != nil { + page.NextPageToken = []byte(*resp.NextContinuationToken) + } + if n := len(resp.Contents) + len(resp.CommonPrefixes); n > 0 { + page.Objects = make([]*driver.ListObject, n) + for i, obj := range resp.Contents { + obj := obj + page.Objects[i] = &driver.ListObject{ + Key: unescapeKey(aws.ToString(obj.Key)), + ModTime: *obj.LastModified, + Size: aws.ToInt64(obj.Size), + MD5: eTagToMD5(obj.ETag), + AsFunc: func(i any) bool { + p, ok := i.(*types.Object) + if !ok { + return false + } + *p = obj + return true + }, + } + } + for i, prefix := range resp.CommonPrefixes { + prefix := prefix + page.Objects[i+len(resp.Contents)] = &driver.ListObject{ + Key: unescapeKey(aws.ToString(prefix.Prefix)), + IsDir: true, + AsFunc: func(i any) bool { + p, ok := i.(*types.CommonPrefix) + if !ok { + return false + } + *p = prefix + return true + }, + } + } + if len(resp.Contents) > 0 && len(resp.CommonPrefixes) > 0 { + // S3 gives us blobs and "directories" in separate lists; sort them. + sort.Slice(page.Objects, func(i, j int) bool { + return page.Objects[i].Key < page.Objects[j].Key + }) + } + } + return &page, nil +} + +func (b *bucket) listObjects(ctx context.Context, in *s3.ListObjectsV2Input, opts *driver.ListOptions) (*s3.ListObjectsV2Output, error) { + if !b.useLegacyList { + var varopt []func(*s3.Options) + if opts.BeforeList != nil { + asFunc := func(i any) bool { + if p, ok := i.(**s3.ListObjectsV2Input); ok { + *p = in + return true + } + if p, ok := i.(**[]func(*s3.Options)); ok { + *p = &varopt + return true + } + return false + } + if err := opts.BeforeList(asFunc); err != nil { + return nil, err + } + } + return b.client.ListObjectsV2(ctx, in, varopt...) + } + + // Use the legacy ListObjects request. + legacyIn := &s3.ListObjectsInput{ + Bucket: in.Bucket, + Delimiter: in.Delimiter, + EncodingType: in.EncodingType, + Marker: in.ContinuationToken, + MaxKeys: in.MaxKeys, + Prefix: in.Prefix, + RequestPayer: in.RequestPayer, + } + if opts.BeforeList != nil { + asFunc := func(i any) bool { + p, ok := i.(**s3.ListObjectsInput) + if !ok { + return false + } + *p = legacyIn + return true + } + if err := opts.BeforeList(asFunc); err != nil { + return nil, err + } + } + legacyResp, err := b.client.ListObjects(ctx, legacyIn) + if err != nil { + return nil, err + } + + var nextContinuationToken *string + if legacyResp.NextMarker != nil { + nextContinuationToken = legacyResp.NextMarker + } else if aws.ToBool(legacyResp.IsTruncated) { + nextContinuationToken = aws.String(aws.ToString(legacyResp.Contents[len(legacyResp.Contents)-1].Key)) + } + return &s3.ListObjectsV2Output{ + CommonPrefixes: legacyResp.CommonPrefixes, + Contents: legacyResp.Contents, + NextContinuationToken: nextContinuationToken, + }, nil +} + +// As implements driver.As. +func (b *bucket) As(i any) bool { + p, ok := i.(**s3.Client) + if !ok { + return false + } + *p = b.client + return true +} + +// As implements driver.ErrorAs. +func (b *bucket) ErrorAs(err error, i any) bool { + return errors.As(err, i) +} + +// Attributes implements driver.Attributes. +func (b *bucket) Attributes(ctx context.Context, key string) (*driver.Attributes, error) { + key = escapeKey(key) + in := &s3.HeadObjectInput{ + Bucket: aws.String(b.name), + Key: aws.String(key), + } + resp, err := b.client.HeadObject(ctx, in) + if err != nil { + return nil, err + } + + md := make(map[string]string, len(resp.Metadata)) + for k, v := range resp.Metadata { + // See the package comments for more details on escaping of metadata + // keys & values. + md[escape.HexUnescape(escape.URLUnescape(k))] = escape.URLUnescape(v) + } + return &driver.Attributes{ + CacheControl: aws.ToString(resp.CacheControl), + ContentDisposition: aws.ToString(resp.ContentDisposition), + ContentEncoding: aws.ToString(resp.ContentEncoding), + ContentLanguage: aws.ToString(resp.ContentLanguage), + ContentType: aws.ToString(resp.ContentType), + Metadata: md, + // CreateTime not supported; left as the zero time. + ModTime: aws.ToTime(resp.LastModified), + Size: aws.ToInt64(resp.ContentLength), + MD5: eTagToMD5(resp.ETag), + ETag: aws.ToString(resp.ETag), + AsFunc: func(i any) bool { + p, ok := i.(*s3.HeadObjectOutput) + if !ok { + return false + } + *p = *resp + return true + }, + }, nil +} + +// NewRangeReader implements driver.NewRangeReader. +func (b *bucket) NewRangeReader(ctx context.Context, key string, offset, length int64, opts *driver.ReaderOptions) (driver.Reader, error) { + key = escapeKey(key) + var byteRange *string + if offset > 0 && length < 0 { + byteRange = aws.String(fmt.Sprintf("bytes=%d-", offset)) + } else if length == 0 { + // AWS doesn't support a zero-length read; we'll read 1 byte and then + // ignore it in favor of http.NoBody below. + byteRange = aws.String(fmt.Sprintf("bytes=%d-%d", offset, offset)) + } else if length >= 0 { + byteRange = aws.String(fmt.Sprintf("bytes=%d-%d", offset, offset+length-1)) + } + in := &s3.GetObjectInput{ + Bucket: aws.String(b.name), + Key: aws.String(key), + Range: byteRange, + } + var varopt []func(*s3.Options) + if opts.BeforeRead != nil { + asFunc := func(i any) bool { + if p, ok := i.(**s3.GetObjectInput); ok { + *p = in + return true + } + if p, ok := i.(**[]func(*s3.Options)); ok { + *p = &varopt + return true + } + return false + } + if err := opts.BeforeRead(asFunc); err != nil { + return nil, err + } + } + resp, err := b.client.GetObject(ctx, in, varopt...) + if err != nil { + return nil, err + } + body := resp.Body + if length == 0 { + body = http.NoBody + } + return &reader{ + body: body, + attrs: driver.ReaderAttributes{ + ContentType: aws.ToString(resp.ContentType), + ModTime: aws.ToTime(resp.LastModified), + Size: getSize(aws.ToInt64(resp.ContentLength), aws.ToString(resp.ContentRange)), + }, + raw: resp, + }, nil +} + +// etagToMD5 processes an ETag header and returns an MD5 hash if possible. +// S3's ETag header is sometimes a quoted hexstring of the MD5. Other times, +// notably when the object was uploaded in multiple parts, it is not. +// We do the best we can. +// Some links about ETag: +// https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonResponseHeaders.html +// https://github.com/aws/aws-sdk-net/issues/815 +// https://teppen.io/2018/06/23/aws_s3_etags/ +func eTagToMD5(etag *string) []byte { + if etag == nil { + // No header at all. + return nil + } + // Strip the expected leading and trailing quotes. + quoted := *etag + if len(quoted) < 2 || quoted[0] != '"' || quoted[len(quoted)-1] != '"' { + return nil + } + unquoted := quoted[1 : len(quoted)-1] + // Un-hex; we return nil on error. In particular, we'll get an error here + // for multi-part uploaded blobs, whose ETag will contain a "-" and so will + // never be a legal hex encoding. + md5, err := hex.DecodeString(unquoted) + if err != nil { + return nil + } + return md5 +} + +func getSize(contentLength int64, contentRange string) int64 { + // Default size to ContentLength, but that's incorrect for partial-length reads, + // where ContentLength refers to the size of the returned Body, not the entire + // size of the blob. ContentRange has the full size. + size := contentLength + if contentRange != "" { + // Sample: bytes 10-14/27 (where 27 is the full size). + parts := strings.Split(contentRange, "/") + if len(parts) == 2 { + if i, err := strconv.ParseInt(parts[1], 10, 64); err == nil { + size = i + } + } + } + return size +} + +// escapeKey does all required escaping for UTF-8 strings to work with S3. +func escapeKey(key string) string { + return escape.HexEscape(key, func(r []rune, i int) bool { + c := r[i] + switch { + // S3 doesn't handle these characters (determined via experimentation). + case c < 32: + return true + // For "../", escape the trailing slash. + case i > 1 && c == '/' && r[i-1] == '.' && r[i-2] == '.': + return true + } + return false + }) +} + +// unescapeKey reverses escapeKey. +func unescapeKey(key string) string { + return escape.HexUnescape(key) +} + +// NewTypedWriter implements driver.NewTypedWriter. +func (b *bucket) NewTypedWriter(ctx context.Context, key, contentType string, opts *driver.WriterOptions) (driver.Writer, error) { + key = escapeKey(key) + uploader := s3manager.NewUploader(b.client, func(u *s3manager.Uploader) { + if opts.BufferSize != 0 { + u.PartSize = int64(opts.BufferSize) + } + if opts.MaxConcurrency != 0 { + u.Concurrency = opts.MaxConcurrency + } + }) + md := make(map[string]string, len(opts.Metadata)) + for k, v := range opts.Metadata { + // See the package comments for more details on escaping of metadata + // keys & values. + k = escape.HexEscape(url.PathEscape(k), func(runes []rune, i int) bool { + c := runes[i] + return c == '@' || c == ':' || c == '=' + }) + md[k] = url.PathEscape(v) + } + req := &s3.PutObjectInput{ + Bucket: aws.String(b.name), + ContentType: aws.String(contentType), + Key: aws.String(key), + Metadata: md, + } + + if opts.IfNotExist { + // See https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-writes.html + req.IfNoneMatch = aws.String("*") + } + if opts.CacheControl != "" { + req.CacheControl = aws.String(opts.CacheControl) + } + if opts.ContentDisposition != "" { + req.ContentDisposition = aws.String(opts.ContentDisposition) + } + if opts.ContentEncoding != "" { + req.ContentEncoding = aws.String(opts.ContentEncoding) + } + if opts.ContentLanguage != "" { + req.ContentLanguage = aws.String(opts.ContentLanguage) + } + if len(opts.ContentMD5) > 0 { + req.ContentMD5 = aws.String(base64.StdEncoding.EncodeToString(opts.ContentMD5)) + } + if b.encryptionType != "" { + req.ServerSideEncryption = b.encryptionType + } + if b.kmsKeyId != "" { + req.SSEKMSKeyId = aws.String(b.kmsKeyId) + } + if opts.BeforeWrite != nil { + asFunc := func(i any) bool { + // Note that since the Go CDK Blob + // abstraction does not expose AWS's + // Uploader concept, there does not + // appear to be any utility in + // exposing the options list to the v2 + // Uploader's Upload() method. + // Instead, applications can + // manipulate the exposed *Uploader + // directly, including by setting + // ClientOptions if needed. + if p, ok := i.(**s3manager.Uploader); ok { + *p = uploader + return true + } + if p, ok := i.(**s3.PutObjectInput); ok { + *p = req + return true + } + return false + } + if err := opts.BeforeWrite(asFunc); err != nil { + return nil, err + } + } + return &writer{ + ctx: ctx, + uploader: uploader, + req: req, + donec: make(chan struct{}), + }, nil +} + +// Copy implements driver.Copy. +func (b *bucket) Copy(ctx context.Context, dstKey, srcKey string, opts *driver.CopyOptions) error { + dstKey = escapeKey(dstKey) + srcKey = escapeKey(srcKey) + srcKeyWithBucketEscaped := url.QueryEscape(b.name + "/" + srcKey) + input := &s3.CopyObjectInput{ + Bucket: aws.String(b.name), + CopySource: aws.String(srcKeyWithBucketEscaped), + Key: aws.String(dstKey), + } + if b.encryptionType != "" { + input.ServerSideEncryption = b.encryptionType + } + if b.kmsKeyId != "" { + input.SSEKMSKeyId = aws.String(b.kmsKeyId) + } + if opts.BeforeCopy != nil { + asFunc := func(i any) bool { + switch v := i.(type) { + case **s3.CopyObjectInput: + *v = input + return true + } + return false + } + if err := opts.BeforeCopy(asFunc); err != nil { + return err + } + } + _, err := b.client.CopyObject(ctx, input) + return err +} + +// Delete implements driver.Delete. +func (b *bucket) Delete(ctx context.Context, key string) error { + if _, err := b.Attributes(ctx, key); err != nil { + return err + } + key = escapeKey(key) + input := &s3.DeleteObjectInput{ + Bucket: aws.String(b.name), + Key: aws.String(key), + } + _, err := b.client.DeleteObject(ctx, input) + return err +} + +func (b *bucket) SignedURL(ctx context.Context, key string, opts *driver.SignedURLOptions) (string, error) { + key = escapeKey(key) + switch opts.Method { + case http.MethodGet: + in := &s3.GetObjectInput{ + Bucket: aws.String(b.name), + Key: aws.String(key), + } + if opts.BeforeSign != nil { + asFunc := func(i any) bool { + v, ok := i.(**s3.GetObjectInput) + if ok { + *v = in + } + return ok + } + if err := opts.BeforeSign(asFunc); err != nil { + return "", err + } + } + p, err := s3.NewPresignClient(b.client, s3.WithPresignExpires(opts.Expiry)).PresignGetObject(ctx, in) + if err != nil { + return "", err + } + return p.URL, nil + case http.MethodPut: + in := &s3.PutObjectInput{ + Bucket: aws.String(b.name), + Key: aws.String(key), + } + if opts.EnforceAbsentContentType || opts.ContentType != "" { + // https://github.com/aws/aws-sdk-go-v2/issues/1475 + return "", gcerr.New(gcerr.Unimplemented, nil, 1, "s3blob: AWS SDK v2 does not supported enforcing ContentType in SignedURLs for PUT") + } + if opts.BeforeSign != nil { + asFunc := func(i any) bool { + v, ok := i.(**s3.PutObjectInput) + if ok { + *v = in + } + return ok + } + if err := opts.BeforeSign(asFunc); err != nil { + return "", err + } + } + p, err := s3.NewPresignClient(b.client, s3.WithPresignExpires(opts.Expiry)).PresignPutObject(ctx, in) + if err != nil { + return "", err + } + return p.URL, nil + case http.MethodDelete: + // https://github.com/aws/aws-sdk-java-v2/issues/2520 + return "", gcerr.New(gcerr.Unimplemented, nil, 1, "s3blob: AWS SDK v2 does not support SignedURL for DELETE") + default: + return "", fmt.Errorf("unsupported Method %q", opts.Method) + } +} diff --git a/go-cloud/blob/s3blob/s3blob_test.go b/go-cloud/blob/s3blob/s3blob_test.go new file mode 100644 index 000000000..15db76d23 --- /dev/null +++ b/go-cloud/blob/s3blob/s3blob_test.go @@ -0,0 +1,384 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 s3blob + +import ( + "context" + "errors" + "fmt" + "net/http" + "testing" + + "github.com/aws/aws-sdk-go-v2/aws" + awscfg "github.com/aws/aws-sdk-go-v2/config" + s3manager "github.com/aws/aws-sdk-go-v2/feature/s3/manager" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/aws/smithy-go" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/driver" + "github.com/DataDog/iceberg-go/go-cloud/blob/drivertest" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" +) + +// These constants record the region & bucket used for the last --record. +// If you want to use --record mode, +// 1. Create a bucket in your AWS project from the S3 management console. +// +// https://s3.console.aws.amazon.com/s3/home. +// +// 2. Update this constant to your bucket name. +// TODO(issue #300): Use Terraform to provision a bucket, and get the bucket +// +// name from the Terraform output instead (saving a copy of it for replay). +const ( + bucketName = "go-cloud-testing-2" + region = "us-west-1" +) + +type harness struct { + client *s3.Client + opts *Options + rt http.RoundTripper + closer func() +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + cfg, rt, done, _ := setup.NewAWSv2Config(ctx, t, region, false) + return &harness{client: s3.NewFromConfig(cfg), opts: nil, rt: rt, closer: done}, nil +} + +func newHarnessUsingLegacyList(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + cfg, rt, done, _ := setup.NewAWSv2Config(ctx, t, region, false) + return &harness{client: s3.NewFromConfig(cfg), opts: &Options{UseLegacyList: true}, rt: rt, closer: done}, nil +} + +func (h *harness) HTTPClient() *http.Client { + return &http.Client{Transport: h.rt} +} + +func (h *harness) MakeDriver(ctx context.Context) (driver.Bucket, error) { + return openBucket(ctx, h.client, bucketName, h.opts) +} + +func (h *harness) MakeDriverForNonexistentBucket(ctx context.Context) (driver.Bucket, error) { + return openBucket(ctx, h.client, "go-cdk-bucket-does-not-exist", h.opts) +} + +func (h *harness) Close() { + h.closer() +} + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyContentLanguage{usingLegacyList: false}}) +} + +func TestConformanceUsingLegacyList(t *testing.T) { + drivertest.RunConformanceTests(t, newHarnessUsingLegacyList, []drivertest.AsTest{verifyContentLanguage{usingLegacyList: true}}) +} + +func BenchmarkS3blob(b *testing.B) { + ctx := context.Background() + cfg, err := awscfg.LoadDefaultConfig(ctx) + if err != nil { + b.Fatal(err) + } + client := s3.NewFromConfig(cfg) + bkt, err := OpenBucket(ctx, client, bucketName, nil) + if err != nil { + b.Fatal(err) + } + drivertest.RunBenchmarks(b, bkt) +} + +const language = "nl" + +// verifyContentLanguage uses As to access the underlying AWS types and +// read/write the ContentLanguage field. +type verifyContentLanguage struct { + usingLegacyList bool +} + +func (verifyContentLanguage) Name() string { + return "verify ContentLanguage can be written and read through As" +} + +func (v verifyContentLanguage) BucketCheck(b *blob.Bucket) error { + var client *s3.Client + if !b.As(&client) { + return errors.New("Bucket.As failed") + } + return nil +} + +func (v verifyContentLanguage) ErrorCheck(b *blob.Bucket, err error) error { + var e smithy.APIError + if !b.ErrorAs(err, &e) { + return errors.New("blob.ErrorAs failed") + } + return nil +} + +func (v verifyContentLanguage) BeforeRead(as func(any) bool) error { + var ( + req *s3.GetObjectInput + opts *[]func(*s3.Options) + ) + if !as(&req) || !as(&opts) { + return errors.New("BeforeRead As failed") + } + return nil +} + +func (v verifyContentLanguage) BeforeWrite(as func(any) bool) error { + var ( + req *s3.PutObjectInput + uploader *s3manager.Uploader + ) + if !as(&req) || !as(&uploader) { + return errors.New("Writer.As failed for PutObjectInput") + } + req.ContentLanguage = aws.String(language) + var u *s3manager.Uploader + if !as(&u) { + return errors.New("Writer.As failed for Uploader") + } + return nil +} + +func (v verifyContentLanguage) BeforeCopy(as func(any) bool) error { + var in *s3.CopyObjectInput + if !as(&in) { + return errors.New("BeforeCopy.As failed") + } + return nil +} + +func (v verifyContentLanguage) BeforeList(as func(any) bool) error { + if v.usingLegacyList { + var req *s3.ListObjectsInput + if !as(&req) { + return errors.New("List.As failed") + } + } else { + var ( + list *s3.ListObjectsV2Input + opts *[]func(*s3.Options) + ) + if !as(&list) || !as(&opts) { + return errors.New("List.As failed") + } + return nil + } + return nil +} + +func (v verifyContentLanguage) BeforeSign(as func(any) bool) error { + var ( + get *s3.GetObjectInput + put *s3.PutObjectInput + del *s3.DeleteObjectInput + ) + if as(&get) || as(&put) || as(&del) { + return nil + } + return errors.New("BeforeSign.As failed") +} + +func (v verifyContentLanguage) AttributesCheck(attrs *blob.Attributes) error { + var hoo s3.HeadObjectOutput + if !attrs.As(&hoo) { + return errors.New("Attributes.As returned false") + } + if got := *hoo.ContentLanguage; got != language { + return fmt.Errorf("got %q want %q", got, language) + } + return nil +} + +func (v verifyContentLanguage) ReaderCheck(r *blob.Reader) error { + var goo s3.GetObjectOutput + if !r.As(&goo) { + return errors.New("Reader.As returned false") + } + if got := *goo.ContentLanguage; got != language { + return fmt.Errorf("got %q want %q", got, language) + } + return nil +} + +func (v verifyContentLanguage) ListObjectCheck(o *blob.ListObject) error { + if o.IsDir { + var commonPrefix types.CommonPrefix + if !o.As(&commonPrefix) { + return errors.New("ListObject.As for directory returned false") + } + return nil + } + var obj types.Object + if !o.As(&obj) { + return errors.New("ListObject.As for object returned false") + } + if obj.Key == nil || o.Key != *obj.Key { + return errors.New("ListObject.As for object returned a different item") + } + return nil +} + +func TestOpenBucket(t *testing.T) { + tests := []struct { + description string + bucketName string + nilClient bool + want string + wantErr bool + }{ + { + description: "empty bucket name results in error", + wantErr: true, + }, + { + description: "nil client results in error", + bucketName: "foo", + nilClient: true, + wantErr: true, + }, + { + description: "success", + bucketName: "foo", + want: "foo", + }, + } + + ctx := context.Background() + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + var client *s3.Client + if !test.nilClient { + cfg, _, done, _ := setup.NewAWSv2Config(ctx, t, region, false) + defer done() + client = s3.NewFromConfig(cfg) + } + + // Create driver impl. + drv, err := openBucket(ctx, client, test.bucketName, nil) + if (err != nil) != test.wantErr { + t.Errorf("got err %v want error %v", err, test.wantErr) + } + if err == nil && drv != nil && drv.name != test.want { + t.Errorf("got %q want %q", drv.name, test.want) + } + + // Create portable type. + b, err := OpenBucket(ctx, client, test.bucketName, nil) + if b != nil { + defer b.Close() + } + if (err != nil) != test.wantErr { + t.Errorf("got err %v want error %v", err, test.wantErr) + } + }) + } +} + +func TestOpenBucketFromURL(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"s3://mybucket", false}, + // OK, setting region. + {"s3://mybucket?region=us-west1", false}, + // OK, use KMS Server Side Encryption + {"s3://mybucket?ssetype=aws:kms&kmskeyid=arn:aws:us-east-1:12345:key/1-a-2-b", false}, + // OK, use S3 Transfer acceleration and dual stack endpoints + {"s3://mybucket?accelerate=true&dualstack=true", false}, + // OK, use FIPS endpoints + {"s3://mybucket?fips=true", false}, + // OK, use S3 Transfer accleration and dual stack endpoints + {"s3://mybucket?accelerate=true&dualstack=true", false}, + // OK, use use_path_style + {"s3://mybucket?use_path_style=true", false}, + // OK, use s3ForcePathStyle + {"s3://mybucket?s3ForcePathStyle=true", false}, + // OK, use disable_https + {"s3://mybucket?disable_https=true", false}, + // OK, use FIPS endpoints + {"s3://mybucket?fips=true", false}, + // OK, use anonymous. + {"s3://mybucket?anonymous=true", false}, + // Invalid accelerate + {"s3://mybucket?accelerate=bogus", true}, + // Invalid FIPS + {"s3://mybucket?fips=bogus", true}, + // Invalid dualstack + {"s3://mybucket?dualstack=bad", true}, + // Invalid ssetype + {"s3://mybucket?ssetype=aws:notkmsoraes&kmskeyid=arn:aws:us-east-1:12345:key/1-a-2-b", true}, + // Invalid parameter together with a valid one. + {"s3://mybucket?profile=main¶m=value", true}, + // Invalid use_path_style + {"s3://mybucket?usePathStyle=bad", true}, + // Invalid disable_https + {"s3://mybucket?usePathStyle=bad", true}, + // Invalid parameter. + {"s3://mybucket?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + b, err := blob.OpenBucket(ctx, test.URL) + if b != nil { + defer b.Close() + } + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + } +} + +func TestToServerSideEncryptionType(t *testing.T) { + tests := []struct { + value string + sseType types.ServerSideEncryption + expectedError error + }{ + // OK. + {"AES256", types.ServerSideEncryptionAes256, nil}, + // OK, KMS + {"aws:kms", types.ServerSideEncryptionAwsKms, nil}, + // OK, KMS + {"aws:kms:dsse", types.ServerSideEncryptionAwsKmsDsse, nil}, + // OK, AES256 mixed case + {"Aes256", types.ServerSideEncryptionAes256, nil}, + // Invalid SSE type + {"invalid", "", fmt.Errorf("'invalid' is not a valid value for %q", sseTypeParamKey)}, + } + + for _, test := range tests { + sseType, err := toServerSideEncryptionType(test.value) + if ((err != nil) != (test.expectedError != nil)) && err.Error() != test.expectedError.Error() { + t.Errorf("%s: got error \"%v\", want error \"%v\"", test.value, err, test.expectedError) + } + if sseType != test.sseType { + t.Errorf("%s: got type %v, want type %v", test.value, sseType, test.sseType) + } + } +} diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..32a0559d3 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,763 @@ +{ + "Initial": "AQAAAA7ffPP4BsPh1wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "6729b8b148acc066", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KaGVsbG8gd29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOkRVb1JoUT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "2IXHmL5OGGnmhTJIjU6FtrI2XeU6UmLeSy8BvSzuSLsht53qGpf0tWWSFVInaGFZYF3N9A12UzU=" + ], + "X-Amz-Request-Id": [ + "PQJP8TPR7AMEVJ4B" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "8eac56421f11c3d3", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Z1ApbkVFx/B96m8JKu6w72mF5o+b4VlA6bbT+yP4NorPGUXsew2MLSaZBBx0U8RSYUa8YefGsj8=" + ], + "X-Amz-Request-Id": [ + "PQJYFTRV0SF585YH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "5ad32f12fe951b3a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "HIznRlixbgvv6OgeswAK/nXWKluJAd4FGsxVN7xoRnO5nsBibVwnxxyvBuhtt9XXm21Xf4M6QM4=" + ], + "X-Amz-Request-Id": [ + "PQJQJ6YBG2HZ7AJY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "ef81035b5492d8d9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=1000\u0026prefix=mydir", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "MFf2T8t3T/epp1gFNgZMRVx3gfo3ueF1DoKG+RDUenb0XIFLxCsaG721jRdCpYq8dv9j1HqLI7s=" + ], + "X-Amz-Request-Id": [ + "PQJJKEBQYF8WRZ9G" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bXlkaXI8L1ByZWZpeD48S2V5Q291bnQ+MTwvS2V5Q291bnQ+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb21tb25QcmVmaXhlcz48UHJlZml4Pm15ZGlyLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "30b7d2112d632ef3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=mydir%2Fas-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "DcaH3NrKt8cAPN4QEykAZ3vsfZ9Og/DURoTagaOosGCvKTaSqitQYXWS5twdZ+AD51+3VaFSuf4=" + ], + "X-Amz-Request-Id": [ + "PQJRPV7E51H72C71" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bXlkaXIvYXMtdGVzdDwvUHJlZml4PjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+bXlkaXIvYXMtdGVzdDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMVQyMDozNzoxMy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMmcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+MTE8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "4d818ce06d95124b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key-does-not-exist?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "O4C1dmQ0ZHfNpuWJoHoEFN3q9bH3JljuUpLXAAhmxBHuAeG+fKw5OB2yYiIm5YucGQTHH3fZd7U=" + ], + "X-Amz-Request-Id": [ + "PQJTE7DPJHNKDHE4" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5rZXktZG9lcy1ub3QtZXhpc3Q8L0tleT48UmVxdWVzdElkPlBRSlRFN0RQSkhOS0RIRTQ8L1JlcXVlc3RJZD48SG9zdElkPk80QzFkbVEwWkhmTnB1V0pvSG9FRk4zcTliSDNKbGp1VXBMWEFBaG14Qkh1QWVHK2ZLdzVPQjJ5WWlJbTVZdWNHUVRISDNmWmQ3VT08L0hvc3RJZD48L0Vycm9yPg==" + } + }, + { + "ID": "b4eb2bdb5ba61d61", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fmydir%2Fas-test" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "peL2+86MKWYp3VGJGh7DXpaMCr2IRt3pAwPK0ye9tE+2Va8JJsXlZB9P0bA9VmPeeVN5RTBo5pw=" + ], + "X-Amz-Request-Id": [ + "PQJSZX3CCKCB5B6P" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjEzLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMiPC9FVGFnPjxDaGVja3N1bUNSQzMyPkRVb1JoUT09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "e74b98f5e9cd787c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "BKSYoD6ALZqWTUqHVVTyob7GXN62ykjqRaMgCkmsCLeTOnNz6RYBuRwbhswUkRkUNdKAE661RRY=" + ], + "X-Amz-Request-Id": [ + "PQJG8HQS87VJ1E8A" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "871ec65be32eba7c", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9qWQpbnxsK28mrkY0tWDRZloIu2ytZnhXJxieLMYxDFksKtUtvP8/dn1kIdRDsPDtWkF24NZadA=" + ], + "X-Amz-Request-Id": [ + "PQJGF8PZBS4BZR2K" + ] + }, + "Body": "" + } + }, + { + "ID": "f437ba0064384098", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "BuSUnD1Iwu3Q1hJ57nWlCj0KmrQN0O3eEVxihyTCKn+gLW4YU607lx5UUz1fCBeKQBGMTH9YlBY=" + ], + "X-Amz-Request-Id": [ + "PQJVT089H99CTF5A" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "83617e8ba6d3a589", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "DA90gWK/ECKwrs4VAd6s9YfQmf/8v2jXLfuB9vkp7pv18dkHndd+qwqNjymRjvTO9cssxN8gRR0=" + ], + "X-Amz-Request-Id": [ + "PQJSN89VCHJ3420A" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay new file mode 100644 index 000000000..bfeb649c1 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay @@ -0,0 +1,778 @@ +{ + "Initial": "AQAAAA7ffPP3KSZjOQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "fbd869055cfda03e", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KaGVsbG8gd29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOkRVb1JoUT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "YIcHuk/RMtTdL7UksmLSAHF4DsMpipyTvyKtHzF6Ea2uM+JrwnM9pqXwWjDeSG4dgnShkOvVneQ=" + ], + "X-Amz-Request-Id": [ + "EENF6XD626HZ56T1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "3e87de6e0fbcb59a", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "BCMVygXAmD3QOHs5nW4XjCXSYHp5RTBq5ZjHAqRB4V6pLjXGQtusjqBaLTSk2a2sS8jkxMZn+4U=" + ], + "X-Amz-Request-Id": [ + "EEN0JK33VB4X8TMX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "663b12060e70f655", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "GcjFmUrS8XNx/9b6pN/zCMqdeZap4jy/tQqeTt19TE6gRDPuN/Y6opBsf7LlHMuzQIZE+ni5zmc=" + ], + "X-Amz-Request-Id": [ + "EEN6BKCV8RN4RD56" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "c44dba1d84631901", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=1000\u0026prefix=mydir", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "8Q5faMc8D+B13qvDQfLoR2p6gT3+NHdl0rIEKEE1mt+XLO8/6AS46AK1KmKru1NwfY1fj9nuzKs=" + ], + "X-Amz-Request-Id": [ + "EENDPK51PK8VTNB1" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bXlkaXI8L1ByZWZpeD48S2V5Q291bnQ+MTwvS2V5Q291bnQ+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb21tb25QcmVmaXhlcz48UHJlZml4Pm15ZGlyLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "d5dc0e60f9a8a5af", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=mydir%2Fas-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "FVD0DQY9aSjyDhte2IjJmZWa1bJpgZsEDM0yxHQcRuiqIosx/GNpKUudUuf9L6JDGyKwq59DiCA=" + ], + "X-Amz-Request-Id": [ + "EENAWQBXHGX6D17T" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bXlkaXIvYXMtdGVzdDwvUHJlZml4PjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+bXlkaXIvYXMtdGVzdDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMVQyMDozNzoxMi4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMmcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+MTE8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "b4225c47d9bf75b2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key-does-not-exist?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "KxEi2StpbzMMOaegZA52NUZp8sfESZAQ3qhngfKAYM81KTZUpweyKECX+iUt6zjHqlJF/gnvci0=" + ], + "X-Amz-Request-Id": [ + "EEND22Z69XJ2JPX3" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5rZXktZG9lcy1ub3QtZXhpc3Q8L0tleT48UmVxdWVzdElkPkVFTkQyMlo2OVhKMkpQWDM8L1JlcXVlc3RJZD48SG9zdElkPkt4RWkyU3RwYnpNTU9hZWdaQTUyTlVacDhzZkVTWkFRM3FobmdmS0FZTTgxS1RaVXB3ZXlLRUNYK2lVdDZ6akhxbEpGL2dudmNpMD08L0hvc3RJZD48L0Vycm9yPg==" + } + }, + { + "ID": "17d86a1dd935d154", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fmydir%2Fas-test" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "qYBJR0wcUwHrkNB1lin7KC2KJWR4vqNQUTT5H7LlpUZHnAUSEPfC0DTafeL4kFsjZBDm5AnE/Zg=" + ], + "X-Amz-Request-Id": [ + "EEN6AG6YFWJE457Q" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjEyLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMiPC9FVGFnPjxDaGVja3N1bUNSQzMyPkRVb1JoUT09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "ad6233e5e8b68e86", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "lHYFQu9MGX3sANKfjnKo1dZYLrfFNxC8jQNJNqvg475xXHOr3mmqrib8i8qBH51/N9MLRIf0h9s=" + ], + "X-Amz-Request-Id": [ + "EEN096CG7F1BE352" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "15cd55bfbc8bf94f", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9LcNvDX+DVcD2lK54lMErd0piXwgz2FNQ7kEQA72BcH5y8Gz6BR2uORKuRV7StT/SmZFG630dZ0=" + ], + "X-Amz-Request-Id": [ + "PQJXG6H5VZKMKMV1" + ] + }, + "Body": "" + } + }, + { + "ID": "825a502990066fb5", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "/1xz9OsOn9ybrLmIMuhQlYQ3y92fyjV1BbL8OHlWoUIZsREjZ+rNYOktb215ZZL6mCWdQUOwEIM=" + ], + "X-Amz-Request-Id": [ + "PQJHH7PPV8B2VH27" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "793e7320dcfc1c79", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "LNi5YM77J1ogdU9rrO+bsX34keCTrl4JJYSLid2LpuBDAIPIuIkY+9DoRyN41TxZxy0BNbR08tU=" + ], + "X-Amz-Request-Id": [ + "PQJJS5RVJQKG5T93" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestAttributes.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestAttributes.replay new file mode 100644 index 000000000..8d0d74ccb --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestAttributes.replay @@ -0,0 +1,751 @@ +{ + "Initial": "AQAAAA7ffPPpEUgIwwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "de4ea0c69f9ce38b", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity", + "aws-chunked" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "53" + ], + "Content-Md5": [ + "7Qdih1MuhjZehB6Sv8UNjA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "12" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yw0KSGVsbG8gV29ybGQhDQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjpIQ2tjb3c9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "HCkcow==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "hYd1F+rcqhwsgo5gSCK2ZNEpvKydqK4ESsaKXhsEsyWntYzvNyymnxyt34shTteE1sNmYsFnuGbjjru8KOKSvQ==" + ], + "X-Amz-Request-Id": [ + "4NS3ENJCAD3W322T" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "e5caec230f2741a7", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/not-found", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "RTCZNiIDpABe+tHS/+3SrQ4UK5JmDRy+d6Y++8Vbt2c+rFUZ5VnoFJ0akJL7ScMurQZYMo/It0IqevgcIdXssw==" + ], + "X-Amz-Request-Id": [ + "4NS44TDEH7N0Z438" + ] + }, + "Body": "" + } + }, + { + "ID": "5c86662e7038d8ed", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rhVUrTUp4myZEKfdDQimeB6sUE60O2z8vWrx8JoctV8jtdVU5+ZwZoYIWvNDB6rSQW4ZbQ7ujmqYS1n0ZKBCKQ==" + ], + "X-Amz-Request-Id": [ + "4NSBEANNQZ37KRCD" + ] + }, + "Body": "" + } + }, + { + "ID": "b2163c51f6d71c8f", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "cj1vq+XPUcjQQJJKb7bFDof5e7dvbUuUluY5Tt7E48MSOnDpdkR9CSbYse3JsgjTeILhGnbRa8fTI1KY8cGHXw==" + ], + "X-Amz-Request-Id": [ + "4NS499XTSA21P9NR" + ] + }, + "Body": "" + } + }, + { + "ID": "104c91530fd2e39e", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "12" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "bC/mbGYbT/MOm6VHxUVGPhE9JRSieEv4xVbF88T2ZpV1NyxJQ4EAANtSrvaJzoxI4XVN+vaA2MSG6EwYXcdTqw==" + ], + "X-Amz-Request-Id": [ + "4NSDN5PB5BMVGNVQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "72bed79de6a715b7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "12" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "HCkcow==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "aysUrZwZ06c55bHHqs8mCqfUCyVtYUP9VIOVxexwLIO+ZOyNffmMv9/XENhwlGwBtihtoLzXFp5VyKMbF6Aq2w==" + ], + "X-Amz-Request-Id": [ + "4NS1KT4V76NT08Z3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "SGVsbG8gV29ybGQh" + } + }, + { + "ID": "bd79d58c4a423b79", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "53" + ], + "Content-Md5": [ + "7Qdih1MuhjZehB6Sv8UNjA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "12" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yw0KSGVsbG8gV29ybGQhDQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjpIQ2tjb3c9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "HCkcow==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "cMkiLJf59QKxilIJ9ExAAdTgz1KriWLKOBrGEsjIER2a13UKvteY9QOhEAMto26YZjCBwXhuQ0llqC6bVa8g5w==" + ], + "X-Amz-Request-Id": [ + "4NS7VZSBXWHMRM0Z" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "3087458cea2001c2", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "12" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ul8Ys/nY+7e8iogF+CY7msMOozFqTDDQ0GQAO9wmE/cxG4LF4rqWxtBu8U3S7Tv6Z2C1LMnBixo/Q4b/vR27pQ==" + ], + "X-Amz-Request-Id": [ + "4NS8D4NY99F102BE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "dbc08384c9e5ee88", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "12" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "EGWeSWcvmdSOhKCUHkHIwpfokdGHV8p7zF9Wwh+WDefEynwULK5AZuV6qFHHx4WTDJyF7GguTr16o/euP5ITOw==" + ], + "X-Amz-Request-Id": [ + "4NS2JK00EFBC2MQZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a6d8ec024ffef555", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "S+HzYZGHY+OHRByznDkOT7g2I0FQ07H66I1oVb6Q5s2nVVnqtlukGUs4Furs1tWHpsffGwegSRBDuQLt6yI6uw==" + ], + "X-Amz-Request-Id": [ + "4NS60XHRVY9BAWSM" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay new file mode 100644 index 000000000..01fbc3797 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestCanceledWrite/BlobExists.replay @@ -0,0 +1,409 @@ +{ + "Initial": "AQAAAA7ffPPsFCUMdwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "392d02d612725669", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KaGVsbG8gd29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOkRVb1JoUT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "1G7ddIzxjgiIjMZpAXnQ2xw0NBVzwwzIeZtW4j95I/bqZGfQ78H8T2AdGLYNNGgPY4LDu/zW0ebUY98UdcLo3g==" + ], + "X-Amz-Request-Id": [ + "7TE6F0QCZ025RD84" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "cee26c1124cdd2f9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "zrMgiNjpDVEQgh8p+KFXa4I8D7exvLjXas0DHdDylu4V64/+Q5ZM/nN/HWSph4IuJDXvr2qaJT7tDEXgnr78Aw==" + ], + "X-Amz-Request-Id": [ + "7TE2ZG797JNH6QA3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "f67ff8cfe01acfa7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "qW3QBFrUGKztdJMNjcvDytb3vIxacLWmOmYciTXc4xSlLn8T5G9tN8BBYo1S/cCoaNZEIqIkwYQftfhTxi1nnw==" + ], + "X-Amz-Request-Id": [ + "7TE5BMHC6NKMR0MC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "c94c537372a0a485", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rXsOxKS5NjF7ay3MWIV4chYbPJUCQk8TBJmCI3mWcaVwgPLcWHSpfdn8I0wA8B8G0g/sqfGsIWkr86POivT/EA==" + ], + "X-Amz-Request-Id": [ + "7TECP2MAMSEHWEDG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "2abba59c0d632dfd", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "8WNgVSsBZhN46Mjnr1zdWOg0FZ/2Zj+ChStkG0RgvpnFdXo+cccsnyn93m5/q2lDMMofRJV7/sqDWd1Y05kD9g==" + ], + "X-Amz-Request-Id": [ + "7TEA4DMY9N46QAT2" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay new file mode 100644 index 000000000..3accbd699 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestCanceledWrite/EmptyContentType.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPPsB09W3AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "1d3f529be8657f3f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rjzRYwuY4vXbdNJN6OyDMDHeNUVmZn2G08gGNA0y6LNBjbGHOV396Ob0eYTHPdElcLFyisK1IGC4a2yi0BUb1w==" + ], + "X-Amz-Request-Id": [ + "7TEEDYY5DTP1AEBH" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvS2V5PjxSZXF1ZXN0SWQ+N1RFRURZWTVEVFAxQUVCSDwvUmVxdWVzdElkPjxIb3N0SWQ+cmp6Ull3dVk0dlhiZE5KTjZPeURNREhlTlVWbVpuMkcwOGdHTkEweTZMTkJqYkdIT1YzOTZPYjBlWVRIUGRFbGNMRnlpc0sxSUdDNGEyeWkwQlViMXc9PTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "4688a8c69a68cff2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9mmDyzRbxTl4q9n6XoBPrZ6+/g29kSZY40lqZrzxhS1FwknBoQs/SYQhi1SMcdRtqcpT1Li2+vNAjO+xcYaEzA==" + ], + "X-Amz-Request-Id": [ + "7TE3Z47C58R8V3V4" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvS2V5PjxSZXF1ZXN0SWQ+N1RFM1o0N0M1OFI4VjNWNDwvUmVxdWVzdElkPjxIb3N0SWQ+OW1tRHl6UmJ4VGw0cTluNlhvQlByWjYrL2cyOWtTWlk0MGxxWnJ6eGhTMUZ3a25Cb1FzL1NZUWhpMVNNY2RSdHFjcFQxTGkyK3ZOQWpPK3hjWWFFekE9PTwvSG9zdElkPjwvRXJyb3I+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay new file mode 100644 index 000000000..754dbf9ce --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestCanceledWrite/NonEmptyContentType.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPPsDep8AQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "a1f2460cbfadc5aa", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "qqRtt0eLN1Su/xaECb9JgDMnIxXBlWeKVrEghGft0Ep9gFfVGwr48hhhiVfbrLHZTJ3RkN1rWqk=" + ], + "X-Amz-Request-Id": [ + "7TE12NVK284KW2QK" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvS2V5PjxSZXF1ZXN0SWQ+N1RFMTJOVksyODRLVzJRSzwvUmVxdWVzdElkPjxIb3N0SWQ+cXFSdHQwZUxOMVN1L3hhRUNiOUpnRE1uSXhYQmxXZUtWckVnaEdmdDBFcDlnRmZWR3dyNDhoaGhpVmZickxIWlRKM1JrTjFyV3FrPTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "2f060241a89f4788", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "J1s45sgjfABGDVOjnZIvR1bW5geDTVbWthAVhYMcW3NrAMVc0Lss5C6SGQtTNnNsBV/JTtLVmiY=" + ], + "X-Amz-Request-Id": [ + "7TECZRBXBMR1X9S7" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvS2V5PjxSZXF1ZXN0SWQ+N1RFQ1pSQlhCTVIxWDlTNzwvUmVxdWVzdElkPjxIb3N0SWQ+SjFzNDVzZ2pmQUJHRFZPam5aSXZSMWJXNWdlRFRWYld0aEFWaFlNY1czTnJBTVZjMExzczVDNlNHUXRUTm5Oc0JWL0pUdExWbWlZPTwvSG9zdElkPjwvRXJyb3I+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestConcurrentWriteAndRead.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestConcurrentWriteAndRead.replay new file mode 100644 index 000000000..07bd6f332 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestConcurrentWriteAndRead.replay @@ -0,0 +1,5707 @@ +{ + "Initial": "AQAAAA7ffPPsJ5pKugAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "0202cad54140c504", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key0?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "Yg8LZ6kff3QVG8W+dFtxEA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6eHh3QUVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"620f0b67a91f7f74151bc5be745b7110\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "xxwAEQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "0bMiCvsRmtb276Sj3ZG7pzAZbZ55n0HZrZSEM2nzeMC7E29o59nkftQUpo15sbGLn/VCNuCx3C7BhaLgrObohg==" + ], + "X-Amz-Request-Id": [ + "7TEF2H6K35WRK90Y" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "edb8ec2d0b699eb6", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key13?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "SsTzFZ3m7R1NrIc42UKW+Q==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTAwMA0KDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6K01kQXhBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"4ac4f3159de6ed1d4dac8738d94296f9\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "+MdAxA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "b8xr/muGLJUVE5hFKmB++yOXTtYjeZ2S8NDnxD2qQwx4NV0vG0HKK4ATOsRdKr/omdVxAruHSbI2RDZTBBQznQ==" + ], + "X-Amz-Request-Id": [ + "7TE9B3FT48NEPCNG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "62ff97ddd0e87f19", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key3?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "7tBPOyKIo0omYOmbN3Ht7w==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6R2lNcUNRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"eed04f3b2288a34a2660e99b3771edef\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "GiMqCQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "yKgL0bFI1soZktAqQjp2aiXv95IU130Fh/9luO7DK62PiFY8Y3oiTN39q0W6tGvd63UPWjbUXDCutnGLIuIXIw==" + ], + "X-Amz-Request-Id": [ + "7TE9RVZ19S291V3B" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "2cc312753e003477", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key19?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "2w9S4aRqKABHoeAhyiAJMA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEw0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6eG9SZE1BPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"db0f52e1a46a280047a1e021ca200930\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "xoRdMA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "3PA/vELXrIyQuc+otmNdqhp1tWP/93V5FlyUFR5c6VWdRidRgCMGUgPcn+siRkiihX+JfUwxIgLLrhE6JUtmqUrkDe7GUnQv2PfTPxVdg3s=" + ], + "X-Amz-Request-Id": [ + "7TE9APZ5D5V68SED" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "3df050687c7e0929", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key1?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "qo85ln3rRBpudISWOUWpYA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6T3Rua0pnPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"aa8f39967deb441a6e7484963945a960\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OtnkJg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "H3TlU5L+WGICftyJUV4FtZjRbcbpUnkPwocuRGdgy4n229y5KVIvuIOmNaJl2Qv7bjPAAsWF+2Q=" + ], + "X-Amz-Request-Id": [ + "7TE2PSHW5CZG4S4V" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0713cc5f9f864a27", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key9?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "kfsiuKRZ73D7CzauKodAhg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTAwMA0KCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6dVRMY21nPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"91fb22b8a459ef70fb0b36ae2a874086\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "uTLcmg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "vN0g8f+1SO/98Gq7b/3NbbDilTZgcLynbKL0pWeymKCiSmMs6jgRkvVQIrLcspSx02WW8tzXls8i79/KDbrwAl8jgS3zmbv3YvhrolKH8UY=" + ], + "X-Amz-Request-Id": [ + "7TED5YWPNZ1A4GB4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "e72eef576eabd60e", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key14?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "NlFDUFM0TpF1S+MXE1PxDg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KDg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6SmZocTNBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"3651435053344e91754be3171353f10e\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "Jfhq3A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "HNX2ZqLWAtI+u8fLyEReS8TnELnYqTK/isUPsVyLCP86HX7f7hZ1RbP8vi8gsS9UhhQ+pJkpHY0=" + ], + "X-Amz-Request-Id": [ + "7TEF5VJ8ZTTFERSE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1e37c9073350c2cd", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key10?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "AXKK1JVcZ791KxchIXYNNg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTAwMA0KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6WkEzMmdnPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"01728ad4955c67bf752b172121760d36\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "ZA32gg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "MtD0ZdoPhRltgUruPZLv0900WY1ZOveqWnINW3XHwtQKA/Z1G64+ogwEmk5qnj25Vx4PIXT1DoQ=" + ], + "X-Amz-Request-Id": [ + "7TED5Y4KPD5G5N0J" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1ebaff7a31951e5d", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key15?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "qHqy3TOCPLWABZ/YTEeiAg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6MkQyTzZ3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"a87ab2dd33823cb580059fd84c47a202\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "2D2O6w==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "MO3fa/TDWFsyMpCt2XWBdoVBtfGBkJQARyXAYfHjdP6mS65hVkVD3zRUBsxmS77nys3f/b0wHiHDguV9MlMzEzxOlVMGwc/s8749/buKfXQ=" + ], + "X-Amz-Request-Id": [ + "7TED3Y97GYHW181C" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "265172e27b8e6a5a", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key2?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "ZUHn/UhoC5tg7AVev6McAg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6NStiT1BnPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"6541e7fd48680b9b60ec055ebfa31c02\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "5+bOPg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "CAHrMor9UlsdwHgAiIaAIwGOfbDOf3FeDrDiSU6owujx22AiHH+nkTB4dNyxkqQtMc/4iYmOYdc=" + ], + "X-Amz-Request-Id": [ + "7TE2ME33HQF4YWGM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "9653a70d7c54c83f", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key12?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "VkGQ+3LJseHAFopbb+BYvg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTAwMA0KDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6QlFLazh3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"564190fb72c9b1e1c0168a5b6fe058be\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "BQKk8w==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Pn1jEmBGNbT7bjJuaZ9jyjzZFJojEg26Ug6FVce7VpLoyJtPDgTvolK+9gEXIqFYjsPHSe4/Qnw=" + ], + "X-Amz-Request-Id": [ + "7TE95PZSQ3M0SPQW" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "dda938b88943e407", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key11?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "AbDmWR96f1VIFnW4JQ5/SA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCw0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6bWNnU3RRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"01b0e6591f7a7f55481675b8250e7f48\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "mcgStQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "yu7gpwRlzNj9Y2Kc6Ceuyb8aGpM0BFXkeOFvrdAj/tAeXXSRtKlalQGrE+DHQrFnc0JY6ulzJRU=" + ], + "X-Amz-Request-Id": [ + "7TE7JFGT37E85TRQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "aaa9917e76015513", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key6?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "lko2uDqoJrgEyYNnvcJ6vw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6cGhOU1lBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"964a36b83aa826b804c98367bdc27abf\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "phNSYA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "DAOeuMRXw0WZ1PwsnJo3vZ3lGuv2vDbM64r/dUKKuiLDSkR47zMEaVdPMIa4oWY46TwvOMIhdNg=" + ], + "X-Amz-Request-Id": [ + "7TE32KHFA8Y1EGK7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "f214d6b884905f83", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key16?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "65n9CjdrJkNQEaG4fFWMgQ==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEA0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6Rzd0M0tBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"eb99fd0a376b26435011a1b87c558c81\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "G7t3KA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "5JxUh9WyVu2XAiwiAhO7U+spk+ruNKiKATeO6qO98/jaq3AZu9sQlk0YQDwJIIikbZVQPdLPY7I=" + ], + "X-Amz-Request-Id": [ + "7TE2PX53R83M5V6F" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "82f4388c18e60be0", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key7?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "kbuiTp5JEugjwAkgztPoXA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6VzlhMlZ3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"91bba24e9e4912e823c00920ced3e85c\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "W9a2Vw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "wXQ05ByFwlmOTCbgTCkKhEw3o6x+ikwgQdt1PTaDYx4uP8v6mwrniOz+qWHBbubLp08MwAPfXSA=" + ], + "X-Amz-Request-Id": [ + "7TE0W4HK4SCCYMAH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "e517d087971892a8", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key5?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "YfRaKQkG0Wv1UeeMsD1f+Q==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6ZXl4NGVBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"61f45a290906d16bf551e78cb03d5ff9\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eyx4eA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "sfLeBsiz3EXNhNN5Ef8ijzsrDvf6VHQ/JiL4akoaNnObadUUnP9HiSMZMeffb3Fcrhq4bmJiQfI=" + ], + "X-Amz-Request-Id": [ + "7TE6WF53P2MK1PZN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7c3b7d0232e755b2", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key8?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "qPZPE0uAGBNKE6LhEQTA8Q==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UlBjNHJRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"a8f64f134b8018134a13a2e11104c0f1\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RPc4rQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "uzQFOhKZT0oDfw5GJNIwhCnisI507HBUU+vxQLmW80dNuuG7Q6kko8NtuNFogkiTdNugnibKeQroV6txPGrL0w==" + ], + "X-Amz-Request-Id": [ + "7TE34K3WCZADQM3Z" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a26b17a16186b42c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key4?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "H06jyF3ZsJDOcwyB5gg+zw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6aHVtY1R3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"1f4ea3c85dd9b090ce730c81e6083ecf\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "humcTw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "fqmblHKGGcYSglddVtD3QwGDdGT3ulA1qU9J7yexC5t83XJdSTICK0e6jEhpNVWzFuEiF1X5aFl5hUMsECFuJQ==" + ], + "X-Amz-Request-Id": [ + "7TEA50VQG4TC28XJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "e791f288f64e7c44", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key18?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "wZvI1MtOgANGQD0gzZ4NUg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6TzBHNUJ3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"c19bc8d4cb4e800346403d20cd9e0d52\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "O0G5Bw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "WKZuOxK4mjz8fm+RBGdzCbRikQDMzTyKTKFMflMyuRcC8oVJ8CaqIbGDPnw4KXuAUc+OZ+nSfCoRxYqbi4uZRAidJoJdBIhe9WYT8f37MKc=" + ], + "X-Amz-Request-Id": [ + "7TE7E11EAZX0ETTF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0bcdb2c71abc4cdc", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key17?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "32eeXsj7ZyhCl0o20wPQ/w==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6NW42VEh3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"df679e5ec8fb672842974a36d303d0ff\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "5n6THw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ug2UDaFDTXOz31bz+7QTpAqRiZB7txr2BwMIVkK3SXa2383bqxY+dsNJlIddbi+khzQDuI7GkMI=" + ], + "X-Amz-Request-Id": [ + "7TEC6PGNPAEKATRB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "503fec1fc379c375", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key19?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"db0f52e1a46a280047a1e021ca200930\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "xoRdMA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "i2xO4vaHsHkSbml3rDQxsbgFWgLlsgMRVHjJcqYeau46ua8BHgprH9umwMFoSESh1BPic6CkLK0=" + ], + "X-Amz-Request-Id": [ + "7TE624A5G4R3211M" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEw==" + } + }, + { + "ID": "e21b9a3a296974ee", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key5?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"61f45a290906d16bf551e78cb03d5ff9\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eyx4eA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "sr2xtTxD19Yzir7f0lVLh1RZci+PIafeMHknGu/eLSAUxdKJN+OlyzP7+b+mMadgDHsvLKKy0C3AG/9mTHiR1Q==" + ], + "X-Amz-Request-Id": [ + "7TE7147EECSAN7N3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ==" + } + }, + { + "ID": "6adba42b1b9bd9a8", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key12?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"564190fb72c9b1e1c0168a5b6fe058be\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "BQKk8w==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "nn1DqibWKKnl7BZ4GIfg9dAm9zrm1j6Y21GjEQqvY0BmBwaM4uBfJLO7D7Vqq85Za4taAgB1jic=" + ], + "X-Amz-Request-Id": [ + "7TEE7V8QJ9SWX5XE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA==" + } + }, + { + "ID": "2e44c0e8fdd63ecb", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key10?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"01728ad4955c67bf752b172121760d36\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "ZA32gg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "3b+FKgOWkGi29rSpF8Cjkd3jjbETwVab6t8dPDsAtsy/wXOj94yuEmuQOcKTRXuLohp8xlu5MJGo2fkBC5Y+ug==" + ], + "X-Amz-Request-Id": [ + "7TE5S1J8N8N2ZD45" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg==" + } + }, + { + "ID": "301aca1c0fedc82a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key3?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"eed04f3b2288a34a2660e99b3771edef\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "GiMqCQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "0vbXeEsUlMejPavMGLS5oJP5l5DCaRFpgxop5E/lSp3NL3hlD7rU60D1JcE3SWgROwo2i4jtTzx4031qh40kiA==" + ], + "X-Amz-Request-Id": [ + "7TE5S1KNM9167PWM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw==" + } + }, + { + "ID": "78925ffb6d0936f6", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key1?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"aa8f39967deb441a6e7484963945a960\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OtnkJg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "BpV6Cl2KRmgYzL31veCuJ7pdY2pNGr9WNTBmFscBSE9d1+qjrayi+PM5dZ+j4S1hQxWPtt+Yl11hJ4xnI8KK9Q==" + ], + "X-Amz-Request-Id": [ + "7TEFKSEPQXKB8E54" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ==" + } + }, + { + "ID": "2b3c02c9c64ff2cc", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key0?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"620f0b67a91f7f74151bc5be745b7110\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "xxwAEQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "aoNEAfXEGPvvO2YLxd5W8mpwDkdN2ZZ3f8xgyPI09k6C8emj9Y6XCXZGS8//XCKQaqX51nLtHanfsYt1ugRoAQ==" + ], + "X-Amz-Request-Id": [ + "7TE1HRQX9GN0W5SC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" + } + }, + { + "ID": "50b474fdf7433b62", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key2?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"6541e7fd48680b9b60ec055ebfa31c02\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "5+bOPg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "HUKMavEpEiP/Sso9Cy6FHNgCi1o1w6kB64ROwqAjlq4cXaV9GdJqhxu2/qD+rRXtZZPK8NRZavH9UK8wVkbjKQ==" + ], + "X-Amz-Request-Id": [ + "7TE2Q2Y8TEM1E7Q2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg==" + } + }, + { + "ID": "3f50d50d588e124b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key18?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"c19bc8d4cb4e800346403d20cd9e0d52\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "O0G5Bw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "XDv1VFm9wt94ptMHRL96L0GOfO/fr+zVLDYD+ZVAkwtdG2QmwqnLrBhdz5DHBA2Lrn25A3JE3GoxtkTuQo6a3g==" + ], + "X-Amz-Request-Id": [ + "7TE9JE02197NGRT6" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "EhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEg==" + } + }, + { + "ID": "636822ee17733c04", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key11?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"01b0e6591f7a7f55481675b8250e7f48\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "mcgStQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "wvxDBYIqh9FvPANE1KrDrDxSI8tFTQraDQWYEOxhWK+bE4vHtDhdoPpL8KeA0qlJ8a5JvhAeYB1KnBH/to9hxA==" + ], + "X-Amz-Request-Id": [ + "7TE320SSNWS18CKN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "CwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCw==" + } + }, + { + "ID": "ba8c284dc20ac112", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key16?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"eb99fd0a376b26435011a1b87c558c81\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "G7t3KA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "MyeaU6rUFxD71kb8NrgGhEVvAuPwiS55Ks82OYx/25nUdDM/QoVksuNrQ7FHCDHRzZq342P+X0tQDjFdO56nLA==" + ], + "X-Amz-Request-Id": [ + "7TED721FXEK1JABN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEA==" + } + }, + { + "ID": "2af87a98809489bb", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key9?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"91fb22b8a459ef70fb0b36ae2a874086\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "uTLcmg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "faK3fp50tHumwwjJZ3pMcki2oAScfUCoJBu2M5KoQmmZ1ztfACufb0arhCTSExEUHVMjd3J7f5HTwr3Yd86/PQ==" + ], + "X-Amz-Request-Id": [ + "7TE8NXN4SMWDG102" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQ==" + } + }, + { + "ID": "a7bde0530817aa5b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key13?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"4ac4f3159de6ed1d4dac8738d94296f9\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "+MdAxA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ehcc4gKiVUxFzMjTkGVZD4IIJMROYO5IucF1Wc12hCgy92TLj5IMlPOLYOwYftMezAHFKjkHxL+FOu+s+if04w==" + ], + "X-Amz-Request-Id": [ + "7TEF27M99JBZDBTX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ==" + } + }, + { + "ID": "4e7b351578cbbf9d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key6?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"964a36b83aa826b804c98367bdc27abf\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "phNSYA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "e/DfELUQy4IXZlI1qwIxnl8LgDb+bk9ZXnI6ArLhv+Lk8C+iWbhf1aqSrl/eMfDYwgJc8E591EgxK3/zN7ARQw==" + ], + "X-Amz-Request-Id": [ + "7TEBARFYDXKM3030" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg==" + } + }, + { + "ID": "b440703d959c0ed7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key17?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"df679e5ec8fb672842974a36d303d0ff\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "5n6THw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "iDLgHd1lCGAsK/v0uhdN3nhGwfmzh9ca3t2BqAY2FvI+16JxbDI8vopSkbjV+TtsKzc8FTaU2JRYFi4ZhpNtgqsqoq23KjItW+xNmPSB6ys=" + ], + "X-Amz-Request-Id": [ + "7TE0460VEB6JMWXB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "EREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQ==" + } + }, + { + "ID": "5dcacb2a47e18ec0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key14?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"3651435053344e91754be3171353f10e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "Jfhq3A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "lOB8pPALQ0atcQ3V12L3KyUkVGWyOwI4Y7uPzQ1ET8uwtM+Y4CerqLXfbyA5nAFZpbGkmPquvWdCZ3Eswml/dmFDOTs1xG40PJ+A5ygUI0w=" + ], + "X-Amz-Request-Id": [ + "7TEB8BRHWBP3FQ73" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "Dg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg==" + } + }, + { + "ID": "e269a262c62bc57c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key4?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"1f4ea3c85dd9b090ce730c81e6083ecf\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "humcTw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "8/7zjVZFdlcbuZs1SzUxOxjqIqGoFCCJP2j+RoSImIlPk5f8x3nxPPSu3/CmFe3+j0gXzJSsJePcSVKj6w9RCvkzxg+y1/DHLLy7+1QBsAU=" + ], + "X-Amz-Request-Id": [ + "7TECXWQPEGN3ARY0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA==" + } + }, + { + "ID": "24ee8f8b6436f92e", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key15?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"a87ab2dd33823cb580059fd84c47a202\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "2D2O6w==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Krb35wFsj3xYrPe+biuU5g8pOsvxKOU/S1kAEhuKchcDSI+oTCTRFVYLC5clnqokj/9fpuEBOXQ=" + ], + "X-Amz-Request-Id": [ + "7TEBWDTMRG4TYZGD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw==" + } + }, + { + "ID": "54c516629a27fa24", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key8?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"a8f64f134b8018134a13a2e11104c0f1\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RPc4rQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "swuXomS5uzDoX+goVwDuUCdXcVsdpqclW/uXUZG4w0m+gG5AvAwOpj/KkthTfFraXs4ik9ksjR8=" + ], + "X-Amz-Request-Id": [ + "7TEDZRRK919F1XT7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA==" + } + }, + { + "ID": "3b4d415c241e00ca", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key7?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"91bba24e9e4912e823c00920ced3e85c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "W9a2Vw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Be3XtGzvEwi1TM7bDY83o8/u7HWpOKvqmg2Wq4vXNcPKfWz7oWQL8z6Rc0KsgkH6UhoMmmHUjzM=" + ], + "X-Amz-Request-Id": [ + "7TEE6C87PN9XFY9B" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw==" + } + }, + { + "ID": "48b701fea7958d06", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key19", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"db0f52e1a46a280047a1e021ca200930\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "MjyNb5fyyLiK1td2Ybv8oyz+tAHVCFHdKemuVkqIBGz/a68MRvv+zkoiR6AMaHt6/Ldnb+cXl7bWCv/yWBg6zA==" + ], + "X-Amz-Request-Id": [ + "7TE79A7W8ZWW8KVY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6488ffcb453b48c2", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key19?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Zyt1qLordi9FN3SgUFVqUQRmevmks2rvebX9zyMYlh39eg5aTJMwEJ3V/qNvO26X9QB4e7a9+gw+ZA05FkqRiw==" + ], + "X-Amz-Request-Id": [ + "7TEFK4K5Z23BQHRY" + ] + }, + "Body": "" + } + }, + { + "ID": "e67a282836bed0bc", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key18", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"c19bc8d4cb4e800346403d20cd9e0d52\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "i46IJyRgRI8uncus7O0iBjzJUfT6ck1q9ip4YkS4D1qV5euWbqn7eiFaS17UVE2ejCJBOeX8NYTWmEQE/QIM1g==" + ], + "X-Amz-Request-Id": [ + "7TE90AHBXP0K9KVY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "dce3d3f6526a0331", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key18?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "shyuCfGF6otI0yCLUrk7y3zLSBFKwF5H45SWm3DYJntpxS7wkOiCioG4EvMb4Xk3BwoGVS0xXi7MD7bxpl0BBA==" + ], + "X-Amz-Request-Id": [ + "7TE1NTFZVBJZ0346" + ] + }, + "Body": "" + } + }, + { + "ID": "0a4482aa57b3a552", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key17", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"df679e5ec8fb672842974a36d303d0ff\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9ge7GLfDlqyKztXNSzY+Gy1zFThe2coIEIsGNYBzGfYU1HZvRTkpcnKe5DM9Ddc1Jq8oq7ETgjRCgXi1Kb7lVw==" + ], + "X-Amz-Request-Id": [ + "ZJNDC0C7JMD2REEP" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "dd2953bcf095d237", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key17?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "DwgzyArGoE/zYJppQvBj4ckKv274CaZSFrKedSKAIQr7f15ZShibcmWZxdA1KcT/djEqWFsx7/L8Mme/PH0+NA==" + ], + "X-Amz-Request-Id": [ + "ZJN5BMVKT72J4N26" + ] + }, + "Body": "" + } + }, + { + "ID": "115fc494b220b1fd", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key16", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"eb99fd0a376b26435011a1b87c558c81\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "yDT33ZYJePn8u7zUqZ1pmCZtqjqQ/XlWVqZmlXk2OM57IyhyRt+ljGBHprEfZn3SMoPubGyCbB0BSw8htzUHPQ==" + ], + "X-Amz-Request-Id": [ + "ZJNDXP1ZJ37CPVCR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "2a2221e9e81a3875", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key16?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ffhiow3v1BJCSZMWFJg7OHcRnqiusYo9ay6GuahDIKhb93ccGWpj3nkNbnrxTAmhIs2pvL/DtaJg2XCQnILUeA==" + ], + "X-Amz-Request-Id": [ + "ZJN7NWANFTV8P6H5" + ] + }, + "Body": "" + } + }, + { + "ID": "492d8f73dd3ce7df", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key15", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"a87ab2dd33823cb580059fd84c47a202\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "TLCgAfE20puVaPCy7zbdYwg833lpSDelna3t0aWDIvsefbCRZXhxzys4b5PiHVYbF5/GFzUWlpMMRGakCghdng==" + ], + "X-Amz-Request-Id": [ + "ZJN65MZ4YS2Q8HW6" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a3db1d20d9177cee", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key15?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Yd+QQCHQzlU96jmKQ2042h4h6F4gNh7XX8Up8LWqDr9kffkIPXmsanI383x6JAyE2cfpX6ReqMPlE8rBoDt2xw==" + ], + "X-Amz-Request-Id": [ + "ZJN5M8S4TV2NE9XG" + ] + }, + "Body": "" + } + }, + { + "ID": "d85c1d212370db5c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key14", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"3651435053344e91754be3171353f10e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "J8R81SBa1EJG/pVzpBR1hXff12HaM7IpaFPHPCwd5F13VyTi/4JCdHU1dKTTz8aJ4yamuDZyhhQYrHNPq9YVNA==" + ], + "X-Amz-Request-Id": [ + "ZJNBPDBPBY25KZJR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0472eb2e1048822c", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key14?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "QcTV6zM0uA/4gyG8xj0DPZ7HkIeQA9lfo2D8BaxMPCzbRYSma29DWOmrRcxt8JE2+MFToIR6EgVh2qD5coW/IQ==" + ], + "X-Amz-Request-Id": [ + "ZJN2Q50DAMVQAXX3" + ] + }, + "Body": "" + } + }, + { + "ID": "80f4b4e862049dce", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key13", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"4ac4f3159de6ed1d4dac8738d94296f9\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "cuXFea0xoV9hUQwQde/mqen4GKlCA28Tv1Pxmpzi/ZVLM/PEq4uWJsw7V6loY2TVTLE4KRJduLRRicFmzPlMag==" + ], + "X-Amz-Request-Id": [ + "ZJNC49GZGKY8P74P" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b4d107cf4e720915", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key13?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "D3WwiK1WV9Gcn7NQgS8F3VpnQa99X3BEzjQtrBj43IJRzp4WhFHGrEDKArNZk05e7CNdQeIXLV9npIe8ls56Ag==" + ], + "X-Amz-Request-Id": [ + "ZJN67S5FNGSMY569" + ] + }, + "Body": "" + } + }, + { + "ID": "38468eea9fd65731", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key12", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"564190fb72c9b1e1c0168a5b6fe058be\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rT3Ioi8Q0rlT/FegjKMLG8O2Chy0U8iaUeql+pBs4IyfWr0CCgR3A7zaTfXqDtkrOgbXLmrIboqCuI8uLz8Zvg==" + ], + "X-Amz-Request-Id": [ + "ZJN17PVNMTDMZBXC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a12fdeaba29384bd", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key12?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "uLGL6QUq9tzj3DXNNu0mjqnZCfnJpnozVaU1eYM5XJcImC++489JpeZXhq/RVwR7sijudREGWXCx1pOmKj8Shg==" + ], + "X-Amz-Request-Id": [ + "ZJN1BJCZGCMNWSCJ" + ] + }, + "Body": "" + } + }, + { + "ID": "ab873af8514136e7", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key11", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"01b0e6591f7a7f55481675b8250e7f48\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "pLNfPlsxYnq/FEb/42HZrrHAiEuHGa8hwUq3PlVtBNwnt8zSVQz3xmr553A/jFtf2OInYPMx4R2/+6GiUVCf2w==" + ], + "X-Amz-Request-Id": [ + "ZJN6CS2BXC2C0WZX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7320492fd29b9630", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key11?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "N3tjcF1kvKpf/OAujC5/Js3DDlFNzonKIajT3rNjFpJgde0+HKBDRyVl5AZ/DtS5bS6vYLpkLmlAmoJBqXDSDw==" + ], + "X-Amz-Request-Id": [ + "ZJN9PH5RMZTKZY53" + ] + }, + "Body": "" + } + }, + { + "ID": "d45e1aeb5c26dd04", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key10", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"01728ad4955c67bf752b172121760d36\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "v51zIWX1o2gCoDcMvGgGqn12NwHIBd89GsbVhfM4bMlGhm+Ygxjwy7h2zCG5cj78woyfDW4QsWkZW/Msu/IARw==" + ], + "X-Amz-Request-Id": [ + "ZJN8ACG2G0R30W5M" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "105c8f82e6c36624", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key10?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "U8oy1C0II9bOPy2w4sranoZT8WJ8gmujyFuPX1ThNAnSsuTkwZ+vafG9N8w3CfOq2H6eAKeP0PyANxhyZyyXqA==" + ], + "X-Amz-Request-Id": [ + "ZJN14329V3J8QYR8" + ] + }, + "Body": "" + } + }, + { + "ID": "51f0cc4a78d20861", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key9", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"91fb22b8a459ef70fb0b36ae2a874086\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "dg3HOWpugvNwlfpGfcMAXfVt7U4/8dJN5Z/ZtRPEkwfdkrhgw4TwYB+w7ww/REc/hLXKekKUp0N2j5Rp/uGSug==" + ], + "X-Amz-Request-Id": [ + "ZJN2RMGR1VXH2RPZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "906ac312eeafbd21", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key9?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Jhfk4yXxMcDNLUnOEOvGfYdlNtsI/uxogHgnpXeHsgfWnpSFk3ZlmlxYSZEK/gO82RPO+MGoli0R3+v/rg3y8g==" + ], + "X-Amz-Request-Id": [ + "ZJN479G46FWD99GX" + ] + }, + "Body": "" + } + }, + { + "ID": "d1e0aa14cb12f709", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key8", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"a8f64f134b8018134a13a2e11104c0f1\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "7f6treIx6P9/9IxO9L5tuoq0EO/BMqgWpBGZV8xuslUEFkpk3LsPrigdttCB4aExNxbZqdXzi9aW7d+72L4nPA==" + ], + "X-Amz-Request-Id": [ + "ZJN7C3XQ67QZ9DZG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "93d68221691c1cd4", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key8?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "uBVqRuO1xrY33qqprwuxgkLQSnYZvKVY8EcBCRvrhtRAN7BE2y1x9OAOP3B/FGcsSRirQ+DhSvVMkhdtglyeKA==" + ], + "X-Amz-Request-Id": [ + "ZJN4TATFSRM3FCNF" + ] + }, + "Body": "" + } + }, + { + "ID": "dd4414f8fbe26f40", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key7", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"91bba24e9e4912e823c00920ced3e85c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "touEMPtmc1Fn4Qw7VXLNbd+XldLnIQIlynVNQEwrTfalNfafefjw9w5PuEfIDPh2AhxXnvKmzFyJmDoOEGvBrA==" + ], + "X-Amz-Request-Id": [ + "ZJN4SYWDD880DGDA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "17d4d872289ac9e7", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key7?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+/qTZ2D4BvIlw6A2HibD7Bot4nmiBdZB70w0yp+VPLnPn1n7yPMhPuLJ+eet3YfHgxACW+5ARispCndaHkv2yA==" + ], + "X-Amz-Request-Id": [ + "ZJN8FY77W8SH45BM" + ] + }, + "Body": "" + } + }, + { + "ID": "d69f7cfef16d06d0", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key6", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"964a36b83aa826b804c98367bdc27abf\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "mv179x+8ROloPIhW3I2m4+6QXPWqGx3avj55WKI/o8WrwyeaNKEBf+9HpDqriKnjEy8N4pVbKdcfFg39u9ukcw==" + ], + "X-Amz-Request-Id": [ + "ZJN4QP9QM3PFVPQJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c46c7d14207a81af", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key6?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+hY+JFnQK26pHw23O1jOBUnzcUS2doKV7bYdeQ+lri1Esux7ol2+2Dsh1gWY/mq/4OMteBEP/qQo12py6Ft4KQ==" + ], + "X-Amz-Request-Id": [ + "ZJN5T634MPRCDA9N" + ] + }, + "Body": "" + } + }, + { + "ID": "8262d76027691a00", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key5", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"61f45a290906d16bf551e78cb03d5ff9\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "4Je3gltkhBqHOhFHOEN6p1o/OcRhfE71b3VqfbfsExQ8uWzTeMzfiF5h6EKwrHMd2tRfLldcGjZ4Ko5j2i/gLw==" + ], + "X-Amz-Request-Id": [ + "ZJN1TJWAAKZF6FJD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "e669654024cd8785", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key5?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "iA0FfvIU3U2bkERtxGArX3xsNKg+4fCYdYlnyybMr40Qux5bFijZreqZV83SXEETQa7H1kQFAiqNqgx04mqgcQ==" + ], + "X-Amz-Request-Id": [ + "ZJN2PMFTE37BXM5D" + ] + }, + "Body": "" + } + }, + { + "ID": "59d0349f96fd3f43", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key4", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"1f4ea3c85dd9b090ce730c81e6083ecf\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "PNjhdNr5BoIrvaFeaYEZRPpqiLs1AWqLnaac93Socu18YBuDiV7a/JpPQavzkqsnZgDqgS3O/DSqvhpyx2ZH2g==" + ], + "X-Amz-Request-Id": [ + "ZJN0W8K5YJVS1DGH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6c83fb5ebfeeba2a", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key4?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "p3kcD7iUxKqsRpHfd+cm5y20ObhSz08HoNgp3R1lk17dN0tLwTC/ppDSlSHTlljPrCwvSkkIfq1tNZXtDiEDug==" + ], + "X-Amz-Request-Id": [ + "ZJND2DCVQQDGB1ZC" + ] + }, + "Body": "" + } + }, + { + "ID": "7d144cca6763f6cf", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key3", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"eed04f3b2288a34a2660e99b3771edef\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "XDzIRWQ2B8TBamqubm9nrKmIXmvSkl7xhME98wBkWUnAY1Ap3vu2tT4qfz9dzYkrX+vGZHM/WjOT6wTnZiF7fA==" + ], + "X-Amz-Request-Id": [ + "ZJNB7ATZQK173HR6" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "9553419b0560272f", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key3?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "u+AEQ2D7f5qli0Jej7oxfnHSvN30qjlhFjM/0+ns0VGZhy/Qy7bJBgZzJq3z3Okq0ATZth+eF8kxyMdD6DD9tw==" + ], + "X-Amz-Request-Id": [ + "ZJN5MWXKK5TDV85N" + ] + }, + "Body": "" + } + }, + { + "ID": "cddd56958b351367", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key2", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Etag": [ + "\"6541e7fd48680b9b60ec055ebfa31c02\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "6tGHBgH/J7puVdVCvYqwRY34cVEYPQlfO/9lhUOU4onZLnWiMAZ/Np/zLV927ERnn87VIwPO22AmMSPhjKgU/A==" + ], + "X-Amz-Request-Id": [ + "ZJNDH4M82KK8VQTJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "bd91eda8ac9d41aa", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key2?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "xjGM+evTxwdt9gqWHQHq2OOP+EU/GggUjIid3CYvJhuC/V0HzhlcjjJdaAH4komI3P+MJ6RQaclexj3urRad4Q==" + ], + "X-Amz-Request-Id": [ + "ZJND7PJ53C4WSNJC" + ] + }, + "Body": "" + } + }, + { + "ID": "bbe3b409a7473e58", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key1", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Etag": [ + "\"aa8f39967deb441a6e7484963945a960\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "q0etak6Z0EFPy+k6ZyViFC8JdIykfN32Mc9xzEn5lODNqwSqApEOK8Wx1Lf9bA9pb28XAqZlSojjyyihaPO5xQ==" + ], + "X-Amz-Request-Id": [ + "NXJ4BWFJ7EA8AHV3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6274d04140be8169", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key1?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ntMzsTOwpKfYCA8jMzkpXoIxveHSPdY92ZT2eqLNdMO9YgvveHpps03i/tPGQbChecVTUOjQR2Ryh6SGQGvaxQ==" + ], + "X-Amz-Request-Id": [ + "NXJ88GWN3TY9DWWS" + ] + }, + "Body": "" + } + }, + { + "ID": "d3303ceadc493994", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key0", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Etag": [ + "\"620f0b67a91f7f74151bc5be745b7110\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "doLip7mkc4DRMhF+BFCb/E16bYAzzY2lcMoxRdJ/e9hkyMRQX4L8HPM5lANO5DuKdEoN0vWFluUPfXbjGmawXw==" + ], + "X-Amz-Request-Id": [ + "NXJ86N187AK7VKPH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6591ef638783efd6", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key0?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "5fNTNenMRjVDFcDZbNVfwDd6MiKsrMRzjpBI7zP14CBGyolp8gGObHiXsjlx6LIwJ+Wx4guKYiWSA/r6xBa51g==" + ], + "X-Amz-Request-Id": [ + "NXJ5RV3EADCWDN8A" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestCopy/NonExistentSourceFails.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestCopy/NonExistentSourceFails.replay new file mode 100644 index 000000000..79c8016d6 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestCopy/NonExistentSourceFails.replay @@ -0,0 +1,108 @@ +{ + "Initial": "AQAAAA7ffPPvOaFWwQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "43b46e52b2a9b95c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fdoes-not-exist" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "8Nud4ov4gUpjH9QrrqRsxgra4hF/FBVep7FXVK1+wHyOg1535v0HrEBJxIhLCQ9mS3svUSDoUHA=" + ], + "X-Amz-Request-Id": [ + "7MGTJ1CEWPT4T0XV" + ] + }, + "Body": "PEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5kb2VzLW5vdC1leGlzdDwvS2V5PjxSZXF1ZXN0SWQ+N01HVEoxQ0VXUFQ0VDBYVjwvUmVxdWVzdElkPjxIb3N0SWQ+OE51ZDRvdjRnVXBqSDlRcnJxUnN4Z3JhNGhGL0ZCVmVwN0ZYVksxK3dIeU9nMTUzNXYwSHJFQkp4SWhMQ1E5bVMzc3ZVU0RvVUhBPTwvSG9zdElkPjwvRXJyb3I+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestCopy/Works.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestCopy/Works.replay new file mode 100644 index 000000000..0aa45006c --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestCopy/Works.replay @@ -0,0 +1,801 @@ +{ + "Initial": "AQAAAA7ffPPwAxJXKgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b9780ac6826d8113", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-src?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity", + "aws-chunked" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "sQqNsWTgdUEFt6mb5y4/5Q==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KSGVsbG8gV29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOlNoZXhWZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "ShexVg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "nwwpoBWtTHj/WSpB2S+3Y6vjlCI+F1rAXpxZRNCpH2YB3C6C8xqDXGYf1usda0NPy5CEEFaKMX8Huk9VgM3sTg==" + ], + "X-Amz-Request-Id": [ + "7MGVMJR05GPMQFP4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b1434bf728490e3c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-src", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "yCS2EePgI9yUvv+QC1GN04OeVRKYpRYUSzmsrsX5Xv0omPz1ZsDRUnWITF8hfQPlspeosbnrSqcuCt91zdCOMg==" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "7MGGSDJW33MY44MA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b55509ee918acf17", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest-exists?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "51" + ], + "Content-Md5": [ + "oPqafXJA1cXuvXCJlDDFlw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "10" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "YQ0KY2xvYmJlciBtZQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6ZHZHeXlBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"a0fa9a7d7240d5c5eebd70899430c597\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "dvGyyA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "t0BTiRKi/S1wDScz4dc6ihI5+XqjnPnPWEOlvUu1X+FHhoIoveluHWAowTKKaCiNNvOeqj+wFCN1Xj2x7rqvdA==" + ], + "X-Amz-Request-Id": [ + "7MGHE82YZVX6BYAE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "d4044a3e85db5d79", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fblob-for-copying-src" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "jSC7bkdLXO2aUqz41QMpxqDA6HYicwoKYhAUbNbxz+DG62Hpng9hWy7mN3Y35Lxq8H+auu80a4NgJJcD2BfTtw==" + ], + "X-Amz-Request-Id": [ + "7MGRKH0KQZG7Q396" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iYjEwYThkYjE2NGUwNzU0MTA1YjdhOTliZTcyZTNmZTUiPC9FVGFnPjxDaGVja3N1bUNSQzMyPlNoZXhWZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "a59a5e8dd2228a23", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "ShexVg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "3uHHa4DT7GzI0qnCjcus6/CtGzGJ/8mfe5jrwMA/aCbiuO5dvgIaEKuXPLZ5sSRIXdBOBEDAk5AQJ5A/MK93lQ==" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "7MGMTDKKM956ZSCK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "SGVsbG8gV29ybGQ=" + } + }, + { + "ID": "06043844acaa07b0", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "i/3ja/fP9Y+LI6/r+DErfd8DlGAECJ6X4Jatm3JnxbKF66uNHfiTCnaoinomznpKwGkbP3cBWH1MpD3kbio4zA==" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "7MGXZ397986M744M" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "45950101f26cbae0", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest-exists?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fblob-for-copying-src" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "grizvXXATy7WXtO2HYYY0UGhTZNQIv+yzcm8TsnSJ/kDUp6dzRNThsF6+C4uOMHtg/cfZ2Gkh+00AF1kBYGZng==" + ], + "X-Amz-Request-Id": [ + "7MGJXVPF7Z99EKHS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iYjEwYThkYjE2NGUwNzU0MTA1YjdhOTliZTcyZTNmZTUiPC9FVGFnPjxDaGVja3N1bUNSQzMyPlNoZXhWZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "2220464d11f29456", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest-exists?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "ShexVg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Y+FTaA+boWKQmAhu2WzaaBnCy8jOgoZyAuT5+XJeV+SmuIAvq65AjtQxKENfjjGMCqvlIPqiwOPXnwm2eLvFug==" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "7MGVZ19XR73MJWVZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "SGVsbG8gV29ybGQ=" + } + }, + { + "ID": "9bea74331bda5a1d", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest-exists", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Rs2NrE6+bdLY5lDVtltPdvVXdKszpodegRxogJss+PPaUZe4FdEZk1bfIcHQBuUsmi94Hjc6N+KIUXW6QqiogQ==" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "7MGKR264BTB6E1VW" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestDelete/NonExistentFails.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestDelete/NonExistentFails.replay new file mode 100644 index 000000000..3776a4c5f --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestDelete/NonExistentFails.replay @@ -0,0 +1,102 @@ +{ + "Initial": "AQAAAA7ffPPwF/rOXgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "e5adbb3491fffa7a", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/does-not-exist", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "BQ7dPy+/HQeaB1GGuwsAkL/Uah26a5Gj/FajxHSzPiPyuzsau2fBBBOff5WEjuQW0tRNx3dwDVEq0cElh5luBg==" + ], + "X-Amz-Request-Id": [ + "7MGQ0TF4XQR78EZW" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestDelete/Works.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestDelete/Works.replay new file mode 100644 index 000000000..3334a3f65 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestDelete/Works.replay @@ -0,0 +1,364 @@ +{ + "Initial": "AQAAAA7ffPPwHJMfnQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "c298e99c31d461a3", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-deleting?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "PiWWCnnbxptnTNTsZ6csYg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KSGVsbG8gd29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOmk5YWVVZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"3e25960a79dbc69b674cd4ec67a72c62\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "i9aeUg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "NRoADEOX1F3f0EIjSQFdS+QZGPkFgw7iyNaYiZQwDR9jdHLW/BABlMl8i2ml3CVuZ8GjKLyPG0nHzNb+afkpKQ==" + ], + "X-Amz-Request-Id": [ + "7MGPT26YWHA0N8MA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "75ffdc91073a45b6", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-deleting", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"3e25960a79dbc69b674cd4ec67a72c62\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+ypll2abqRnJekaErDv+waY2n/CUZwPL3DczL9DjzPxDxCcPuI4Xa12FzAfX7Z6oMKdK09Ii1ZIq/hkqqnKQRA==" + ], + "X-Amz-Request-Id": [ + "7MGZFF0S3TDGBBSA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "34936fe5c980e8a3", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-deleting?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "88JNenNoYWCXBjnMgt0NcpuHmOIv67iCk1RCzaDkuFBeKzw2RF2wuAiCgiu7zLAPC3+BpjrzYz16KbqwcB5P0Q==" + ], + "X-Amz-Request-Id": [ + "7MGM0WPZDVRN5GDZ" + ] + }, + "Body": "" + } + }, + { + "ID": "10bb4f7f7dbe971b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-deleting?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "lRVSPjFhjOw+GvhKgG3sI9EN2W6Yqxvh4tPfF3lEK4kUMuWJtnWbC3dk0cSytseAnPGhPNxSEYw97W6GqdZwZw==" + ], + "X-Amz-Request-Id": [ + "7MGP087FWDM94952" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1kZWxldGluZzwvS2V5PjxSZXF1ZXN0SWQ+N01HUDA4N0ZXRE05NDk1MjwvUmVxdWVzdElkPjxIb3N0SWQ+bFJWU1BqRmhqT3crR3ZoS2dHM3NJOUVOMlc2WXF4dmg0dFBmRjNsRUs0a1VNdVdKdG5XYkMzZGswY1N5dHNlQW5QR2hQTnhTRVl3OTdXNkdxZFp3Wnc9PTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "18ddce16dc82bad0", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-deleting", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "wceoYwCXes6BOcUALDqTs/wwIAK6bLqM1TKPYgNI9w7iO/72wmKpspditGoF0cxyFFACNJW1Z3jpZPsB9FvLOg==" + ], + "X-Amz-Request-Id": [ + "7MGT06RSRY0561Q3" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestDirsWithCharactersBeforeDelimiter.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestDirsWithCharactersBeforeDelimiter.replay new file mode 100644 index 000000000..c21eb2d0a --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestDirsWithCharactersBeforeDelimiter.replay @@ -0,0 +1,1265 @@ +{ + "Initial": "AQAAAA7ffPPmLv5+WgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "9368cdb2d91d42ad", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "OF8SJNz/2+Ay5ZHQn5IbQ6mhD0ouQEZHZjmA0/T4Dj/6L6VhRc2PbynDmVyUzPGIVI0T5uRke6w6KN39bn+Mog==" + ], + "X-Amz-Request-Id": [ + "3WXKA0EZ0TFG2X9M" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PEtleUNvdW50PjY8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjEvdGVzdEZpbGUxZGlyMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyL3Rlc3RGaWxlMWRpcjI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC0vdC48L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC90L3Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "89379feed755f2a2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=10\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "lhHY3azhG61QL++HLADA+YrDyb3zglZ6dltynUks7V66eniBn/biCRyk4TneSAO/9nPI9VZcbNSJlWdo8m1tPg==" + ], + "X-Amz-Request-Id": [ + "3WXTSG131BWHBRYA" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PEtleUNvdW50PjY8L0tleUNvdW50PjxNYXhLZXlzPjEwPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTE8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "8c39f79b056a19b6", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=9\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "SA55x5y/YrY5FEL0eCwsAd64FeevkWMW0/1nu7974ZcUoIiOmIhwSh/9+nzfeV5KhI/OG7soPGH2k4XY/MNKIw==" + ], + "X-Amz-Request-Id": [ + "3WXJ511R826JM33X" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PEtleUNvdW50PjY8L0tleUNvdW50PjxNYXhLZXlzPjk8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "469e57d0f2f7b761", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=8\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "ywvx4bS0Y0QlJNl42T3VljGzZjVZPaJKwBgoDxWw8Bqe0crwvsZyN8XV97NjYpNgAsNRCiY/K0hKSrsSUq3e5A==" + ], + "X-Amz-Request-Id": [ + "3WXZM4AVT8Z86XF8" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PEtleUNvdW50PjY8L0tleUNvdW50PjxNYXhLZXlzPjg8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "26d44f2f067cc5df", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=7\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "2fjW8SRsrrAWOiMd7WCbSOZbRT1LcpCEziJ7fpvRL1rDcSfePo3MQWnuqqaUpjTknK0udva/QwV5sy4KL61dJQ==" + ], + "X-Amz-Request-Id": [ + "3WXRZ22PBFK544HV" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PEtleUNvdW50PjY8L0tleUNvdW50PjxNYXhLZXlzPjc8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "61ac71c433709f87", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=6\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "9qj+DY2Qca7EdKXaDRem3EWPvF7LxsAVM3WYes+7fmFOxbiD6WNO6EP3PNICl8ealwlkyYuSZk3TqZjyyLxQcA==" + ], + "X-Amz-Request-Id": [ + "3WXXPBTY100W81HA" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PEtleUNvdW50PjY8L0tleUNvdW50PjxNYXhLZXlzPjY8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "061cd80395b9446d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=5\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "9xjJxbghaDh1uh4peVCbU+RHfCYAG/pue0TyN9IiuEMXdCYhgz7iXGTyWh8LZqHwx8xuLtUj1OtPK7LlHznDhg==" + ], + "X-Amz-Request-Id": [ + "2DCM9QN6A2XZ2MA1" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE5leHRDb250aW51YXRpb25Ub2tlbj4xUmxNcE9BUVJPdkVjOEZ3OXdTa3lRemQyK0hGSUE5Z3RIVldObUdkMTB1eTY1SHJJN2dEeHFGNlVyajJCNUJoajFOOEwvdXVUZ1pCcWdCUlR4UjBNdGlXODdtN2xIZDUrcnh4STQwMXUwQ289PC9OZXh0Q29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjU8L0tleUNvdW50PjxNYXhLZXlzPjU8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "37bd750a72d0dca4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1RlMpOAQROvEc8Fw9wSkyQzd2%2BHFIA9gtHVWNmGd10uy65HrI7gDxqF6Urj2B5Bhj1N8L%2FuuTgZBqgBRTxR0MtiW87m7lHd5%2BrxxI401u0Co%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=5\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "mOGq1hb1cFnHdIhqO1BiQbKfeI02z2vU23KRwj/dnjEjb0I+cgP4tAqx7nrmKnwNffzSOlA1Cm1GkND5oJo4KQ==" + ], + "X-Amz-Request-Id": [ + "2DCVGW51X904FKP5" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFSbE1wT0FRUk92RWM4Rnc5d1NreVF6ZDIrSEZJQTlndEhWV05tR2QxMHV5NjVIckk3Z0R4cUY2VXJqMkI1QmhqMU44TC91dVRnWkJxZ0JSVHhSME10aVc4N203bEhkNStyeHhJNDAxdTBDbz08L0NvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz41PC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "c73d644ced9d1f5c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=4\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "uVcK8dv2y168mUz+dZJy/HXJmudnIp7ZTOhTt1JUYfUcyaY3JFcJvD7s95pDfy1fbQ12MS0EEfdPN7xFa4pKqQ==" + ], + "X-Amz-Request-Id": [ + "2DCVW7CVFP72GYVN" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE5leHRDb250aW51YXRpb25Ub2tlbj4xSVltOEwwRWdjazA1V2tGWU00amp1eW5hdVBaUklvZ0NHU21vak4xVHFpMnhKMEp4STlWUXlZMXpqR0g5OHluRkRHeTBQSENPUkpyampkQnJWSTFCTmRNUjk4aTBXVnJ1UFE2VWJvOHZab2c9PC9OZXh0Q29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjQ8L0tleUNvdW50PjxNYXhLZXlzPjQ8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "9304fc879a49e53e", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1IYm8L0Egck05WkFYM4jjuynauPZRIogCGSmojN1Tqi2xJ0JxI9VQyY1zjGH98ynFDGy0PHCORJrjjdBrVI1BNdMR98i0WVruPQ6Ubo8vZog%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=4\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "NCP4R8fFXFvjgytbO9pEayaEh0FUfdBVNTwgfoDz40GtPRflDNQnzFlDZW0ZoDXFc0tOgfMcmAegvvG1YtBPfQ==" + ], + "X-Amz-Request-Id": [ + "2DCKWKAW7SSJTK94" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFJWW04TDBFZ2NrMDVXa0ZZTTRqanV5bmF1UFpSSW9nQ0dTbW9qTjFUcWkyeEowSnhJOVZReVkxempHSDk4eW5GREd5MFBIQ09SSnJqamRCclZJMUJOZE1SOThpMFdWcnVQUTZVYm84dlpvZz08L0NvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4yPC9LZXlDb3VudD48TWF4S2V5cz40PC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "4435a5d4490c6d8a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=3\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "9Z5FOQ0NGRRaUftx6w9fGHq4tS702C9Vtz04A8MP8PQqa7zDUugAmFxyfggBcb+LofAUbeMx47lbwhOmw8S/hQ==" + ], + "X-Amz-Request-Id": [ + "2DCQP62TPXTDHJPV" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE5leHRDb250aW51YXRpb25Ub2tlbj4xa3hQNlJaQXJ0V2l5OG5JNkZzSlBTOHlHUmpoVmpQQ3NNNGxyaHF0dEZqWmFyWTJKYktlQkl1b242KytTeTdteVVudmd5UWsvaFRUN0FMbTh2aXdhaWRzMWcrU1pscUFRM2l1RWcwK3NnUUk9PC9OZXh0Q29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjM8L0tleUNvdW50PjxNYXhLZXlzPjM8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "c1caeae3422459c9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1kxP6RZArtWiy8nI6FsJPS8yGRjhVjPCsM4lrhqttFjZarY2JbKeBIuon6%2B%2BSy7myUnvgyQk%2FhTT7ALm8viwaids1g%2BSZlqAQ3iuEg0%2BsgQI%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=3\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "6NliA82HCIc6CW9xsUeDj1meTa7s5IWI2gkoB3ZVCpKZn0oRuPigKMs6MtVEckH2O1l7Loq2NyakFi7MtEky9g==" + ], + "X-Amz-Request-Id": [ + "2DCQKMFXANJG23TE" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFreFA2UlpBcnRXaXk4bkk2RnNKUFM4eUdSamhWalBDc000bHJocXR0RmpaYXJZMkpiS2VCSXVvbjYrK1N5N215VW52Z3lRay9oVFQ3QUxtOHZpd2FpZHMxZytTWmxxQVEzaXVFZzArc2dRST08L0NvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4zPC9LZXlDb3VudD48TWF4S2V5cz4zPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "141b874bb9a5cc20", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=2\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "ayVl7IWhUyCDW2dpWhXZvoZVyWN7I6CQw3nz9WNtTkPva+ONIzyfpBomIf0J1os2L6oVCahOCsAOjKaHznrUPw==" + ], + "X-Amz-Request-Id": [ + "2DCN0Z5TVRQ3QDGJ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE5leHRDb250aW51YXRpb25Ub2tlbj4xd0N2dWlBU3V6L3ZkSThlVFZKaE1jWFNJSzcyYmZia0hCQk1ZYVBZbEI1cjFKREJicEVVZlVhUENiVFdtQldHUGpaeFBwMTkwd0RqSDczVnhZMjc2MDBYdDdJcTZmZmVvaVJ3S1hJMjdHVlE9PC9OZXh0Q29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjI8L0tleUNvdW50PjxNYXhLZXlzPjI8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "8b71e5086023484f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1wCvuiASuz%2FvdI8eTVJhMcXSIK72bfbkHBBMYaPYlB5r1JDBbpEUfUaPCbTWmBWGPjZxPp190wDjH73VxY27600Xt7Iq6ffeoiRwKXI27GVQ%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=2\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "bctONUOk4/ADHjG38cvvU+FaRKLTet4+J3Jhjus7M2a+eD+PBtrzN0V2HqDboKw+yogdWmzasZ69aPJ52bDfqQ==" + ], + "X-Amz-Request-Id": [ + "2DCQECPJNCGEYEKT" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjF3Q3Z1aUFTdXovdmRJOGVUVkpoTWNYU0lLNzJiZmJrSEJCTVlhUFlsQjVyMUpEQmJwRVVmVWFQQ2JUV21CV0dQalp4UHAxOTB3RGpINzNWeFkyNzYwMFh0N0lxNmZmZW9pUndLWEkyN0dWUT08L0NvbnRpbnVhdGlvblRva2VuPjxOZXh0Q29udGludWF0aW9uVG9rZW4+MVFVTmU3U2l1TW9QVzJ3NjhlNVZKMVBEWXJRY2JQcEcwTmg0VTZET3BwR20xUmJ3VmxXQU1teGpFUUZURHRHWDhmZ3o3cFdPeUNMY2tWK1lacDhKNG9selduSVNJaVVlUCs5akZYbW1kRkdBPTwvTmV4dENvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4yPC9LZXlDb3VudD48TWF4S2V5cz4yPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC0vPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "356e5e76ea4aa1b2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1QUNe7SiuMoPW2w68e5VJ1PDYrQcbPpG0Nh4U6DOppGm1RbwVlWAMmxjEQFTDtGX8fgz7pWOyCLckV%2BYZp8J4olzWnISIiUeP%2B9jFXmmdFGA%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=2\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "BgMKQ7u2QswJlSKh2XSeDjsuMOKAs8aQxJypFaTh9GqUt0N+JGw/pAiCtVUvfgNxmPvOON42yDvyJ5dXHXiZXg==" + ], + "X-Amz-Request-Id": [ + "2DCWQ63ZRT2GNAK8" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFRVU5lN1NpdU1vUFcydzY4ZTVWSjFQRFlyUWNiUHBHME5oNFU2RE9wcEdtMVJid1ZsV0FNbXhqRVFGVER0R1g4Zmd6N3BXT3lDTGNrVitZWnA4SjRvbHpXbklTSWlVZVArOWpGWG1tZEZHQT08L0NvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4yPC9LZXlDb3VudD48TWF4S2V5cz4yPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "a572dbacac5b8c12", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "3NpJ7aM/To0D7vw5Vv3hixaXtoktTyk9S9xd+oFZkAbYUB3JxCbR14CsBBCntrZEn5BCOHoSGOS5msY3s//QDg==" + ], + "X-Amz-Request-Id": [ + "2DCM6VTX19RYER10" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE5leHRDb250aW51YXRpb25Ub2tlbj4xbzNkclhmTm11N2dqMk9ZTVBub1pDM3B3YVRZWkxDMTdQbE51TGxPNUY2SHlHYUh6RUxBUFc3NkJVL0FiVFU0emFqMTBNNzQ5bDV3SWs0d2dmWm4wY3hHRjFIWUtmMWFBYW5XZytGYWphWGs9PC9OZXh0Q29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjE8L0tleUNvdW50PjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "c4b291027bc31084", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1o3drXfNmu7gj2OYMPnoZC3pwaTYZLC17PlNuLlO5F6HyGaHzELAPW76BU%2FAbTU4zaj10M749l5wIk4wgfZn0cxGF1HYKf1aAanWg%2BFajaXk%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "uQvyv8y/S1Xovz9IfN1RTEOui11HUqzCZbZZgynY8j4abhoEadNgXI+d0UOXiXElQPcUcXgX62V4PS52HZjgSQ==" + ], + "X-Amz-Request-Id": [ + "2DCTTMDSSTET04DS" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFvM2RyWGZObXU3Z2oyT1lNUG5vWkMzcHdhVFlaTEMxN1BsTnVMbE81RjZIeUdhSHpFTEFQVzc2QlUvQWJUVTR6YWoxME03NDlsNXdJazR3Z2ZabjBjeEdGMUhZS2YxYUFhbldnK0ZhamFYaz08L0NvbnRpbnVhdGlvblRva2VuPjxOZXh0Q29udGludWF0aW9uVG9rZW4+MVdaK1ZtaVFJNFRCeHBnZVpVRmFSZFlQSm5DUThiakNBRHFXYjY5bHN5V2dKUGZrbEdLUDdXZ1BJOU9oaXM0eEJKeHUybCtMRSswSmFIck1JaEhPWmhkUm5KOUo3Qi9rM2RoRWJnQWZKRlk4PTwvTmV4dENvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "f3e36a1ef8e04486", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1WZ%2BVmiQI4TBxpgeZUFaRdYPJnCQ8bjCADqWb69lsyWgJPfklGKP7WgPI9Ohis4xBJxu2l%2BLE%2B0JaHrMIhHOZhdRnJ9J7B%2Fk3dhEbgAfJFY8%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "TB2WZ7payPoGnxsPpcILR2x+snYnG+o7Jtp0EgN7O6KthS0MH4gmimb6H2DBM8wE/GHWiUlHGrObwei6ISNmIw==" + ], + "X-Amz-Request-Id": [ + "2DCQNA7QC8RVVP76" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFXWitWbWlRSTRUQnhwZ2VaVUZhUmRZUEpuQ1E4YmpDQURxV2I2OWxzeVdnSlBma2xHS1A3V2dQSTlPaGlzNHhCSnh1MmwrTEUrMEphSHJNSWhIT1poZFJuSjlKN0IvazNkaEViZ0FmSkZZOD08L0NvbnRpbnVhdGlvblRva2VuPjxOZXh0Q29udGludWF0aW9uVG9rZW4+MTFScHBjZU40eEF1ekY3ZDNGMytnMlNKb2JBdm5ST3dHTmlDNEcybC9sNHpXNkhEbHNoK1M4RTBNQVdteGVkUUhrcVJCQmgyWHo4c2paZkM1TDlQUGJFaFp3Y3VqUWxuUmFSWDhKMzhvb1Y4PTwvTmV4dENvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "575559fb6561e338", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=11RppceN4xAuzF7d3F3%2Bg2SJobAvnROwGNiC4G2l%2Fl4zW6HDlsh%2BS8E0MAWmxedQHkqRBBh2Xz8sjZfC5L9PPbEhZwcujQlnRaRX8J38ooV8%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "8XU0c7Se/ZNzX1HigMEmQuonQhbmcu4dzCA+1vK82E+7bCkyzhrkTICk15TTzBeCfxrvUXThL6l6BcVxe5Zarw==" + ], + "X-Amz-Request-Id": [ + "2DCW0PBAK7GJMD2M" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjExUnBwY2VONHhBdXpGN2QzRjMrZzJTSm9iQXZuUk93R05pQzRHMmwvbDR6VzZIRGxzaCtTOEUwTUFXbXhlZFFIa3FSQkJoMlh6OHNqWmZDNUw5UFBiRWhad2N1alFsblJhUlg4SjM4b29WOD08L0NvbnRpbnVhdGlvblRva2VuPjxOZXh0Q29udGludWF0aW9uVG9rZW4+MW1TK25NcDRYVzJYY0p5VVBMUVVkS2IxS0VxdmY3bFZyZ0JGYjU3KzlDRlJTQUUvSmNsSjV3bGFtN1owWHlKV2tPSGNGemZlQWJ4ZENKZGtuaDZnUnN2TlVjZGhTQ1g5SlFKdWw0ZTYyQm4wPTwvTmV4dENvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "965e8053c9c57a2c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1mS%2BnMp4XW2XcJyUPLQUdKb1KEqvf7lVrgBFb57%2B9CFRSAE%2FJclJ5wlam7Z0XyJWkOHcFzfeAbxdCJdknh6gRsvNUcdhSCX9JQJul4e62Bn0%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "5WMPcaH/3TNoHqlqouCnjrdU7yenok+y4vI3JDS0gM0xUOJi0lgCIvQVJppqi1NYUQcH/V3BxJ2VT/u24u1XjQ==" + ], + "X-Amz-Request-Id": [ + "2DCS13HJWXC59BYD" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFtUytuTXA0WFcyWGNKeVVQTFFVZEtiMUtFcXZmN2xWcmdCRmI1Nys5Q0ZSU0FFL0pjbEo1d2xhbTdaMFh5SldrT0hjRnpmZUFieGRDSmRrbmg2Z1Jzdk5VY2RoU0NYOUpRSnVsNGU2MkJuMD08L0NvbnRpbnVhdGlvblRva2VuPjxOZXh0Q29udGludWF0aW9uVG9rZW4+MXNnUnA1MitxTHRibXBnbDFHeDVsV1ZsdDJzKzBhVjBFVVU5Y2hhcEdEWFNNMmg1MmttQ3VvY2hya0o4bTFhQWsvTmlDUkp6MHJuSXVpVjVBT2Q0TVBEcHF4OStBd3gvRzRlTGoxWG5nMWV3PTwvTmV4dENvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "269ef06ddcbe624d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1sgRp52%2BqLtbmpgl1Gx5lWVlt2s%2B0aV0EUU9chapGDXSM2h52kmCuochrkJ8m1aAk%2FNiCRJz0rnIuiV5AOd4MPDpqx9%2BAwx%2FG4eLj1Xng1ew%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "6w39Qa03/S02KmRLQa1pKopY50jh0UZoMCpXhzuJnW50LwGiwGfm2jpQbt7jSn9FQBrTmAyEYOI5TT4y7DKmeg==" + ], + "X-Amz-Request-Id": [ + "2DCSXSD8AR1A3B08" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFzZ1JwNTIrcUx0Ym1wZ2wxR3g1bFdWbHQycyswYVYwRVVVOWNoYXBHRFhTTTJoNTJrbUN1b2NocmtKOG0xYUFrL05pQ1JKejBybkl1aVY1QU9kNE1QRHBxeDkrQXd4L0c0ZUxqMVhuZzFldz08L0NvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestIfNotExist.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestIfNotExist.replay new file mode 100644 index 000000000..94b65b83c --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestIfNotExist.replay @@ -0,0 +1,321 @@ +{ + "Initial": "AQAAAA7fhzwPDIpkKwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "763e919e19f9a051", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-if-not-exist?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "If-None-Match": [ + "*" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text", + "BodyParts": [ + "Yg0KdXAgYW5kIGRvd24NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk9KM3lsQT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Tue, 08 Apr 2025 15:47:28 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OJ3ylA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Qq8whJdNLYQoRRDBL+Sshs9YmDt1hGbEUG0+m+libQFWyYxcPsRql9sIgIanlhOjjjmbZgNswSo=" + ], + "X-Amz-Request-Id": [ + "94AKMXSWVXPHYSPA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7300c90db336a95e", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-if-not-exist?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "If-None-Match": [ + "*" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text", + "BodyParts": [ + "Yg0KdXAgYW5kIGRvd24NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk9KM3lsQT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 412, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Tue, 08 Apr 2025 15:47:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "C+k4OU/6dGtM9ujfEqb03VFYDS6S+4oOw2ymKVvhUDUJnKocoBJKXwp8cL+jznKhDEdcadNFciE=" + ], + "X-Amz-Request-Id": [ + "94ATY2ZNHVZCJSY8" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPlByZWNvbmRpdGlvbkZhaWxlZDwvQ29kZT48TWVzc2FnZT5BdCBsZWFzdCBvbmUgb2YgdGhlIHByZS1jb25kaXRpb25zIHlvdSBzcGVjaWZpZWQgZGlkIG5vdCBob2xkPC9NZXNzYWdlPjxDb25kaXRpb24+SWYtTm9uZS1NYXRjaDwvQ29uZGl0aW9uPjxSZXF1ZXN0SWQ+OTRBVFkyWk5IVlpDSlNZODwvUmVxdWVzdElkPjxIb3N0SWQ+QytrNE9VLzZkR3RNOXVqZkVxYjAzVkZZRFM2Uys0b093MnltS1Z2aFVEVUpuS29jb0JKS1h3cDhjTCtqem5LaERFZGNhZE5GY2lFPTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "f481da281af875da", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-if-not-exist", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text" + ], + "Date": [ + "Tue, 08 Apr 2025 15:47:28 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Last-Modified": [ + "Tue, 08 Apr 2025 15:47:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "1BLNZr0vpnLLHsALFgaU2oT7dOfP0X/PaZhG6o9YvDUrg5i4gUsoMdtlZLNmGMNFLIW1gMRncvg=" + ], + "X-Amz-Request-Id": [ + "94ATGZQQS84NRE5Y" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "d775e14818ab1ff2", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-if-not-exist?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Tue, 08 Apr 2025 15:47:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "yYYfd1ocV26Qckd4Dz4AKS3s7rs3682jczCvotpMkzCB5XTk7MR9zMzvRlrqS6KyAu9ESFkcn84=" + ], + "X-Amz-Request-Id": [ + "94AQESKZMHJWWF52" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-1.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-1.replay new file mode 100644 index 000000000..f4b56fb18 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-1.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPP1HGx1eAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "9f414b80e979836e", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "EpM7ZErmRWE78yJn3NLBiGvUMIoTcM+AjdnE7NGT2H3H7PjNSmdDvME5qMki5gARmxGZXcvE0OY=" + ], + "X-Amz-Request-Id": [ + "5S0HR8QHHAPPV8WB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "4b298f8b59f729a3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "uCGhes1dxC8+gOTXqiUo8xWRvZyK5S4s5h/bOpfA26BJBJTLQcblgS34dScTnwmkbFiX85OL46Q=" + ], + "X-Amz-Request-Id": [ + "5S0P7Z4C8SNN194Q" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "757a13d1ae76e447", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "j/whl/S0pRLqELsxEduBUtKpqXItigmcfb5AOCGHN3dmZIis8euqfgsgkdbjlzdWom1kQWPP+tA=" + ], + "X-Amz-Request-Id": [ + "5S0YZTEPTDYN6WT5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b6920a3c110394f9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9v6obQSyuSymYXB1eKH5zX7LlQAdQynH7P1lvMjZX6fIm7KIx8sLtx0270fEkZe7+fIRk9dMxTE=" + ], + "X-Amz-Request-Id": [ + "5S0MNAV0R811NKD7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "5fec02c511176637", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Z6PYfDb7q9pdniZn08p3idvRNS6UcNUQwFwytPleVUpVpgDun1mYwHsNpnyf9agMmjV34Rw4OiU=" + ], + "X-Amz-Request-Id": [ + "5S0Z96VZ76Y9EJXB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjEwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "2c3b71d51560ab6a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Ny8TGWuZ/zeC+HSScIoKsa9A7mktvs6pTLDa3dCOAU0o+rRqXwTXMELopDvtnUtyERk6TkZy4mY=" + ], + "X-Amz-Request-Id": [ + "5S0WFVMZQYS914X8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "df14192e2d60e70a", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Zd9vUcjvxgIShlt1Mv1OyeU1xFquh0cAN66RpcEperQWnYNCKtZCs2p0uNjEE8bADhl2hmSWLlY=" + ], + "X-Amz-Request-Id": [ + "5S0SXCPS6WXMTBS2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "419c87f8682e9ad5", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "64muDM81yXgnXlKJ0DwLZdEWIVqMlzeiWFWi0YIArl/8ykOI/k8uHXOcRb9vec8IvNjUq5jtliI=" + ], + "X-Amz-Request-Id": [ + "5S0VKEGV0XHA11Y0" + ] + }, + "Body": "" + } + }, + { + "ID": "ee116bdb0c6c3679", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ZhCyg+EfEYu4HWzhcrq4OEk+lpxirTFOHPxS8MaQ0D8ColmGgwYN2xyVWk1wFvXim8gawv2Jz2k=" + ], + "X-Amz-Request-Id": [ + "5S0MMZB4J1EKDV8K" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "3a8991f81c5d12ab", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+s8SLWnQ+09DShwa+g+KyiDjtcWHCjPZY2HzLZ/Hp5ayr2BsRPJL5hOibWxyWzGTag+6AznxCC8=" + ], + "X-Amz-Request-Id": [ + "5S0X5507HVJZ6JFZ" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-2.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-2.replay new file mode 100644 index 000000000..98124b086 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-2.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPP2K8S48AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "6c286d8e04e0222c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "CVzXBA1jwLjfPhfQqVa8fb8SXL4jNnKR97tFIUiTxqBxPdl8PCGYw/lMmDcY40lDurAfNt3VLMeQNqrZESlP2Q==" + ], + "X-Amz-Request-Id": [ + "NQX7EQTVCC9M2TFB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "5189c879a31c9ed2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "d8hjsrCgJTPcl0sQhov/HTRaULgLEXkk5FMCiqvlsefpiSLe3j7SpnidgLJGOFb0CZyhdKNQ0eY9cKW9RrNTcA==" + ], + "X-Amz-Request-Id": [ + "NQX30TTNVKV1S27Y" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "8bab9109e87fa5d9", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "/kk9pKt5e31PFw7qUbBAvpoMgHIeeE6hko031xOiMrMKeDf8ZQeCZfPWN1EurW7o/67tqRJEGP2lxc+v/WYe4Q==" + ], + "X-Amz-Request-Id": [ + "NQX6J8WACD9QD1MH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a57a04c3344237e7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "bjjfmxsQMBYlXfo1z/hN84638mw1t/ZBE0Mz75UuK23/p0uHwF2rYGBTtzkRgWsBQdc3dJsXfYJN3lbD0zwAZw==" + ], + "X-Amz-Request-Id": [ + "NQXCJFMWXCQPPHSA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "1763ab634ed497fa", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Zkp+r9gI+UNgcftLOn8Ye4A5I7SV/ocKTWTNgPOMfkOMHu/LCyfu099aCg4JR4zzvUXxIYxO3U7bMF6rSRln9w==" + ], + "X-Amz-Request-Id": [ + "NQX5HFXM382X5MTV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjExLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "dabb8630157e3f45", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "QCdN22x2cC3XxEAVMGL+MDCiji1KJVGA+p02a2m0WnETOVlQEBFJUL8QgwzXi/6aM+/dKrDmuV9X1XOJz+WRJg==" + ], + "X-Amz-Request-Id": [ + "NQXD2QW1QN8KEEFF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6d3477d16be751b0", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "xrGx/QkhEB+PVWC3727RdbzNzu90cnOD/iyzxwisoE89e0I2Vr3I2LnyN3H9tiUKZeiVlzb9gHsbN+vNb3d+Rw==" + ], + "X-Amz-Request-Id": [ + "NQX4FDQ5Z72TMHEK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6f7e4912428bd8a5", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "W9g1zCxrxzQ7ATxj0RKLoqeHbLY3wNVr19ZfIq3IwUCuzGLLnoF/I2htOXTIOhsJA8K4S3rd9Mf8isBMXa2SOw==" + ], + "X-Amz-Request-Id": [ + "EEN8EQK9J22FKEE4" + ] + }, + "Body": "" + } + }, + { + "ID": "5f887fa61cce7f79", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "8LqvmqWwNuKXIJllL9QtY/ffm2InB3ukBXqG2M7EAKsana2xTVR6DEJPeCTtmdkFBCyuKHMxZi9RQuo4CPQu3A==" + ], + "X-Amz-Request-Id": [ + "EEN5TPH8N8VXEH6S" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0247b5da6615377f", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rnv2oFCtptigEb3gAjX1nj3Fa1ZbQ8ET4bktbzFzT2dGHqCBOFREIAOESr3TfT9sBH44j/Osl+UJWypJyewDmg==" + ], + "X-Amz-Request-Id": [ + "EEN2G738VM9TN398" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-3.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-3.replay new file mode 100644 index 000000000..87c0cda56 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-3.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPPyOKJVVQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "405a64d19ae67ddd", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "NZiz8yPVFWnMuOhECaIawCFHjuDgimah9yLbF2VkqDmMBfHWZ3jIwLSEI1r7o9knezmzQgtVVNc=" + ], + "X-Amz-Request-Id": [ + "3K0JYRJ3KBB76FBC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "dd66092f2442e7b9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "uOnx1cQdA/5/bqOlLsiCVehzaoTJSE1aAL/vzgNjGsB7GAIyXUoMT6slpA40HPwx7XVxlAjiJMc=" + ], + "X-Amz-Request-Id": [ + "QQY9BG0H2PP5082W" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "e21258d1e8c0bc65", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rKYP7mzC9pr35XO64HjMyZvIYSFpMFJh5pCnHhvwA8vNfDL0Mu8p0nvG1YEECZIleo1Z+tI2OHM=" + ], + "X-Amz-Request-Id": [ + "QQYCVRYA7AJC0BB3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "9fe6c328872db1be", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "voktqPDcuH39cgWaY80LteDB3TePKOgPcUNKszloNi6a18CxGg264AcgTSIrvpcPCj9fBxzAUDs=" + ], + "X-Amz-Request-Id": [ + "QQY0218R26NN88VZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "c4853a7f9a4090e9", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys+%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "DDQxv7meTdSmybjaJvBmywsVcDMkGWSuwkeRfLRqQPDPD5OFV+gCcZDycdyol9YCbrpzejIJ5tw=" + ], + "X-Amz-Request-Id": [ + "QQY7P4VFJM32QEPS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "dd35a3c810e6f550", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "sxeITotkG63xDjW+Yi/rPQ1qcpIt4ZimJ1hl66qFZW1FMLhadzY1cCxZ+FWzY/27oZpPZoLkDlw=" + ], + "X-Amz-Request-Id": [ + "QQYA9YE9KJXHBXQB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "c1f2fde93d6d00e2", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "m2TVzQuxBey+b55q1L+DXRBl9IXEhSg79sfSRPyIYtiEHAxkJYv6qk+/DxWRGHkyGU/u0WOTPoc=" + ], + "X-Amz-Request-Id": [ + "QQYF4R10RBXP386E" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "f313370b87f9a3c0", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ZDCbFuHvhCkW/1CXSCdO9/TXDZm7q32STYOeU3/jev9eI6RE5t6SnDWWc6zhC7CbwwDNMpteRUI=" + ], + "X-Amz-Request-Id": [ + "QQY2SQD3PTQSC7T7" + ] + }, + "Body": "" + } + }, + { + "ID": "58c3e2641329a31b", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "7Z0oMPvGhotLosl53omUlUb96a/UHmmYwyJhqB8qHztFqtnFhgHns2Ht5ea2phy5NLTRZ28fNhI=" + ], + "X-Amz-Request-Id": [ + "QQYE90E2EJ2PKB6S" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "50e60f03be0f4beb", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "BDRwjDPRp3qvCT9sbLoeH9E77Z4oh4Dp6oMZgqJApTZ71BMIoRA7o35ndi6hV3tdregIW03OmyU=" + ], + "X-Amz-Request-Id": [ + "QQYFH0WC93AN3E4N" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-4.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-4.replay new file mode 100644 index 000000000..05942fcb2 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-4.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPP3BhKtgQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "6dc819acbdd45b52", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Ltjnz8498mDpeGLxRjOndEy4B+SMCvVgqaGcfPddjk9UovjRrAb+WEhXBFP+VM8E9Yj2SpF8faOe/Wo1Wa+25g==" + ], + "X-Amz-Request-Id": [ + "EEN1ZK7C3B8XDHBN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "24f59593ace0364b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "/NFy1gvP4bITDvt8TAasmp9CsHBqjf/mEtQ8LP7VIAEwgESo8Xps2D5ySNCYpkfGJnNLaUnFJ07sa91NqubzMg==" + ], + "X-Amz-Request-Id": [ + "EENCJZ4GAGS47TYX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "ae9b00f73979e0ab", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "JOSW2gcHH2Bf9ZtxiNr4+u4oimd+nBVgHrzP6hS8jpH6sCvrlinZ0SY6JLQ7lcY4ZOWYh0G30ksmY9mUGETYsw==" + ], + "X-Amz-Request-Id": [ + "EEN12VJKEZT6T7H6" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "e9cd5bb359cb7462", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "TeosT6sdBHLWKKs+DSsNfEKDZYqjDwlVhb4FRU2KuJ9/EUn/SBaO4B2oYBMg+2IeMJkc4KWN03CrRKbaWdCqIw==" + ], + "X-Amz-Request-Id": [ + "EEN8SSKSRY50MWK2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "17b2aa6a4ae0d7d5", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%3A%3B%3C%3D%3E%3F" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "7qEf9Nh9exBqTU2tp0q7duotrgtC0UrFDkAixnbp1fu0zQYcoyeOikvqcs7ADrdoYWIWzqOH9MMbk58lyJJTbg==" + ], + "X-Amz-Request-Id": [ + "EENA6D9K9204P63P" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjEyLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "dd7db67e25a7182f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "IQt0sk9XjMDzsOV8IUkHfYURYlIFvnb41pIcnTqjw2jZ3hfbbRILRvdHo1x6HDA370CI4dG1mpENfsfWoL8scQ==" + ], + "X-Amz-Request-Id": [ + "EEN62YRZPKXFXJZF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "0a5b6e20c363017d", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "5NclqPYrRUf+KxlehdaXmt7sj+1U70s4/PPUniEk2e6hMFSTUxyrjoAGx/PwABp2S+NQ/zBpoAfDA2WKYZMuqA==" + ], + "X-Amz-Request-Id": [ + "EENBG0AAS6H5VNR3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1fb2d83babf17f25", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "OGexuePcWzxi4TVsh7V+8G7P4L2M1khweV6vqPrAxSrGDERWVrbRNhIaNICHXcqcwHBZ8e6IbvTjhygTWPpxpg==" + ], + "X-Amz-Request-Id": [ + "EEN6M9D737PVH2JW" + ] + }, + "Body": "" + } + }, + { + "ID": "9b446ba3e47e52a7", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Ehnf0ZQO9MBZkrcMI5EtI2KlzVq7xGJfjgi0Y6+zRBbdwFGceenRT5hFRuwj1N11iGY9cL3OBKlJRgKlhp7D/A==" + ], + "X-Amz-Request-Id": [ + "EEND80RD2DEZJJS5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "f8ab64038efe3476", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "C4iMhZYkerOshRLOb9LVH4sIIZyqy2t8k+GRjHyrtx3/xLC5M+f2qCWGHAJ56DleK92xgO5EWz/1Wy+13zJPQA==" + ], + "X-Amz-Request-Id": [ + "EEN38950W0PHAYGN" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-5.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-5.replay new file mode 100644 index 000000000..85eef4a81 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-5.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPPwKO7bzQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "97e714fa37d4fb94", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "tDcS5tmc5hNU/SSakNVJKwtUYma5ZPrbl7q5y2eWbkPjoLGsOuOlqM5Z5lxTQyz6WRIH0gd/1Fk=" + ], + "X-Amz-Request-Id": [ + "7MGXPJY1T55QNNTC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "373ec1c970cff466", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ktfbn/CVcAhAZWTX+utAD/E6TVV7ne7wUZmAFnoqf550TgpN6XCNJrTkviLLV7g+Xjoe6sZd33U=" + ], + "X-Amz-Request-Id": [ + "7MGTRZHH3TSZMY7C" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6e9ea07521da4163", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "RIILfudMTgYuMtD2qKaBbIJy3MAjc4vXB4enSakTgJa+Z14kjXXhJWZ0MX7BEfgZWDE1bJ1Lzvc=" + ], + "X-Amz-Request-Id": [ + "7MGVN2JPCV2XQN4A" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0bfb6c581087bdc7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "s4uOGw6DKwdBAcw7oZHknlEPVYIy1W3ZySxJtmC1OKm4HaSkjJjQPAIPyCrwmavXWBnl7MjSpvo=" + ], + "X-Amz-Request-Id": [ + "7MGJH7PE3C7PHE19" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "bb2d339f1c319fef", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%40" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "gYQ1lXH8MrvpcX4Y0LDd23RKEtL1jILChZZ8NKDyqBk6MHjO0SOzydJnLsgIl5awuyq5Djj6aB4=" + ], + "X-Amz-Request-Id": [ + "7MGS6BX1JCKT4X2K" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "5f94e388c44abeaa", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "nN4HQCmrERU/MxENka/XNdMxNmNDXcoFiIPmKQ0V+ySAZ8YvT5OnoT4dNqwqziaqwV21SEkdjCk=" + ], + "X-Amz-Request-Id": [ + "7MGJ5A7P5HDDJPSE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "980519bf36312070", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "RQTy+LQD0Dm+gPj53P+DvD4PmCZ4vW6KcFzxXRlOGG13T+P86b0jgUkZURC5cZGUADG26gsZ38M=" + ], + "X-Amz-Request-Id": [ + "7MGYGNKKNY6HAZ79" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "331e3054373b5066", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "R7SQbSzQmJfIhl3ng6H2CDDILZbRM/7RoslMZiypv0a0c96d5VH0N19p6KyR/2ukDVVto3EYr0c=" + ], + "X-Amz-Request-Id": [ + "7MGRDVPWGZT8VPEN" + ] + }, + "Body": "" + } + }, + { + "ID": "6bbcb74c64edc4a0", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:05 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "w0TyvlOdgmt8oN18JpFVnryMXVcf3mqERYhfg5+Fz9W8Lppa6v869sVQkzD6yu+YSv1jKv171vA=" + ], + "X-Amz-Request-Id": [ + "7MGG47FRBESKWCG7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "50b52823ca2b9527", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "mHJkRwZ0db2zAGzTuuR1m0sqTXQ53s+vh0AQLfRUGA6sBHf7oEd57K/8MI+ubPBNmybzbnwXg4k=" + ], + "X-Amz-Request-Id": [ + "85TBV1W37K66SSJD" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-6.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-6.replay new file mode 100644 index 000000000..b52148994 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-6.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPP1Mi5wNgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "bcefda6e01919548", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "gX55K8P1fnp+SFlUS/JTbqvpRCMNsYEpOrfk7T9NNTViYtJnS8r/+bu29I9BTYYnxNpBSUbBFXM=" + ], + "X-Amz-Request-Id": [ + "5S0ZTXTG197FWS0R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "32ae12d4ae30979d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "50ZQ4ALkmpxJRrgmh3/ud3iwhTRIov7q4FLfiVSrFTwJf1EXuXapzJ2kn5CrMFYfdhESepifiEY=" + ], + "X-Amz-Request-Id": [ + "5S0Z0R3E7E3ZP5CR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6590a52f5ec1e3f0", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+umt133zG4zkHos/sk6aVcxwBfQCgVwyPE1je+0CL6Du0FEVqP2eg12PBCGisyXDqRpM/C5BL3Q=" + ], + "X-Amz-Request-Id": [ + "5S0NKJF5J7XMKF9Y" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "afcfbadc1087ef1c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "jx26pApPLVdLN+EZWLb5KCfncX0qNMEQLX/bztDvsTfpAft5dyt/Kum/YrwKvSjDfJJGttRLG8Q=" + ], + "X-Amz-Request-Id": [ + "5S0PWE2BZCMNPYEQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "22cee18a994063b1", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%5B%5C%5D%5E_" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "LToBynQ/1mJLfYPravbMIfcIOqtzC7nyhJQXzCX0GbvgaSTCZ6872xi+dPy2zG573DZSGLUFyC8=" + ], + "X-Amz-Request-Id": [ + "NQX8HWFAD31FWWKJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjExLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "c5d6550b1ae099e6", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "C5+lpxgg25HS4Mf4j7HZ9qzPH6fAWD+eUM6heOrvWoKYcXcjazsLmd8tvg2/uSr62klFWd0IztM=" + ], + "X-Amz-Request-Id": [ + "NQXEDVZGR3P4DPKQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "82f7c2adac414364", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Ry8oAKed9uNrOedXoPrF34BZ/MlsDfiRA9fvkTkuYMuAZdxT4nl5DDAPRyQGlhJCN2HXZ5NHHVI=" + ], + "X-Amz-Request-Id": [ + "NQX3P2S51C9RBWYT" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ff67b816ebf6fbb5", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "/x0szljP4wfOXd/szGRETZQls7N5OVPZTYUG0dPFSDEo7YtzA4OfMaklC3RRV7PUS5+XVWJaigs=" + ], + "X-Amz-Request-Id": [ + "NQX1G90KFTG6GQXC" + ] + }, + "Body": "" + } + }, + { + "ID": "3320f6575b1588df", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "8jkNrhf3Fd7QB6pQfEEmFnItf7IjfLNJ0rv+fNVSpcMcCIi92hlrXzUCWb+qbde8Jwd1o/Oa/hY=" + ], + "X-Amz-Request-Id": [ + "NQXAXB8YR69SH9YC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0bc0fe7dc4447aad", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "YdGmm3BoWKTGGFAZ5kfChxG8zRsu5fp/QwkqBeToeElPEVxW8rLRtiz7HEaYllzcw8cV9pbK/fM=" + ], + "X-Amz-Request-Id": [ + "NQXDS9VMNMF1S8H4" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-7.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-7.replay new file mode 100644 index 000000000..9269a2528 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-7.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPPxArDA6AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "d1ff8ea5ee677a36", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "MGqjZPWgZfhuARlc+6sLo5izIm4+OcWMIhW9WilwgW8O6RIVM5lw1MIyC4U2R44jUg5G0IdTpUg=" + ], + "X-Amz-Request-Id": [ + "85T231QNNX319MWZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b6a68a7f033f3731", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "qT8cTcZzlG6zmdrXEyg0yelfURno3S8xpTq2xmOlBI2TagdtR9uck5fGa6Usl5xKP1XHy7k1A0c=" + ], + "X-Amz-Request-Id": [ + "85T83MAXAMP617K4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "f03511cf32b8cd30", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "pOh+awbec8SaHVfDc0nHo/DAMSL0vTIgKZR2YClO4N9LYCpdyGFZ4NNNDHyzbgLWDp2SX4jwXRM=" + ], + "X-Amz-Request-Id": [ + "85T1SBMN5SZ9Z8WB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1eda210bf5f8a3f6", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "pHCUAglgFe4b7s/wCPMhAZs6o7q4AFnbtthmq3jvQQ1UDAZ6g6fYdf5yjZemxl0burdHpwzNtnw=" + ], + "X-Amz-Request-Id": [ + "85T9TJWXT2QZQDMS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "4f3196e92468d359", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%60" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "DxjuR638Uq9v8pX9ixPM8LMMDN9MlKuq9H+Ut5aesl5ZJrjiaVH8exXK3vxg6DDqoUGLgnDSL/s=" + ], + "X-Amz-Request-Id": [ + "85T7PC18EA6TFGRF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA2LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "96426321f8593166", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "xae4TAzHIuawRxfYTnmy+8OosXVRN+PseOS7gyt+H8DByPCfwrfmC9g/le6HOaktb3emVSw75nc=" + ], + "X-Amz-Request-Id": [ + "85T0G5EY6SQYDABF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "11e6bb4dff639f7c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "qohSqUeGo7JYZX7szzi+e+VKmz+D2f7biY2bc7H/ruhhoc8GPOrSevt2GO2H1l5Ixx+NcvfNFMQ=" + ], + "X-Amz-Request-Id": [ + "85T890BR11ZK920G" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "16b7c5af2356f7c9", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ySCGzf0rJgV3YMzDFHbMs5T4HVizKYH9mmzX22iPbqrH15iuRA9IL8jJcOSeD71UDViEwPqeCN4=" + ], + "X-Amz-Request-Id": [ + "85T9AARS3PTY90PF" + ] + }, + "Body": "" + } + }, + { + "ID": "9bcb5ce8f39d549e", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "RsmmJG1r5tjT2ChW+gIkM1LFZzq54mRPR+z+CxfudrEhP1JGU4vHVJKF7aXOsLx3vyEMDOvlv+Y=" + ], + "X-Amz-Request-Id": [ + "85T5WBS5MMDG03KH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "510dcb5ee948ba6c", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "y/EsV+C+85Pz1DwvnHdn/GFp04NAqOSjoPK6p9Qan92pEGzzNIIJSgch4rqLLDvzc0J5icx+O08=" + ], + "X-Amz-Request-Id": [ + "85T4BA38R7WMPQAQ" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-8.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-8.replay new file mode 100644 index 000000000..0bf9059c3 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/ascii-8.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPPzEYQ8yAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "9c0c386d0bf55b0e", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ZG6DKMGpC/alrJyLoyWYOGZsb34myY9W3SiD2Jzvq1L1rq6zMSNUkQmK+PdpZD43s6zLhbbTb7A=" + ], + "X-Amz-Request-Id": [ + "QQYCD1PNGWZYQVN0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a0241bf6625f7f82", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "LrT9CfSLRhZhlSlCwhcq0O+RhhWPM2eWs3scHMvF87zMQrXU3VjGToPHKtTm0mO+9j9RqIz+FTE=" + ], + "X-Amz-Request-Id": [ + "QQY4D4723ES9VWY8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "d781bc49b10ecacc", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "5udlnZvvExiunXJ2n0FleQ9IUyC8JwJPtRkyo7fkVn+BhDtxLyK7dfKX4Ro7RSy79GJGhX7xyTE=" + ], + "X-Amz-Request-Id": [ + "QQY29XRHRCWEXCHD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a7b4cde5fe13fd58", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "POyqcuK+NNPOSDnGImK5olVgT4/bv9KTiO84KkdfMnfoN6YE9pSmgyuOpWTprOfdF64MUMqJvIU=" + ], + "X-Amz-Request-Id": [ + "QQY1NM7NG69PSMHN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "7da9b12fcd570843", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%7B%7C%7D~%7F" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "YQMYR5oUQCXv8yddQu0wA+hlgwT47D7nxL3lduLaCvP9wqieKRZOHm5i4IAYlNY9EhYhwTebgwE=" + ], + "X-Amz-Request-Id": [ + "QQYA5N2EY19WG5ZX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "0b81011940196a1d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "9FQ/K8pjVExicsF+DU9Ed8Lcdiicom4bRzcg2uLDXw+rhH8eE47pg7+HWreIdNm42mu+MZvfhbY=" + ], + "X-Amz-Request-Id": [ + "QQY98RN1AQJNE8WJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "ae640dacb2399421", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "1aSegIC0g5soprOmAOy+U8e0QVS1VQ17jE8aRZ3eXE7fputGkm6SMmoKOqB1CZghh7a+gHsp2Bc=" + ], + "X-Amz-Request-Id": [ + "QQYDHXRQW2BFERPE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "71b473ba86573708", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "5wiujn6GaNs9ppGhrCUuarUU386c6Pwc8ByJiSMEKXSm2ufdS3vRXJOpVZFwBbiRzTI6Jx96TsM=" + ], + "X-Amz-Request-Id": [ + "QQYAFC63X91V5352" + ] + }, + "Body": "" + } + }, + { + "ID": "7a2ef7d47a5175f1", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "IYfs++IGCjSx2/X1FCKa7Y4EaCu+VMIJ0kjKxeqdeBhIPjWnGxxoT5sBm475W+3tpXRM0iFZSMQ=" + ], + "X-Amz-Request-Id": [ + "QQYDB640R4NB3BQ1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "db0bd9a35f63d4a0", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "7Yc5PKOsed0GQqzrGMCdWY7sr5UM7g2jtLrDoiNrYl7oQzwnQDWrFFAh8jfLG02ChxRrQ3I3Tww=" + ], + "X-Amz-Request-Id": [ + "QQYBK12MXCWAXGDA" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/backslashes.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/backslashes.replay new file mode 100644 index 000000000..039c33db1 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/backslashes.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPP0AbUH9QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "82afeb81499e5286", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "dgbwm54A6CoqY4pVciZ2oAPC82cao/gGkTCRu9I/fA/MV06mPoBECRywh3XuvKzGpOPrUhaBI5k=" + ], + "X-Amz-Request-Id": [ + "9J3FCM2RNNZE4XGG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7a99af1619342b02", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Oc+fYqw1dkzw36DvoiyWJgyjZ/d5sqq4S56tigw+JM1ZPs3tqj63lYBeiNR5q1lJQeso+19s+IU=" + ], + "X-Amz-Request-Id": [ + "9J30CC9PMYAWR15H" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "145352588a854ab3", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "QqHnpT63+LdtDuBBDKC89y53lA23f96bxpKRvCkdxp7Mjogf93P/2QKzkGMM5291ZGlJhocsD+s=" + ], + "X-Amz-Request-Id": [ + "9J3FWE2K2NCFXM1B" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "932ae56fe7ee4123", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "JYOp3j+edM2FvRJDlyuk63sP6hJwQdKQ9s20L8JYszChoo/2Q1MxJEFtlXTfnakTZHoAI4R2USU=" + ], + "X-Amz-Request-Id": [ + "9J33WDGEN1D797XB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "a6d8fe9c8d8345e5", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keysfoo%5Cbar%5Cbaz" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Wv5HSp6skqsYDU2+VfQZZ9tjRlffQlWdS2dZzHabllCvEs7Y7k21leANmlSxl2jSCqr4//EUYOA=" + ], + "X-Amz-Request-Id": [ + "9J3804T1HSA0ER69" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "22248e9e5997511e", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "DESvva3gMsmsOsg5mbi53TOWE+rHQsmDoerPmIHAVtfoUro3cpWp08YAa0lZb9Ly9djygFEjoSc=" + ], + "X-Amz-Request-Id": [ + "9J32QAMTX1DYMHHY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "7e159be05ce023af", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ObkAfTitq4EvEX7iOnn+H04qFA5cjNkVFHl3kuLjtZf2pGObBZvTmGxD4XgDRqEZdRt7S/404GM=" + ], + "X-Amz-Request-Id": [ + "9J32MR5K03WHD9ZQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1ff0411d83ea46ca", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "zdUHquddvS7JFQOzE3gLb52dZ+nFcu6Q9ox28NADciYu795vedE7lCuo6+clyWFRvmVfYguqcYo=" + ], + "X-Amz-Request-Id": [ + "9J33QK3EAQW5HRZ7" + ] + }, + "Body": "" + } + }, + { + "ID": "9d08a957b47168e2", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "PJ/e3onSVV/nOyuEFO/CGS3cE0T7yI1ttVUii9ams8dbQwYzYQWRXvQNhTOjvRBQbpggBU8HiQI=" + ], + "X-Amz-Request-Id": [ + "9J3FKFDXZM782RX8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "29695cbf547ed899", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ZCShgLf2zbBNV1tk1qsQ1aPcn7VUTohW2DlbNnsrP8DUVZRn1AzFrv3nRjQuijZkifgzf/DyWOs=" + ], + "X-Amz-Request-Id": [ + "9J334KTNC7GKYDS1" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/dotdotbackslash.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/dotdotbackslash.replay new file mode 100644 index 000000000..07c2364e8 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/dotdotbackslash.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPP0F/m6IAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "ea71d1841a9bfa79", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "XA1D29h76jBYdDnMuqnObBvTurQShWSGer2IERQlzKT12PnPOe6MS76HaiCHRg5gorJ7MD0vdfc=" + ], + "X-Amz-Request-Id": [ + "9J37QG40MMMY1VHG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b82eb0e83894f21a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "QrZvouV+hSCO/5J7wJ7jzc7iH9+2uNP4BYqljslbAOiQ3Jp0SA7wrYe9BZE9Txd5b7FaATyLdO4=" + ], + "X-Amz-Request-Id": [ + "9J3DJ46Z9G65N67H" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "da096fc3fce92fcb", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "wa1pqRmFIJKrJ9x6tKrDaq7StynSU6OGmW8PWxoz/YpaeTffIs/Zvp5Ql1Bn4nmHMQv16u5LP8A=" + ], + "X-Amz-Request-Id": [ + "9J391KV6DX76BSRM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "48143041516347a7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ZhcDHWIQNuStZr/UTjf1WskozFMKCRor89eYrFgo0dquqG645Tu4eKSNesTWoLZHbxlrgDXW4uY=" + ], + "X-Amz-Request-Id": [ + "9J32A0RQVPE3MNWT" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "b328793366040f85", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "b6e5Oke91PrUBxPRiU321aZyjLzV17di3ENBe2Wzcd4pY06uEGSzeon+GdPhiWCbmwjyTsMSMLg=" + ], + "X-Amz-Request-Id": [ + "9J33QTCSKRXCGEYE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "e49a6d4dfbbb0740", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "1Kn1pMsLUUItcAydjuD3rY+furgLKcAMkQ7ZpAkQMxJs1jVld24faTbHiYDfyk6m40OWuM+hWYY=" + ], + "X-Amz-Request-Id": [ + "9J3FGDXZYGQ6RZCE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "d01399ffa837f6ed", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "uRjs0ih3V0bAAP9gfkLAPkNBUSPWNCPMZ5FdP+0KoAS3vAlmTWikbtUnWz4FlG3KLmOhgcgvHsk=" + ], + "X-Amz-Request-Id": [ + "9J392PNN3SMT66E3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "61f01cfe5bba5d1c", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Syuwo+mmaHdahQN6WGhWj2c1bZv0jTORbWesIGP6wc9MoldPCgAk+RplduJrGSHHMg+dJM1aIMM=" + ], + "X-Amz-Request-Id": [ + "9J335GY3D8073S5N" + ] + }, + "Body": "" + } + }, + { + "ID": "468220c62badc188", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "2wAUEpuc3qOV59omhtsDWI86+NeqQkmogtVwNHAUm4PPmLRZjVMwwgzolcdVmQH7FV3L7Ks+BRA=" + ], + "X-Amz-Request-Id": [ + "9J35YXFB3NJJ2A9A" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "051e884e0f27b830", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rhH5lmlbACNnOEtHvNwO5xFWETOtpPq3gnEuqhlnPzMEiaR4KV4svEQbDs6UHEpq+1ONbBYmg8Y=" + ], + "X-Amz-Request-Id": [ + "9J354TG3SZMWZEDT" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/dotdotslash.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/dotdotslash.replay new file mode 100644 index 000000000..b15629991 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/dotdotslash.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPPzJ5ybXwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "43fc61e486167b9c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "zPLjw4wXkVDO71gA1VOAwrpXWxH3qkYt0xfq2rhaIscYe8usvjECrABZulvny1RXzw0nh+WG3Ns=" + ], + "X-Amz-Request-Id": [ + "QQY15DG2XHV1VZ15" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "50dd407df89bb974", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "WnpxtoK5KppbEOjtA/PZw794N3VpIKHaEsYOxR4rtTasiWEudri7RE6C+O8Q7AJiUh9xSyj4gvc=" + ], + "X-Amz-Request-Id": [ + "QQY01TG17Q1R23MK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "ef78a9511a82f23f", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "M1drPioWHDAxY73oPAaEg2ni3ZucsU6XfbXthw2Eg6exsOQlg1IOexozKtKNY5SlSxBbLCu6r+Q=" + ], + "X-Amz-Request-Id": [ + "QQY5D66GN5XYBDEM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "38b84b825c1c44f4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rSotOasL1vnbHGfP4p2hXeQbAHmKfJ17VBa3KoL/lpMpIs+kozPtkQz/xhrFQj+Gr8ApMUzxEnI=" + ], + "X-Amz-Request-Id": [ + "QQYFBSYX0DBVGZYK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "3d4cb983c2d3bf76", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "HQIhC9yVv0YoomWPhhpw0QsxD7raXycbJ4LfwTaW0ldSQxotyszUZ92lM2upAV2tzFFmnLHB1Zw=" + ], + "X-Amz-Request-Id": [ + "QQY9A7VAB4QRQD76" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "21163a92c4d259b3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "KjxBG8fNFD07BscE5fNi/SuLLoVg+v7OaMx0vG+GGTPXPnPONH5HzcR+q2wnjzZej6QB8bQYftI=" + ], + "X-Amz-Request-Id": [ + "QQYEJP6NMZ1KVT9N" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6fb02f535044f9bf", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "QdGWldh01xWab6nP8N4t+E6VXELu233TRBHytYLyAlZwAEJ+2C8+iGKM7G5RC08l5kkUmw6sZs8=" + ], + "X-Amz-Request-Id": [ + "QQY6PV5ASNKBA44V" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "18a9a6581607b86a", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "cvDdAcNfx2HDLFSCBJATgINtiNrc0t7RvrNOdLLlLEayDkMsElKss6AZwXL2ocLCaOLqc1DAydA=" + ], + "X-Amz-Request-Id": [ + "QQY1YV0MQJRJX4CH" + ] + }, + "Body": "" + } + }, + { + "ID": "d5be7e544cdf19ab", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Gsz1u2Un+HRxr+HlAffdueZ0zYiD962DgufwyqxzQJXkDvYk2dV7Byh51zxhkCDr4mCxTvxVkR4=" + ], + "X-Amz-Request-Id": [ + "QQY18N7CWPFRYAMN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7be5f72e533bf2fc", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:08 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "g6XJe1H9ap/NPibnNomn0iayEpHlDV3oyXYYYoMkQwo57x6iWaVyL+7TLjgW4c/qRYTGy8+VsP0=" + ], + "X-Amz-Request-Id": [ + "9J39CFPEXTYFF4YS" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/fwdslashes.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/fwdslashes.replay new file mode 100644 index 000000000..c4d5af3b3 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/fwdslashes.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPP2CqrcIgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "e0f7f8b73d51b3e5", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "46cQTcZDDxmY6vprLCZ142VdZXpqjB6XF7tE/qnG8F6GGzg36TXZMOQ+D0tunSfsTpqy9N7y0WaBKuleI/U2HQ==" + ], + "X-Amz-Request-Id": [ + "NQX26GRQ3KKYBBWE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "d8d7279dd95f30b1", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "X3Hku9c/qP3ENUuIEq1+/Gr4xIvY27YArRg4U0/NA9cxoKqUE1p/YD3fGUt4GMiUUfPgzv5nUeAViFXjKvqVvw==" + ], + "X-Amz-Request-Id": [ + "NQXFYAEXE8PARC9D" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "706909024341d905", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rIccJVrMQga6eybrK0uq04b8LbTSE8zCFYmOtK7CC0ahX+twTxSTcpNMxY7aKLiH5xDFFSL/lu4kqqj+5N07nA==" + ], + "X-Amz-Request-Id": [ + "NQXCWZ4MM8J1JF9N" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "79aa8b268f30bfa3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "qCIwEZnDX5fOUy4uzbuyYmiAGdMsFsrMKHrOhkjiQzi3WhkfjNz1ThqAWdhgZU1Jo0dXu3WZS9BFkfqE8pmFsw==" + ], + "X-Amz-Request-Id": [ + "NQX75N0FZM2PJ72M" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "0c471ba5ed921989", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keysfoo%2Fbar%2Fbaz" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ekHzsrOhUq7ajbVn0k7npCwOfo8WMJVGc6VtFx0kJqim0ENFcLkXmbyskZ/TKtHF3+gSxUua/r36ohrtpF26RQ==" + ], + "X-Amz-Request-Id": [ + "NQX19Y0C2NKX6138" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjExLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "51d38238bb43ac90", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "eT3vu1mLeslsrD3jKv22zFT4nfZHOc91tDbcF+dyMb34IjgZk1PlCFgAcFJkh/HcuHSxFtrfgyrvyfaaEp/EPw==" + ], + "X-Amz-Request-Id": [ + "NQX06BB0EXHMJ363" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "5f729508a09c83c1", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "1fqpUphokTlJFqxXLqTYXj/OMTFjrvENT5T6NCqySOaXfm0VjTZh8dRF9uI4n5OJECaZGgPugekLVJk127d2+w==" + ], + "X-Amz-Request-Id": [ + "NQXFKXW83VCHRAM6" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1441468b54d1ea2d", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "fdKZlVGrVy5eHgKvYYjGSxlijGuBqvLAQnAwqP7aM4MeNZXG0odV29BQq3cP1cE2JaSrPPfOkqGFCpDVtIVOWg==" + ], + "X-Amz-Request-Id": [ + "NQXDZY88VJCJZGH5" + ] + }, + "Body": "" + } + }, + { + "ID": "1246823ddac8ee60", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "QLyt/OVrF5ndKFTR791RwuYx679o29LSJGUCgQNAU1PNdkm9Z56FYceMJ7mQpOlEoHE58QiUOS9x1+ar3mLaYQ==" + ], + "X-Amz-Request-Id": [ + "NQXDF4MVB5AJN79V" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "712446cd9f2c8cac", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "m5zhnO/F1b+uE1oqa9y5llQUt7GluzSBknFrmA8kuj2VCLLwTDuSj9SdaS7Zx6CzgsmUdaFf6BC7chGfIftXTQ==" + ], + "X-Amz-Request-Id": [ + "NQX6FXVSGMBXVY89" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/non-UTF8_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/non-UTF8_fails.replay new file mode 100644 index 000000000..c2f98150d --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/non-UTF8_fails.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPPwKOJ6dwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/quote.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/quote.replay new file mode 100644 index 000000000..28ed998df --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/quote.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPPyDN9vAQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "4aaee89324311cf3", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "dnQPYb0iLpxgxW+8B9IxO5TijanE7YpY6CQLChatn4UtpkA/CADcFA+FvDGlaDNClGPiDzdVpB4=" + ], + "X-Amz-Request-Id": [ + "3K0Z324DKT1YEDK5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "bc39aee4d91a653f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Js0fko4MRcp6C+qpiy1/9IAU7D+v3rNoagwoKJwJ0bp5lQwhUUWFRI51CQc/oYuNj5q2Qrze558=" + ], + "X-Amz-Request-Id": [ + "3K0QHGMD0ZWSN35C" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "62bf59b364794414", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "K+gyS+55V9oqYbyy1rKVQTYAQwPZomGQ0CWdmORY1DRiIXPE2fsqGEaNcCXI+WyomOj7z4cJbOo=" + ], + "X-Amz-Request-Id": [ + "3K0PQD0N7W5V0SDD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "441ecd751ad42593", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "iUFdPzLQhFSd/edpflLX+7atM0LOmfHk5rXl9tK+hPhYY0rVQXEjWbUa2WB1mZ9tXVDo4olZnMc=" + ], + "X-Amz-Request-Id": [ + "3K0SGQFRR8933WK5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "8a522fcf9a3214ea", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keysfoo%22bar%22baz" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "gWks/azzNFh2pdn9fBBgzhIc84vhTTCG+HYfHw3g5WAThoHxkYDwcSM/YDX/zr18Vy5Ggx6Welk=" + ], + "X-Amz-Request-Id": [ + "3K0VYMSRCYSS7DQ5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "cc97535e60b2ca78", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "cp6jPNbkQoNe5Dxj4e8BRw7KoxsX41gTyQB1iAq3vCe5nic+pqRAp3gq6a0VG47KC1ln83Dlkdg=" + ], + "X-Amz-Request-Id": [ + "3K0KSX3Z1PVQZ1A0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "54038036d26a9ab9", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "qCAVWkQbv5B151SchXcLT5TAXKwPf2I1fOl4kPAtQWZXsKYiypNeuOiCZTAedSYkw12vSQy08mE=" + ], + "X-Amz-Request-Id": [ + "3K0RWB6RV7JQGEZ7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "95405cb21be92479", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "4+11zbL3CiouuEFHoi0tcKzRkFUbgXGvsRpuODMzMKIclYs+b6p5KQqc4O4hfGOTe4FuS0mbQKI=" + ], + "X-Amz-Request-Id": [ + "3K0PWZ5JX99NASP5" + ] + }, + "Body": "" + } + }, + { + "ID": "dd2c85e93d8c5008", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "zxohMQVkARZRTDxc3XbzETD97ORuePbPxBT+jg/WKABDLGV861DjHw8HOFpTNMx0/f9uFtrbZtg=" + ], + "X-Amz-Request-Id": [ + "3K0V1WVX49TAYNBP" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "24d4055be85b5ff0", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Bi+hiO34V7B1FSSKfHkeyEnIHYpIQLHnNa6oDMEk2VFyBqUPr+stt8UHYTZ5WUTxz+Dn6wn8eeM=" + ], + "X-Amz-Request-Id": [ + "3K0MR1XASSYVQDDF" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/repeatedbackslashes.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/repeatedbackslashes.replay new file mode 100644 index 000000000..f60c25b2e --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/repeatedbackslashes.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPPxMeywegAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "0b0b24a809f6deb8", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "f1JdTof8iR5XXCo5CAvN6anPnJxTvq5zA1gZKcMocyeWVdOXXdV2mzFKmY/dKpnm5WrB8h/8CWA=" + ], + "X-Amz-Request-Id": [ + "85TDRBZ44V1DQH50" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ca34e5f7cfb080b4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "D5a+8ZPvhpYuLrnm2wmXvROTHGgHohUs+lN9hR0GscR2bpDJRQyEzzXl74RU5A2WExX2RVSpa2g=" + ], + "X-Amz-Request-Id": [ + "85T4PSKNGFVB56N3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "51dc3d91750dba56", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "d+Y+FyiUeLHAEZAtCTMqSmTJC4BxXdIW7zN82252jc4sJASkGgcG1IsV16liomPPb4bNW2mZ1G0=" + ], + "X-Amz-Request-Id": [ + "85T0NW2DC9WJBARQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "9ae8706bb1e591d6", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "C9flfxvcPEpQS4buNbEp2/IBU4VV+mBxp6FeRvUGNAOLNndkL53k6HSyaKc9teTOM506Zce0eyA=" + ], + "X-Amz-Request-Id": [ + "3K0SDB1AWYD9K6CD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "7efc9c4829433bc8", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ftDbUbhXPumfB5pzEWPhAVptPwTeGe6t3l6TzqcWbB8NgE6BK7zfhdfWRGMJwBTNI6KHGRwzMwE=" + ], + "X-Amz-Request-Id": [ + "3K0QG737AXB4AZ5T" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "42b084745b07e77a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "uSJAJz7PBd7zOituzTUmkKi9av6fKe3efIH2/JkyStmGCZFO3ZawWL2kVmExjCLCeYJ8QvOdKaA=" + ], + "X-Amz-Request-Id": [ + "3K0GRH9FCMHSX7WJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "46414372ff2cdb35", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "iUw86oGpY8LP72Kc8TFh3XToMn/WbUWfwXe8rw1FuUZLmc2pCKB7sw6pNZBU1YJZ8FBHschEUOc=" + ], + "X-Amz-Request-Id": [ + "3K0VZWCQHS937VK3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "f68ecd90b5dfcd7b", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "kKMDLvEWHHgY7/PuoadBe+42mUGm1bciJbaNbO/jbbIPppNqSjxzleqveKVF10wOtNcXQ4nBFlc=" + ], + "X-Amz-Request-Id": [ + "3K0YYP37KBE4V9AG" + ] + }, + "Body": "" + } + }, + { + "ID": "19e59772bb786dd5", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "cTuhZ9hXmyy+Pc4jgDubZp/PWStWruq0wSZFYG83qyU5pTadiIlaPsbN+sHsu/JZeB19UiCQuQ4=" + ], + "X-Amz-Request-Id": [ + "3K0VW3EREFR5YSAT" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "de1b4663141eebe8", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "hEGLmvxjrm6RPOONAT8y9dfRFHhIs/1GIQcnKiEypatyAI6QPUboOd1Tl2N0vyrFmap/PQ8fIT4=" + ], + "X-Amz-Request-Id": [ + "3K0X6ENPE98070A4" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/repeatedfwdslashes.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/repeatedfwdslashes.replay new file mode 100644 index 000000000..a14ddd954 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/repeatedfwdslashes.replay @@ -0,0 +1,458 @@ +{ + "Initial": "AQAAAA7ffPPxJFZ9iwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "a1399303dd1d03e0", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "UFRyA0ZWndT5ro6MJaBKbPeDWbeNPra8CUmg8mJkTnJdc4KPX3uGtgB7oCQagVJjaAZWI0gWVc0=" + ], + "X-Amz-Request-Id": [ + "85TFNEA282TVKCJY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "982b1524f5f72c8d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "f7jA8C6cE47ax3/Ei/qzqvITRRxQ4HjIWKhQRdz0pcfyV76x41HkpZj2guPy1aeyMR0OKNcL1Uk=" + ], + "X-Amz-Request-Id": [ + "85T1M8PJJJDAGR7H" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "9edb252188f91e3c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rwcTYjFh6MRW8dFXLA/y58taWE1AqybVRjlzJsIjrulEl+d7wVlGUkhIWeSnoDkGyVBOotWM7Ns=" + ], + "X-Amz-Request-Id": [ + "85TA6NVXH4V9RGD6" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "96238ea7e0db93bb", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9CSvB9pA8Gd/b4iwrjANwS6Bqkurp1ZXE082sXMEY3WGkbs6AlmsL0/bOqYSEuQIRCR2WY00e8o=" + ], + "X-Amz-Request-Id": [ + "85T9F8V1W04ZQF03" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "55078aacf92de167", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "IHfpwGNOvSjawq2CX5oRwz0x9KXtXl0ggpa7g3Mvx6sdq8IVHd4X5kehplHVGLnl3v1+g+wX6E8=" + ], + "X-Amz-Request-Id": [ + "85T8HQJ14934V0K6" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7751512ae6ee0ff7", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:06 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "4OyCYl6tFHicSOGZrPBmnyMuYK0OWwLU7B5zdukAxF8yW19X00e6P9IxSLPSeOvUZ1WWO4rl/ks=" + ], + "X-Amz-Request-Id": [ + "85T2A8KDXBFGDVD4" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/spaces.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/spaces.replay new file mode 100644 index 000000000..09e12148e --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/spaces.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPPyIt7muAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "99cd9714ffcf83ea", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "I/fyaMhQ1z1nqRj9B2RRWW0ZPF/zwlLu5eNpQ773GYYWwfjHjMWF+Lrb6SCTXNjyYMWDteNDKdw=" + ], + "X-Amz-Request-Id": [ + "3K0JEEWQH4RPQZ73" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1d223982ef81de2f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "qnRmCeGkVDjBQJ6EcGVGwVpR4T24cwvDfpe3ODp4ImBiY8lr2UGmzbzTZe/Z0ZSMbmX7IoHzFNY=" + ], + "X-Amz-Request-Id": [ + "3K0W4SMX1Y25J6W0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "998d12fed313188a", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "geAXKEDfVPeK/nzNASWinJSfopAsOreSMqTq0ycJQz+wEUhOFIAaexmlSZDbx/P17FnX13o3XsY=" + ], + "X-Amz-Request-Id": [ + "3K0SZH95ECZTZR63" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6bd5f8f76ee1f4a5", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "zj3J9uUzUIbQX17sq0lTwLUDXmIhkfATT4I954YGu0+kuaTsxXmCyBa1N3+6wk62/9oTbmmx4y0=" + ], + "X-Amz-Request-Id": [ + "3K0VNZFEF8XY7SQS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "d26340d1a3e761e5", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keysfoo+bar+baz" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Euhq3JZipspUjkSb6kh5bwutTKqXpiKoZ+HJtPXXGfI2vu9EsuxznlrDFUXMXcG3WshEr+HBLQM=" + ], + "X-Amz-Request-Id": [ + "3K0Y6YMT4G04M523" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "a34e61cf68cd93c5", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "5m9QwO88OOSrFZ0tz8ot/bNt/TfK1a14Nxxyoaeylh+fgEckzOuCcB++pVcTihlb1tYdYWzXIoM=" + ], + "X-Amz-Request-Id": [ + "3K0RKB0AJRBRVY6Q" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "ae2c365ca2a7f935", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "PtdcZJuErZv1GBn+J3VPVYAephWRXDZoMF8lWVQZi+g3O4MW0fDaGRvfYSCWS3au0GgJmpSaSOA=" + ], + "X-Amz-Request-Id": [ + "3K0M1HNMC72P5HAM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "47bff2261f560b63", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "yhX+UkoImXjxpKx6pe/RjkqEkO3KwL/QyyfB19YDILEax7DKiB8yC3W5AWLBcCI+ceIEVEhWDfQ=" + ], + "X-Amz-Request-Id": [ + "3K0Y39C9J8NJFXPJ" + ] + }, + "Body": "" + } + }, + { + "ID": "85228bed95961388", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "atGgb0iDLXRxr3BlgSsLHkxCBZRO1Rp25aJrWl71L42gNkLDhAXgNdp+WqGvj3LB1BloC9PqZi4=" + ], + "X-Amz-Request-Id": [ + "3K0YM41WYE1KBJN2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "8f61b0f2bc62f998", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:07 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "zewRR7o67TQj+klvtj+NVj/yomhxcjwazr77SGizK1EgJvpYghaCIUG7oAl7MJViU80FPOG06NA=" + ], + "X-Amz-Request-Id": [ + "3K0Z6W63576C2WWJ" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/startwithdigit.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/startwithdigit.replay new file mode 100644 index 000000000..e651023d7 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/startwithdigit.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPP0LSoIQgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "9e34a06bb3130548", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "p4Ue9X9eiPuSi4YRTeNv542Iy7NdE5wqQDoAfSz6O4MRHSOxI+w9jDJZ7srGgahk5imE8Zjaeno=" + ], + "X-Amz-Request-Id": [ + "9J3FC1K28NS25KGQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "39458733766b882b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "IDH6GqsDpc6inHG6kAHXW6QyqxWIsQXz6M8XrB+sHWdbsthroiJ2oKgNGAsXmthJWVx+oebhufw=" + ], + "X-Amz-Request-Id": [ + "9J3BR19P9ESNX1AE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "1f8606bc785fd7a3", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "h53DlgLZS/cQfmjbxIQBrlIwxOTFv9gm6+s7k2BHhl7RYVkQ5FTaKs8g7960JGLO6Rrs73EZU9s=" + ], + "X-Amz-Request-Id": [ + "9J3F6W8WQAB8NKHE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "cf633f79d3dc5c7a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "e3jYfKnj2WGs7dpTBK5SFFsIW0R2YaZ8/JfBlFcxEYF2F0M/KjKKLhtqHvAeemonisCLHCRAOXs=" + ], + "X-Amz-Request-Id": [ + "9J38VNPHD41BX3G2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "a87f4092ca3839c8", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys12345" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "k3RSgBa6816P9Ckbuu0mcXETXIjT7CQkwYSditu2pVVy8V1+TxuxYxYDiZnmr8pLkr1mNruw+kY=" + ], + "X-Amz-Request-Id": [ + "9J3FJQNDQT9V9GY4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "f4491c9cc985c1c2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "apOZ867/OKP7hkf2IlxkTxBZmzQe+tHmSVIyAgr1eFILORx7pM6hVMitQp7w6ZjxlXicrB8TuoQ=" + ], + "X-Amz-Request-Id": [ + "9J3BWD06VHST54PV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "b0473e4bcbe2a53b", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "2zhjEuRX3xcHKvyJXm8w2vuGl7LBxw4tphHEr9ry2vl8z5enHwCLdK9zoFra5ODoZph1494DC/I=" + ], + "X-Amz-Request-Id": [ + "9J33HJZNM6ER6C5C" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "40e446ec5203fd80", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "aM3bI0d2A5XnYn0yctru5QnKBKyMqvvEP1b+hZyBZJiZ0ne6Wd68iD3qOWxRcofOgo8Wb5VCUvU=" + ], + "X-Amz-Request-Id": [ + "5S0TCNGT2ZD0EZVQ" + ] + }, + "Body": "" + } + }, + { + "ID": "abb4f7008a3f2109", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:09 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "UJf/VKxARRlWyAQQSBncSvTJk3SA6pZwHUdWqDNljsrZQ6j6BaTV1Z8HTamjXcgc8UJvlekcBj4=" + ], + "X-Amz-Request-Id": [ + "5S0Z73HBN2G686S8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "cfa314549fe5019e", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "p+0wDBsQQVhhB+nAYCsuig8bo1WoLTY9fSL8Fom9kLDP+RG5AsdUjmAqt7McoRDrjMiYlEKjmkA=" + ], + "X-Amz-Request-Id": [ + "5S0W7WP8YD1CVPZN" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/unicode.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/unicode.replay new file mode 100644 index 000000000..758d0a449 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestKeys/unicode.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPP1BkZPzgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "077aa7f8ec50024a", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "tY806Tzg7HJKgzkQ/SQxvSJRZ37Zj+YXlEeJaCXdTK0ClMNM/JPF5sGSGyWSG9kb40SUq+WJSug=" + ], + "X-Amz-Request-Id": [ + "5S0X3N5XAJWAKEC1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ff260a47a451d6ec", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "SG/votILQVc7JHFZuWYXgTWz665D0XJ0McdAKz0bB5bAoKtvoh6Qbt4yMfaMFM2NAnuQu5BVXDs=" + ], + "X-Amz-Request-Id": [ + "5S0XQ8WEEKKF240T" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "d64953540cd2ef08", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Rg4PTpnC2v8/SIZ8lJFV2LyyoEiSBcYy8MUg1G/gqtQyhdodRRRhRyJ0eEjzao7eAqXew2/Htao=" + ], + "X-Amz-Request-Id": [ + "5S0JQC2XZJKBP9C4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "228b484d6849a890", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9/4ia4hXX8+kb9DeZAnDp5ecu74NMSxjCf4iMpebUEQOtd0Z5AtTCkcmnsFp9jGn6/DBKWnMiFA=" + ], + "X-Amz-Request-Id": [ + "5S0NG8E0G49V5PWD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "d219552a7c0071c1", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9zPqSHtjVJVFEZqdXLAl/Vbg5I6ZaB+AdbHSmdtfmdNIki2krR8q3NWs7V7V1gGs7GW9AfSCvQY=" + ], + "X-Amz-Request-Id": [ + "5S0ZPY2RYEQT0MFG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjEwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "c4bf44675ade847b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "mARCv+Lj7G5khId8forPqOcbKGbplN2+nCNgGDd+ysh73S2nX6oVL469pKzSna0pVBQe/V/zznw=" + ], + "X-Amz-Request-Id": [ + "5S0SHA0ZB53D8BWK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "deee0e6be0331084", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "GGD4gJ3cQXrGq6AakyMvFybghjHiFGzq+3A5Ja/aHdVNLp9k87zGyD83OTGnwL0d6rmnwTsQwFk=" + ], + "X-Amz-Request-Id": [ + "5S0KERPNFRMHXD53" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7cc15c7d77610a0b", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "WwQJrDN2P42tTJMU/AHYWRRW1LTBU8buvNG48fnpfo+oxHXWWrm5kz/IK9mynidjUGYSrPQSiEQ=" + ], + "X-Amz-Request-Id": [ + "5S0SVNMDN5F1102N" + ] + }, + "Body": "" + } + }, + { + "ID": "4392af6357b431f7", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "5zPT1Mx7YOPHpDjsTcbXt//CLSLlzjnC2llKvd5w7zvXg5mfAyz6G+IR6mo8YzcF8jsAVjNzmNA=" + ], + "X-Amz-Request-Id": [ + "5S0JYQMHR1EW3N8D" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6c41dccf7c1d93a0", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:10 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "X92uxF32c7ThMrbRc3CIrh8MDVXnrhsdjiyCuasnTlNyeNDtZio4yNvpaXViSmpjA2h4X8WquSk=" + ], + "X-Amz-Request-Id": [ + "5S0MS4PQDY71HA5A" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestList/PaginationConsistencyAfterDelete.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/PaginationConsistencyAfterDelete.replay new file mode 100644 index 000000000..a63cab812 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/PaginationConsistencyAfterDelete.replay @@ -0,0 +1,425 @@ +{ + "Initial": "AQAAAA7ffPPlA5LsbAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "2e55281f65146aca", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "zvauE/F3t669i6Za4nA6E8scsX4+jz7W6FDDpJiZ/t255k9GU113SwNJFFOeMOLoyaF6Y09qdesUoh7bIQGmMxE4zRkHfqCWMGifbnZWsLM=" + ], + "X-Amz-Request-Id": [ + "HXAQJ4BBD97YDDN1" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxLZXlDb3VudD4zPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "bcc81e38f734cf32", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=2\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "m5tdiVqxrwx7We6ZVbRp4zl0xcypj2Y8K3FDklQ4Y0pWyN4r6qMcYy9hVDNg32d55veyFg+bzxZSRXUb/kEaftQQn/L0wIYLh4px/WwqT3U=" + ], + "X-Amz-Request-Id": [ + "HXAX7X4ZXZ3YCHDD" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxOZXh0Q29udGludWF0aW9uVG9rZW4+MWZncFZNZmlzK2pORTFwcFg0L3p1eTl5c3Z3VE83WWhyRTgxMnpUWkd0MDB2elV4Q054bDdDekYrT0RuKzNuYUY8L05leHRDb250aW51YXRpb25Ub2tlbj48S2V5Q291bnQ+MjwvS2V5Q291bnQ+PE1heEtleXM+MjwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "727f4463a58ea5a1", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-1", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Sun, 30 Mar 2025 17:01:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "/gQX2NVcbIyvTexsvzSH+6JnPOaIPnFS095IkqZVUVv9+RMrxIrwhvmPXSQFIul6duOnlv2XCFmC79yjlf4D7e46p0uKDugljD2QmcuwTi0=" + ], + "X-Amz-Request-Id": [ + "HXAVASYQK7W7R2S4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b4518d478f1d9d7e", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-1?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "oKY46YG9ReLnfFM5XuobEAe7jCN9emopUMSTtk8LOTy1b/vBGdMnFG8Gqm1cX8D7pVBOGfAfnydgTzcLiLP8RN8Y/2jYAmyEctsH8ZeiNxs=" + ], + "X-Amz-Request-Id": [ + "HXAVA5HMZFYYAEB8" + ] + }, + "Body": "" + } + }, + { + "ID": "0cd4a82ad206b9a3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1fgpVMfis%2BjNE1ppX4%2Fzuy9ysvwTO7YhrE812zTZGt00vzUxCNxl7CzF%2BODn%2B3naF\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "O7wTSEWcyEiP6auuIp+nk2mAHH0LfcgOE+tSZqFCm/MUWPVnGFcQncDeR7XZFfpjGlli+Gv2owxDoNpGafIqWLMajGz3hQkkHp+0ePEw0s4=" + ], + "X-Amz-Request-Id": [ + "HXAGCYDJ4RYSPTMN" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxDb250aW51YXRpb25Ub2tlbj4xZmdwVk1maXMrak5FMXBwWDQvenV5OXlzdndUTzdZaHJFODEyelRaR3QwMHZ6VXhDTnhsN0N6RitPRG4rM25hRjwvQ29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjE8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "a176be2d333fe3c6", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-1?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "KKmkCso2YmMvvEQacq3ojKEJAXSy5ilATfrTKhqAluSq/imVfzpKACZGUFviMJwx7ksD4Up1pjS7t8Yxqd0atnQ0KdMITUrQaT+F7qf9kmw=" + ], + "X-Amz-Request-Id": [ + "HXAWJECQQ7AW18FA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestList/PaginationConsistencyAfterInsert.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/PaginationConsistencyAfterInsert.replay new file mode 100644 index 000000000..481a60b56 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/PaginationConsistencyAfterInsert.replay @@ -0,0 +1,425 @@ +{ + "Initial": "AQAAAA7ffPPkMMIC/QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "21bcb14cff8a70e7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "dl3JqjV+o4I5KIsNHcXefN+F6Ay/qLCMHof/rzlcxHuy1av5cNEM1sakIfOw0FJz0FBYaM24Emo=" + ], + "X-Amz-Request-Id": [ + "GZ5BKCC0R26QYQQZ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxLZXlDb3VudD4zPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "12d6b83912fe92ea", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=2\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "Cj+0kUOQ87GLA5JbttNfmEyzD6j+S8uhwffBTt9c3XFbm1LECXkygOFfto/A7eR/h0IZPrjviEg=" + ], + "X-Amz-Request-Id": [ + "GZ5ECR6MVPHBPV3M" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxOZXh0Q29udGludWF0aW9uVG9rZW4+MWNZOUJLYmMxcTdDSG1GS3lFcUZhbGpRTkdicm5BTE56cC9abmR3cndHQXl3VGpESEZGenV3Z09xbjRTb1d2QzI8L05leHRDb250aW51YXRpb25Ub2tlbj48S2V5Q291bnQ+MjwvS2V5Q291bnQ+PE1heEtleXM+MjwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "282bf9e0555ea8bc", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-0a?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "C61sm6KNutIJeTimGsW1xnV13HUer4NbKcTUK7t6lgx4vYfgpFpX0hogpQksw0ayGm/wxlTu0dI=" + ], + "X-Amz-Request-Id": [ + "GZ5D0DP80WSZ9AC1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0d2cf8387b4418c8", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1cY9BKbc1q7CHmFKyEqFaljQNGbrnALNzp%2FZndwrwGAywTjDHFFzuwgOqn4SoWvC2\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "i90N4z9s7rRfZYzAQymR5/XbBBlfTPwGmAVgPfKUTSOUAvsp9MWkz80suuGXd66cR6eWlJk050c=" + ], + "X-Amz-Request-Id": [ + "GZ527XA7HYKM3B8C" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxDb250aW51YXRpb25Ub2tlbj4xY1k5QktiYzFxN0NIbUZLeUVxRmFsalFOR2JybkFMTnpwL1puZHdyd0dBeXdUakRIRkZ6dXdnT3FuNFNvV3ZDMjwvQ29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjE8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "d372ae8e9ada7d1d", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-0a", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "zhpGjGfAzC/to9HBBnjDkixSvTFusNX9gc8An6Vv0jhIAxaRRtRryAjKZLSuzx6EmGiXAbRgO6I=" + ], + "X-Amz-Request-Id": [ + "HXAW8Z8C28C3H7FS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "e07a7ee1bd6d4e51", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-0a?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+ifTLf0Ini8uTW9GohQk+fSjlP8F+M9t5ngkdKYdeXCMmzJ+OylyaM6rgEHIwq0DpaQHnbaRexk=" + ], + "X-Amz-Request-Id": [ + "HXAM7DXEEDZC3WSC" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestList/by_1.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/by_1.replay new file mode 100644 index 000000000..bcffc422c --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/by_1.replay @@ -0,0 +1,279 @@ +{ + "Initial": "AQAAAA7ffPPkFwJ9OQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "326251f11c674f1c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "371d9R0+NnY8qH27MFiXQBQ/u8dmPUts+dZuHhgJsjBESunxzl5U21nqU+dz3HrPlW3hXRiQYMI=" + ], + "X-Amz-Request-Id": [ + "GZ5DBZWSCQBTH0DC" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxLZXlDb3VudD4zPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "71a423f02d3f47ce", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "qIA+gDenA05mUn36UJug/wpPA6aWU101RVFUxXAYNistgtPsnuJoFtx3gSPn651m2R7s+H0NFv0=" + ], + "X-Amz-Request-Id": [ + "GZ5DZFC7XP0G446T" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxOZXh0Q29udGludWF0aW9uVG9rZW4+MTNYOXJRZlVQZExTVmRjUitVOVgxaWV4V3lseHdXMDF3T3ZqZzk0eStHZnFyTmIxdGxRM3kzakxLVEh4ZS9PazU8L05leHRDb250aW51YXRpb25Ub2tlbj48S2V5Q291bnQ+MTwvS2V5Q291bnQ+PE1heEtleXM+MTwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "6fc433291bbbb195", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=13X9rQfUPdLSVdcR%2BU9X1iexWylxwW01wOvjg94y%2BGfqrNb1tlQ3y3jLKTHxe%2FOk5\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "AULxjtpIjDE2AQv0BaA6aO4Ka8EKw1weH6XuF1IeHbMhRt8LpScwPJF0F7ojd8VC3gvbjQFApoU=" + ], + "X-Amz-Request-Id": [ + "GZ59EQZ28PZDV54G" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxDb250aW51YXRpb25Ub2tlbj4xM1g5clFmVVBkTFNWZGNSK1U5WDFpZXhXeWx4d1cwMXdPdmpnOTR5K0dmcXJOYjF0bFEzeTNqTEtUSHhlL09rNTwvQ29udGludWF0aW9uVG9rZW4+PE5leHRDb250aW51YXRpb25Ub2tlbj4xNW4rT1gyeHQvS0w5NnA2SHBEaXZLdmJyNVV6TGx6TWhXQWpDZW5BNU5XSkV3T0tzN3hiZ3grbnFBdUl1SlRjUTwvTmV4dENvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xPC9NYXhLZXlzPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTE8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzBUMTc6MDE6MTQuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "7348db8bc031aec0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=15n%2BOX2xt%2FKL96p6HpDivKvbr5UzLlzMhWAjCenA5NWJEwOKs7xbgx%2BnqAuIuJTcQ\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "kO+/uq/WUUrN5dx2FlB00FB0xZn1r5oPj6AWxb16JfbSnZkpaQRShofKyUzQilc8RQBiLHoQidY=" + ], + "X-Amz-Request-Id": [ + "GZ55RZD5WCB0H9ZS" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxDb250aW51YXRpb25Ub2tlbj4xNW4rT1gyeHQvS0w5NnA2SHBEaXZLdmJyNVV6TGx6TWhXQWpDZW5BNU5XSkV3T0tzN3hiZ3grbnFBdUl1SlRjUTwvQ29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjE8L0tleUNvdW50PjxNYXhLZXlzPjE8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestList/by_2.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/by_2.replay new file mode 100644 index 000000000..dbb418a20 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/by_2.replay @@ -0,0 +1,221 @@ +{ + "Initial": "AQAAAA7ffPPkIWs6/QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "1df229c65ec3f9ff", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "MEN0ngwoWhcC5s2s0YBjwHhuSQkTTiqUdTlN9w5kqcAbVYXke4ZShsaNRi3i+jBv5UnGLu+wxvk=" + ], + "X-Amz-Request-Id": [ + "GZ53BK8RDQ91QBBN" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxLZXlDb3VudD4zPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "c5a1f3cd1ebd28bb", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=2\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "pnlgWJrvPAZogLqGgOhzffs50pCkXr9bDR6g3wHmQZul8Xbt/CNSWzfFt6k2Jj1tlA93CvJ3Idc=" + ], + "X-Amz-Request-Id": [ + "GZ5C9KKHFSQAN6YT" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxOZXh0Q29udGludWF0aW9uVG9rZW4+MTJaTFE1dnRwaVFEVS9nS1h2YVhRV2Y3T2ZnQ3NNMXpxbVlsSXRoUzc1RXlxSElKTy9xSmpxMmc2Z2VxelNjM2k8L05leHRDb250aW51YXRpb25Ub2tlbj48S2V5Q291bnQ+MjwvS2V5Q291bnQ+PE1heEtleXM+MjwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "3dba1bdd5adcdce3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=12ZLQ5vtpiQDU%2FgKXvaXQWf7OfgCsM1zqmYlIthS75EyqHIJO%2FqJjq2g6geqzSc3i\u0026list-type=2\u0026max-keys=2\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "zZyisux9d9lIzXyYEoizJbqNaxpCvM0nrUtg647rU7T1mNgNjL72fXXSA49KsqnSDimN5j2KhYg=" + ], + "X-Amz-Request-Id": [ + "GZ55JPMR1QJ79Y4T" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxDb250aW51YXRpb25Ub2tlbj4xMlpMUTV2dHBpUURVL2dLWHZhWFFXZjdPZmdDc00xenFtWWxJdGhTNzVFeXFISUpPL3FKanEyZzZnZXF6U2MzaTwvQ29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjE8L0tleUNvdW50PjxNYXhLZXlzPjI8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestList/by_3.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/by_3.replay new file mode 100644 index 000000000..90f98af78 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/by_3.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPPkKZS0jgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "3983e8017187ad4c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "phQLTU2SnTyh5yJ5FeOdGzBl52A+HTgH5NAV/jx+rK+6chyHrJfwYcVQVbSfS18njQYad3lZTcOziBuZKl06ug==" + ], + "X-Amz-Request-Id": [ + "GZ5001Y955TZV48P" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxLZXlDb3VudD4zPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "708b3a85717b6ebb", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=3\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "3tCRURmEG7AmDe6zL3Xug4K+W1zGpqcL3u9KhlacI6lztuiOsXeusyrW+Hu5lxX/4cufO2NvA7DcVP5um/HBTA==" + ], + "X-Amz-Request-Id": [ + "GZ51G38NM0W7K5EG" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxLZXlDb3VudD4zPC9LZXlDb3VudD48TWF4S2V5cz4zPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestList/exactly_1_object_due_to_prefix.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/exactly_1_object_due_to_prefix.replay new file mode 100644 index 000000000..066108052 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/exactly_1_object_due_to_prefix.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPPkCX/14QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "c563bcc938039158", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "Bivmlwg9fryAlTz/NfIuh5IDh5gHCjmCVhM41XCgrKdvrbDQPkbRGaClgBEezZpZjbXxMlnzKmY=" + ], + "X-Amz-Request-Id": [ + "GZ5FA3J5A0QGTCRY" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxLZXlDb3VudD4zPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "127d5056127d1b3e", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list-1", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "uuyWUulVVoKglO/fjnlPJw7IzXjbFcezTU/qDwbppbS1CezE5CKE2JAQsEjvxuSnEj52KfQaHgc=" + ], + "X-Amz-Request-Id": [ + "GZ52AY3ETY80H6WV" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdC0xPC9QcmVmaXg+PEtleUNvdW50PjE8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTE8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzBUMTc6MDE6MTQuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestList/no_objects.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/no_objects.replay new file mode 100644 index 000000000..e3de9c774 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/no_objects.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPPkAsthiAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "97ecfa64283e61ef", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "W3tSLGjBaY/sWcrJbOLYpVYyhBY7yDZCfqTO35yyCcYAnTbbUul928bADazHL2gLe2skg5EP+dlmYYdlBzWy8tnyWrisgi1o8KbCtsSYClU=" + ], + "X-Amz-Request-Id": [ + "GZ54D8VVD4H6VZ97" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxLZXlDb3VudD4zPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "5a4770ca7576ed88", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=no-objects-with-this-prefix", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "swKs6fyJLakYjdIk11+zpTimE1FtI9DVDLLHIJgz5OMQjOiB38IlyvW8xK1Kf5lRyw5FA1tLkiqcNd507M+CLny7Ju3kN8NcUxtPvOzXrbw=" + ], + "X-Amz-Request-Id": [ + "GZ52PXAXR356SHNY" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bm8tb2JqZWN0cy13aXRoLXRoaXMtcHJlZml4PC9QcmVmaXg+PEtleUNvdW50PjA8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestList/no_pagination.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/no_pagination.replay new file mode 100644 index 000000000..0caac793b --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestList/no_pagination.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPPkEGlu7QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "cce33ba44cda12af", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "wzLZNMoBNvWHEtidOxCU/r2yq+dvrYGMNW6MD0jO89tDUG9qsgGAVJ+HIYr6rCWDiiVj7/x/rhE=" + ], + "X-Amz-Request-Id": [ + "GZ5A5K6VV2MJF0H2" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxLZXlDb3VudD4zPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "4b24d9c163fc8079", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "xsx7zXkmDN2roMbihGRqwbhoFUuQLz/TbhKQrA0lwjrOY+wpgjgMeBCezc9Jcd7wK3ffM91jjrk=" + ], + "X-Amz-Request-Id": [ + "GZ580PHWFAPD9RW3" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxLZXlDb3VudD4zPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestListDelimiters/abc.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestListDelimiters/abc.replay new file mode 100644 index 000000000..7eb9503ac --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestListDelimiters/abc.replay @@ -0,0 +1,831 @@ +{ + "Initial": "AQAAAA7ffPPmFKoG4AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "cdb646b25e45e538", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "3pUy/t5VJ8OCEeZmCIs2u7Tk4lM+1Cmv50QiQbQc/wCAHKIptlPO1rTOR5uKaZ5IvmyYyUpeBTo=" + ], + "X-Amz-Request-Id": [ + "3WXTN7NKW1GVNZ99" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48S2V5Q291bnQ+NjwvS2V5Q291bnQ+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2EudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2IudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2MudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2QudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiY2UudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMwVDE3OjAxOjE2LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTkuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "90a3260bafb37889", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "Uv2JsctJF/sTfZKa4Mi1ga/Rd00Rtc8eXZKnOQzk0t4NX1nq4zXc9Xs5k9LitBTAiF4BzPXhAx8=" + ], + "X-Amz-Request-Id": [ + "3WXQ3CE1DV0D73SW" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48S2V5Q291bnQ+NjwvS2V5Q291bnQ+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2EudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2IudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2MudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2QudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiY2UudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMwVDE3OjAxOjE2LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTkuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "f80b512a3b1ca665", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "10eMMtH586aR/g2d4vePtYB3ervGPnOEtEjARDoghVhbW5C3etBJvL6P6FYgK+GhrFIkUtblIrY=" + ], + "X-Amz-Request-Id": [ + "3WXTNSP8TP8FYKNA" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48S2V5Q291bnQ+MzwvS2V5Q291bnQ+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48RGVsaW1pdGVyPmFiYzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmM8L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiYzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "4629ba5d2de1dd98", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abcdir1abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "mthnq6Aj/63cy27ucalP6Jr0GnrDS8gw3WvriIAfloQlKorygeqOFNUyy0bDmLtsjw3qe99UAww=" + ], + "X-Amz-Request-Id": [ + "3WXPSN5E7SXCG12P" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjPC9QcmVmaXg+PEtleUNvdW50PjM8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj5hYmM8L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2EudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY2IudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiYzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "d096a8b8931206b1", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abcdir1abcsubdirabc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "DGnJh7XrpYZzXNkf2ep6qD/WY3QzcYX8goaJdC7eLflRweJDAeYpTBJzagr/9Z0R1z/gWAnYbgE=" + ], + "X-Amz-Request-Id": [ + "3WXHE6PT28K9VQM0" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjPC9QcmVmaXg+PEtleUNvdW50PjI8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj5hYmM8L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2MudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2QudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "6bb88714deaad358", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abcdir2abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "SWYunM56uF18KqeEpSEXvQggf9Y/OASZJSGKdvLLJxIHeQnzWbN75rlJ8yT+4WW3ah9bK2p8PG0=" + ], + "X-Amz-Request-Id": [ + "3WXSJBHQMNSMH1RR" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjPC9QcmVmaXg+PEtleUNvdW50PjE8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj5hYmM8L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiY2UudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMwVDE3OjAxOjE2LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "3fc81a686c953ada", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "60hXF9DhH+vVMc4H3B71CKTZAsI5Kv8tVexw0y7i7tlp29f/87vCRlX5EVd0ufFI6mf5hV0S4tA=" + ], + "X-Amz-Request-Id": [ + "3WXNM535QM2DFE29" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48TmV4dENvbnRpbnVhdGlvblRva2VuPjFETm9NaWl4N084cXlrWDlzaHdVbndTc3hpalJVd05iNGxBeXdJUW1WYkh0aHBkNnhzdjZ3Q3RQZmV4SS96L3AvQWtXbm9MeE1NY0dmN08wckhmL1AxUT09PC9OZXh0Q29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjE8L0tleUNvdW50PjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj5hYmM8L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "6c1f6894a9987e83", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1DNoMiix7O8qykX9shwUnwSsxijRUwNb4lAywIQmVbHthpd6xsv6wCtPfexI%2Fz%2Fp%2FAkWnoLxMMcGf7O0rHf%2FP1Q%3D%3D\u0026delimiter=abc\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "xRi8pSnqWa1TMeVX7AbA8gkW1tqS9KcI7MLn/15QeNulMyGx6Zy0LE0GIRnr3P0DZBQckU3OY8s=" + ], + "X-Amz-Request-Id": [ + "3WXWGDXWBGYD7688" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48Q29udGludWF0aW9uVG9rZW4+MUROb01paXg3TzhxeWtYOXNod1Vud1NzeGlqUlV3TmI0bEF5d0lRbVZiSHRocGQ2eHN2NndDdFBmZXhJL3ovcC9Ba1dub0x4TU1jR2Y3TzBySGYvUDFRPT08L0NvbnRpbnVhdGlvblRva2VuPjxOZXh0Q29udGludWF0aW9uVG9rZW4+MUpKb09pWjRBLzJuQk1xYUhTcUZ2SDNzTkF0dnF4YzVicWZ6SStyWlkyRUhHWUlOUlg3enhvY1NIWE14eEpXVU1XT0hHSzFoVUZIVThRaDVkRk1FUG1RPT08L05leHRDb250aW51YXRpb25Ub2tlbj48S2V5Q291bnQ+MTwvS2V5Q291bnQ+PE1heEtleXM+MTwvTWF4S2V5cz48RGVsaW1pdGVyPmFiYzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmM8L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "dfb47186008b134c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1JJoOiZ4A%2F2nBMqaHSqFvH3sNAtvqxc5bqfzI%2BrZY2EHGYINRX7zxocSHXMxxJWUMWOHGK1hUFHU8Qh5dFMEPmQ%3D%3D\u0026delimiter=abc\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "IlQ7gjOsD1XZEEexQrrJj7LRxgi91Mv6AMJxSQbawAJuzeyi+i29EgaVyjyf9d0uXKRMegXtAus=" + ], + "X-Amz-Request-Id": [ + "3WXQGJZF34HAQB7Q" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48Q29udGludWF0aW9uVG9rZW4+MUpKb09pWjRBLzJuQk1xYUhTcUZ2SDNzTkF0dnF4YzVicWZ6SStyWlkyRUhHWUlOUlg3enhvY1NIWE14eEpXVU1XT0hHSzFoVUZIVThRaDVkRk1FUG1RPT08L0NvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+YWJjPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2YudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "fff4f72a5c8fcfbd", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-abcdir2abce.txt", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Sun, 30 Mar 2025 17:01:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Zq6SLu9Of/IxGEllQSPQtMkP4+22qS0yZXTc5HgCA3kd0XYBPCftuy1kaH/diapBQzqrUHIMcCU=" + ], + "X-Amz-Request-Id": [ + "3WXH10MTGNFVPZZN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "fcd957032a2bf260", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-abcdir2abce.txt?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "8zKycx6PaHVzp7DD1vJRPXIdUFGMPWVYNciKOs1wRA4o2mdtINmqi4KTAWawdoj7WLesNx7/gpc=" + ], + "X-Amz-Request-Id": [ + "3WXRF29F93GZT41Y" + ] + }, + "Body": "" + } + }, + { + "ID": "d7a4a36ef17c7d36", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "HdsawQltgZe7/qGipj3fLnFcht1uZcNNvBq/AofjJcn2oWnPEEOt+BRspcRj54SZbjUbL2g4cLs=" + ], + "X-Amz-Request-Id": [ + "3WXMZZF3KW983BMA" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48S2V5Q291bnQ+MjwvS2V5Q291bnQ+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48RGVsaW1pdGVyPmFiYzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNmLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmM8L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "c3a9da72bd436934", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-abcdir2abce.txt?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "jOqzb/rm2V/fbC/retYmD/5SUQwBqsg0Z7qgkUL2En6zhf9qh40AxVv+ha8HLf6kidROPMnPGsg=" + ], + "X-Amz-Request-Id": [ + "3WXJS54TTXHXNQ9E" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestListDelimiters/backslash.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestListDelimiters/backslash.replay new file mode 100644 index 000000000..12a77cb1a --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestListDelimiters/backslash.replay @@ -0,0 +1,831 @@ +{ + "Initial": "AQAAAA7ffPPlNCS/JwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "18015b20ef4ed9ed", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "Gsnip9KDBb5Jvkz4NYAdW3utL1YKS7yyKsCdx1+JIgtTsLu2ndUykXjExkcP90adLtG8805RgRU=" + ], + "X-Amz-Request-Id": [ + "HXAHE7E1T9WT6SDB" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PEtleUNvdW50PjY8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXGEudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjQxOjI3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjFcYi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxzdWJkaXJcYy50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxzdWJkaXJcZC50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMlxlLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNi4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxmLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "e67723ef413b99fb", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "DfVXM+1DKVOZmvYr/yHQ3dq9NPKbMw6PV/egRlXOftoTdu9ZIWUpITAQUJLy1xLqikX2kHoWPmA=" + ], + "X-Amz-Request-Id": [ + "HXAWG5G3D39X4BRB" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PEtleUNvdW50PjY8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXGEudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjQxOjI3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjFcYi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxzdWJkaXJcYy50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxzdWJkaXJcZC50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMlxlLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNi4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxmLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "207f9869bc2d36ec", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "4GJb9I8Pbv5MMPrNinhQln5/GimKcYq082TR0ksHjSM3SVueU2KlSw0+aNeR0xoUFXzF/zWrYPA=" + ], + "X-Amz-Request-Id": [ + "HXAMKMWQN7CQ44D2" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PEtleUNvdW50PjM8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj5cPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxmLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXDwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMlw8L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "159216c29db174b1", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5Cdir1%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "0GNUnraskpWXbx+GXnXUFWm4YbyRQCYwj4eFW5+ePxpVxCNFz9Y2rAZ6OhNKVbMR63hPTPfMo+s=" + ], + "X-Amz-Request-Id": [ + "3WXJQR5DA7PE6BR4" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVw8L1ByZWZpeD48S2V5Q291bnQ+MzwvS2V5Q291bnQ+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48RGVsaW1pdGVyPlw8L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjFcYS50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxiLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXHN1YmRpclw8L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "e70c3b43ef9a53d9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5Cdir1%5Csubdir%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "VZropsb0oPXXtn09eye6BtgtaoJ33SBhlBmaLf2UFTJykeVOmG5l7QYee6llOcMFHj8EkVgV1WM=" + ], + "X-Amz-Request-Id": [ + "3WXNVY2NZDWXY46V" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxzdWJkaXJcPC9QcmVmaXg+PEtleUNvdW50PjI8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj5cPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXHN1YmRpclxjLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXHN1YmRpclxkLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "6c1de7e852aff4fb", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5Cdir2%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "fHq5nNm0+iRjSI/oMgplZi/TghTLSx3/PrBvKhTgbpDj24dF7YzDxbWauRnMk/1I75D6DaGl650=" + ], + "X-Amz-Request-Id": [ + "3WXHZ15BC40XAP9S" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMlw8L1ByZWZpeD48S2V5Q291bnQ+MTwvS2V5Q291bnQ+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48RGVsaW1pdGVyPlw8L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjJcZS50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzBUMTc6MDE6MTYuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "32d554572ca01262", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "SowDMgawfeHZhdxh369PeCwsEuWSVlPsDfWGkRh25j54Fs1iQcaBd7YjGkS1xnA+FgRx7ykRCAY=" + ], + "X-Amz-Request-Id": [ + "3WXTT75GA9XMKG3A" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PE5leHRDb250aW51YXRpb25Ub2tlbj4xaWxpSU1DODBGWnFFTjdWTzNMUWpjSFlOQkZNNXlQbmJGQ2NQa2ZBTWRONVlTT3VPeFBmZ0Jud0hvcVVuQ2JFRzZNRTdIYzdJeGw4PTwvTmV4dENvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+XDwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXDwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "238a6d31140fef6f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1iliIMC80FZqEN7VO3LQjcHYNBFM5yPnbFCcPkfAMdN5YSOuOxPfgBnwHoqUnCbEG6ME7Hc7Ixl8%3D\u0026delimiter=%5C\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "VhXvMC4ylQ/2IoeAlSb9y2KSEw2G/3pjPFMP2krMTKEZZ7fgMmfHr1ByqNFZh9ZZCBdpPFAipe8=" + ], + "X-Amz-Request-Id": [ + "3WXVT0Q0DG1XW302" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFpbGlJTUM4MEZacUVON1ZPM0xRamNIWU5CRk01eVBuYkZDY1BrZkFNZE41WVNPdU94UGZnQm53SG9xVW5DYkVHNk1FN0hjN0l4bDg9PC9Db250aW51YXRpb25Ub2tlbj48TmV4dENvbnRpbnVhdGlvblRva2VuPjFBNTJmWUh1dmNlTHBBTVhLeEN1SzRPZCtrRkV0ejBiYTJ4YmhCMFhIZnJHTVRlK3grREdmUGtqdVRXSXU1b201Tkp6RHFpaHVBU3M9PC9OZXh0Q29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjE8L0tleUNvdW50PjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj5cPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjJcPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "d5cf1838674e0f43", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1A52fYHuvceLpAMXKxCuK4Od%2BkFEtz0ba2xbhB0XHfrGMTe%2Bx%2BDGfPkjuTWIu5om5NJzDqihuASs%3D\u0026delimiter=%5C\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "5xhDyApLiaPDaIP2eNAYO6TrlhtCxd1JNed5IOQ5D2SNvyyT+yN4aM+n4Uhp/ymJL3E/3Puzdx4=" + ], + "X-Amz-Request-Id": [ + "3WXNAXH0118FRWM5" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFBNTJmWUh1dmNlTHBBTVhLeEN1SzRPZCtrRkV0ejBiYTJ4YmhCMFhIZnJHTVRlK3grREdmUGtqdVRXSXU1b201Tkp6RHFpaHVBU3M9PC9Db250aW51YXRpb25Ub2tlbj48S2V5Q291bnQ+MTwvS2V5Q291bnQ+PE1heEtleXM+MTwvTWF4S2V5cz48RGVsaW1pdGVyPlw8L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtXGYudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjQxOjI3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "1b9e3febaa3020cb", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-%5Cdir2%5Ce.txt", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Sun, 30 Mar 2025 17:01:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "8aUDoq8szedougxQFfON/xZncwrJmgAdusbte4HeGtkY5sJ2dpClaeg+NOKJGsnzRsS/OG2T6h8=" + ], + "X-Amz-Request-Id": [ + "3WXHG9D35F08E4GG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b265da6ff16df5e1", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-%5Cdir2%5Ce.txt?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "3XUh6yKxchH8hssZB5J66GifWsUnXvAnwErIqXL2/pwmjobtiFJowe3g1n+F1P6MmzpsAyvRoKA=" + ], + "X-Amz-Request-Id": [ + "3WXN4Q4KC7XWTM67" + ] + }, + "Body": "" + } + }, + { + "ID": "c72bd00c0acf28e4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "1GexYw2uoVfDbM8tfVE3FjUdKtAxXG3shfIJzrksOlTxSp+K5T+dPCFfzQu3FH9ilbgR8Amvdsw=" + ], + "X-Amz-Request-Id": [ + "3WXRDR8BVXJ1TH7T" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PEtleUNvdW50PjI8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj5cPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxmLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXDwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "93ea63a503c8a65b", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-%5Cdir2%5Ce.txt?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "iPQAzUjJ+kcWHwldJnTOIua32Sydiu0XMAT9MY6Z24AiAG1uFDnazlN9zovNU0BiQAzAh838ESM=" + ], + "X-Amz-Request-Id": [ + "3WXVAREJZZY7G7PA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestListDelimiters/fwdslash.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestListDelimiters/fwdslash.replay new file mode 100644 index 000000000..440091be4 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestListDelimiters/fwdslash.replay @@ -0,0 +1,831 @@ +{ + "Initial": "AQAAAA7ffPPlGTlqwAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "be6c627867a3808c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "HjZsxFSX90S1xGWmjc0AQJCkduH0BNiGv+2GjJ+dWeZKq+m090do5GDZ7HqdeeWpAjUPOn+UOvk=" + ], + "X-Amz-Request-Id": [ + "HXAZWBHP0Q1FJMHQ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PEtleUNvdW50PjY8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2EudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvYi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvYy50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvZC50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMi9lLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9mLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "5bc79c1a1a3486a5", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "mnjXxlInA5A/OxoVkdrE0sCIPo8Gf0sq84n9FaB8s6ULKVoZQzOOxeiN356RsgMLJ53/UY76DKY=" + ], + "X-Amz-Request-Id": [ + "HXAG7BWQ6V9HBGT1" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PEtleUNvdW50PjY8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2EudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvYi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvYy50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvZC50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMi9lLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMFQxNzowMToxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9mLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "6c02a23a0f52f124", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "8dqOCusC1BDmm2iTqUNz+YgnMpYphHHIjTtkbMIatr0Q6MUmB1pv7rNB9WUPQt+sQUqZgz40hLs=" + ], + "X-Amz-Request-Id": [ + "HXAKG9PC39FJ97TT" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PEtleUNvdW50PjM8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9mLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMi88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "be9248acad1df371", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2Fdir1%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "7i5+rqK+D3iN8lKKKvutMhnRniw+jIwd3v+MqyQsp1ihTdhWLn82kyGkcJd9XmMxoOYwXOVu0T4=" + ], + "X-Amz-Request-Id": [ + "HXAWXBFKD2AJZ2TQ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS88L1ByZWZpeD48S2V5Q291bnQ+MzwvS2V5Q291bnQ+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvYS50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9iLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "24f42b7b96fa7f17", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2Fdir1%2Fsubdir%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "75wqke+JIo8WVCXFbGo3oHOnKKiH/AF4tRtmyIGnnFHKiqjgfjSMCmzkZH1C0f5gi4H7om0oL7M=" + ], + "X-Amz-Request-Id": [ + "HXAHXE7B341J7CN9" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvPC9QcmVmaXg+PEtleUNvdW50PjI8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci9jLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci9kLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "ac079b453f3b49e3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2Fdir2%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "TeLpBHGmyb3XO14KO/uDunL/LobhrY6KmVsz+WH5R02QwcqliEcG3lcHEoLLl053wuWwHnEFshY=" + ], + "X-Amz-Request-Id": [ + "HXAXPRPEV25TPCC5" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMi88L1ByZWZpeD48S2V5Q291bnQ+MTwvS2V5Q291bnQ+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjIvZS50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzBUMTc6MDE6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "70562fa12bac4f1c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "xnkb4yCdPkVUg9lr30uMU8l1txWnIjq/3tFXEun+xlK2VtNSRTvXWbdd8+nD1kFoZCrJIaU/pqs=" + ], + "X-Amz-Request-Id": [ + "HXAJVYGYEQWJFQSK" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PE5leHRDb250aW51YXRpb25Ub2tlbj4xVnVEaDBZcVFzQnBKVTFLN1lwV3plOHROU3B3ZEtPNTU1UTlyOWszSWFkYVErQzNWRVFjMTJYSVFXNTJHdC9QRFNqSWlDSW1pdmxnPTwvTmV4dENvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "30799b3231b6a535", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1VuDh0YqQsBpJU1K7YpWze8tNSpwdKO555Q9r9k3IadaQ%2BC3VEQc12XIQW52Gt%2FPDSjIiCImivlg%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "wU6NSrUS+QMgoSXlKAGeYtieY1FB4iyEQS29uEq6i6F3lXkQc3GOABIW1PEc5tRJ36WzbXR0lW4=" + ], + "X-Amz-Request-Id": [ + "HXAW4HWJ5X6PGMPS" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFWdURoMFlxUXNCcEpVMUs3WXBXemU4dE5TcHdkS081NTVROXI5azNJYWRhUStDM1ZFUWMxMlhJUVc1Mkd0L1BEU2pJaUNJbWl2bGc9PC9Db250aW51YXRpb25Ub2tlbj48TmV4dENvbnRpbnVhdGlvblRva2VuPjFkbmtlMytBY0VXclVqeUNPRUxDYk1LeWw0NFBwZ1VSMEhWY0pCNWlGSWpGb1RxMk92bE5rdEVVdnFwQ29aM1RUbG5rWERqeGFNUm89PC9OZXh0Q29udGludWF0aW9uVG9rZW4+PEtleUNvdW50PjE8L0tleUNvdW50PjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjIvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "b01b00e38d1d2d82", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?continuation-token=1dnke3%2BAcEWrUjyCOELCbMKyl44PpgUR0HVcJB5iFIjFoTq2OvlNktEUvqpCoZ3TTlnkXDjxaMRo%3D\u0026delimiter=%2F\u0026list-type=2\u0026max-keys=1\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "6TKDe8L4pAu487oWGXIDxut5B5ZZ9mG7o1PBzBql9S72dgDmedr4ywBwdvz1wU9JTUJf9un8d4w=" + ], + "X-Amz-Request-Id": [ + "HXAGKECW2Y5YHCX3" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PENvbnRpbnVhdGlvblRva2VuPjFkbmtlMytBY0VXclVqeUNPRUxDYk1LeWw0NFBwZ1VSMEhWY0pCNWlGSWpGb1RxMk92bE5rdEVVdnFwQ29aM1RUbG5rWERqeGFNUm89PC9Db250aW51YXRpb25Ub2tlbj48S2V5Q291bnQ+MTwvS2V5Q291bnQ+PE1heEtleXM+MTwvTWF4S2V5cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtL2YudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "227ef94977d8bc53", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-/dir2/e.txt", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Sun, 30 Mar 2025 17:01:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "YqhndN2U5azZ+mDGgyBW7hDmigkItH0Svp9FYR7Ea/dt/EIabXp1lzfgtXyz+fKbv1U5eVTSpQ0=" + ], + "X-Amz-Request-Id": [ + "HXASG2FJDSW5EGD8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c90ea3991c718682", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-/dir2/e.txt?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "WOvuoAfh6wnFDlmCDHPgG1vUNuGPxFFepLFw7YbQAgbyQrqk3Y9mxCutKPIwEHOSF2vHeaqg/VQ=" + ], + "X-Amz-Request-Id": [ + "HXAVWHY15AWXSYGA" + ] + }, + "Body": "" + } + }, + { + "ID": "52bef1f907d6bf69", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026list-type=2\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "SLrmqXbXeu6Fx0K1/V5Q74deEgkVKpdG0QNlZdAshgp6kmYGZ5nmqdPZaAlOSKyJWiq/wghWbxM=" + ], + "X-Amz-Request-Id": [ + "HXAMW3XR10V71DFQ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PEtleUNvdW50PjI8L0tleUNvdW50PjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9mLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "880b93ebef6e08c4", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-/dir2/e.txt?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "+4P8DdPdXxfRNWJOjgDlCypvrwj1/M8T7nDiQRyR7j6PWYD/PwbNUg+vpODnghTwSBBj3t3JRc4=" + ], + "X-Amz-Request-Id": [ + "HXAZWYXWC9BYPW0R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestListWeirdKeys.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestListWeirdKeys.replay new file mode 100644 index 000000000..dc8c97d8f --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestListWeirdKeys.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPPlEr8U8gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "20d9e217883cf80d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=list-weirdkeys-", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "2M8zmEwgpDcIJlVKeQXN2+7jg1qMbSF5AompASioEsPC0nHq1VbYWSpbpw599E0u09IEa/XqIcE=" + ], + "X-Amz-Request-Id": [ + "HXAK2AAS3KXX98JX" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bGlzdC13ZWlyZGtleXMtPC9QcmVmaXg+PEtleUNvdW50PjE4PC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtICEmcXVvdDsjJCUmYW1wOyZhcG9zOygpKissLS4vPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLS4uX18weDJmX19mb28vLi5fXzB4MmZfX2Jhci8uLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX188L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtLi5fXzB4NWNfX2Zvb19fMHg1Y19fLi5fXzB4NWNfX2Jhcl9fMHg1Y19fLi5fXzB4NWNfXy4uX18weDVjX19iYXouLl9fMHg1Y19fPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLS4uX18weDVjX19mb29fXzB4NWNfX19fMHg1Y19fYmFyX18weDVjX19fXzB4NWNfX19fMHg1Y19fYmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLTEyMzQ1PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLTo7Jmx0Oz0mZ3Q7PzwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1APC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLVtfXzB4NWNfX11eXzwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1fXzB4MF9fX18weDFfX19fMHgyX19fXzB4M19fX18weDRfX19fMHg1X19fXzB4Nl9fX18weDdfX19fMHg4X19fXzB4OV9fX18weGFfX19fMHhiX19fXzB4Y19fX18weGRfX19fMHhlX19fXzB4Zl9fPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLV9fMHgxMF9fX18weDExX19fXzB4MTJfX19fMHgxM19fX18weDE0X19fXzB4MTVfX19fMHgxNl9fX18weDE3X19fXzB4MThfX19fMHgxOV9fX18weDFhX19fXzB4MWJfX19fMHgxY19fX18weDFkX19fXzB4MWVfX19fMHgxZl9fPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLWA8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtZm9vIGJhciBiYXo8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtZm9vJnF1b3Q7YmFyJnF1b3Q7YmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLWZvby8vYmFyLy8vYmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM5OjAxLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLWZvby9iYXIvYmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjQwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLWZvb19fMHg1Y19fYmFyX18weDVjX19iYXo8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMte3x9fn88L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMt4pi64pi64pi6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "db190c2931344fa0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=list-weirdkeys-", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "+Zq/l/x4RUDhJIh4qkOWZqvoL7jOHcJ6O0inTHXuzbSQnXEzfCCPyHE7k1XWr/If+SAqI2J1+ds=" + ], + "X-Amz-Request-Id": [ + "HXAVEHHDS0TVQT7H" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bGlzdC13ZWlyZGtleXMtPC9QcmVmaXg+PEtleUNvdW50PjE4PC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtICEmcXVvdDsjJCUmYW1wOyZhcG9zOygpKissLS4vPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLS4uX18weDJmX19mb28vLi5fXzB4MmZfX2Jhci8uLl9fMHgyZl9fLi5fXzB4MmZfX2Jhei4uX18weDJmX188L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtLi5fXzB4NWNfX2Zvb19fMHg1Y19fLi5fXzB4NWNfX2Jhcl9fMHg1Y19fLi5fXzB4NWNfXy4uX18weDVjX19iYXouLl9fMHg1Y19fPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLS4uX18weDVjX19mb29fXzB4NWNfX19fMHg1Y19fYmFyX18weDVjX19fXzB4NWNfX19fMHg1Y19fYmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLTEyMzQ1PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLTo7Jmx0Oz0mZ3Q7PzwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1APC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLVtfXzB4NWNfX11eXzwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1fXzB4MF9fX18weDFfX19fMHgyX19fXzB4M19fX18weDRfX19fMHg1X19fXzB4Nl9fX18weDdfX19fMHg4X19fXzB4OV9fX18weGFfX19fMHhiX19fXzB4Y19fX18weGRfX19fMHhlX19fXzB4Zl9fPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLV9fMHgxMF9fX18weDExX19fXzB4MTJfX19fMHgxM19fX18weDE0X19fXzB4MTVfX19fMHgxNl9fX18weDE3X19fXzB4MThfX19fMHgxOV9fX18weDFhX19fXzB4MWJfX19fMHgxY19fX18weDFkX19fXzB4MWVfX19fMHgxZl9fPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLWA8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtZm9vIGJhciBiYXo8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtZm9vJnF1b3Q7YmFyJnF1b3Q7YmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLWZvby8vYmFyLy8vYmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM5OjAxLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLWZvby9iYXIvYmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjQwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLWZvb19fMHg1Y19fYmFyX18weDVjX19iYXo8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMte3x9fn88L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMt4pi64pi64pi6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestMD5.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestMD5.replay new file mode 100644 index 000000000..1ded52141 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestMD5.replay @@ -0,0 +1,653 @@ +{ + "Initial": "AQAAAA7ffPPvJTrEgwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "7400d77d90e8467c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-aaa?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "L2Zh51lDzsCxsJSwtMyvFswpYGwOzvnGevv3p//TdmaUfAXkUZsz16PA9DCgt6gRRIB529bnq7M=" + ], + "X-Amz-Request-Id": [ + "VNEWCBN4TW1597KN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "5eed82b1dd98934b", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-bbb?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "48" + ], + "Content-Md5": [ + "afqrYmg1ApVVDefVh7wyPQ==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "7" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Nw0KZ29vZGJ5ZQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6RFkvWWRBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"69faab6268350295550de7d587bc323d\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DY/YdA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "9cdk9QPupD5DsPJ9+Kpn6RKM42v1DulwcQk61n/2p0ZTfQSB5ol7c++rJNqRzB7+5seXUD0HpRA=" + ], + "X-Amz-Request-Id": [ + "VNEQJ5TSMD6AESNX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b4556ab3a0127254", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-aaa", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "NMoWYtdQ9x9aRYCqrVjMkh4sONfMPBy27YDLrzZ8L/WKEdnkHP5eFqbY7sDijMXW5RK2M9U5UYk=" + ], + "X-Amz-Request-Id": [ + "VNEVJBHRYYYJDBP2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "4b86796c864869ef", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-bbb", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "7" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"69faab6268350295550de7d587bc323d\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "YUa6+h2tIOzXoXWuZyVBYj9pioyrwRzHXsD03UOczmQipzwzg4CFu89vgXzyuhpBYn8X1bc2jMY=" + ], + "X-Amz-Request-Id": [ + "VNEYHSJ3WH3R1VAF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "3756306a3f3d4110", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1000\u0026prefix=blob-for-md5-", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "6ElXrPQlTUIggiRVKUaKwO8DY7RcqcilW52FKavj/aPTZglZzHGBlcMzUEbp92o0jovBRfnN4rE=" + ], + "X-Amz-Request-Id": [ + "VNEZ70BPBKBZMW6N" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbWQ1LTwvUHJlZml4PjxLZXlDb3VudD4yPC9LZXlDb3VudD48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbWQ1LWFhYTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMVQyMDozNzowNC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1tZDUtYmJiPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjA0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs2OWZhYWI2MjY4MzUwMjk1NTUwZGU3ZDU4N2JjMzIzZCZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT43PC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "6c4dcff7d9cde2dd", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-bbb", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "7" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"69faab6268350295550de7d587bc323d\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "2LF0XLY1x3CZDNxmDaB93hJMDiBwkBfnuLEreV2T74ZDTBKrJq08Z+U33NB0e6HZqoMXEg1Svbk=" + ], + "X-Amz-Request-Id": [ + "VNEW1BZBSEN4VDED" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "132ad0cc93bf2039", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-bbb?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "IH+V0cFBPKPvT7i/RzCmzoan3XwHKynEnQS1gRrbWCodq2+/pLiMYocAfpdL29UDT0rkRTw6Kyo=" + ], + "X-Amz-Request-Id": [ + "VNEN67F3M45EP6KF" + ] + }, + "Body": "" + } + }, + { + "ID": "21e65547a201871f", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-aaa", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "yZR/0cZ/0iSoa5r5XA2W1Txd1r9TOoGFh4KIdH54mI9p3L0NX5kKaNuon6+kw5KVOcmTm6E4VZc=" + ], + "X-Amz-Request-Id": [ + "VNEYF12R6G0RS270" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "e3091185bc915a71", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-aaa?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "UFyqJtVm8K0PSF/dk6uhNnbG7K8v5plSkdYJqy1tvHYHRyz7dHxWdZAFgBYZy8+Psj5OGgPWL7o=" + ], + "X-Amz-Request-Id": [ + "VNEW1ZNTG71ENKSZ" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/duplicate_case-insensitive_key_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/duplicate_case-insensitive_key_fails.replay new file mode 100644 index 000000000..bc149b1f7 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/duplicate_case-insensitive_key_fails.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPPuNCU77wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/empty.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/empty.replay new file mode 100644 index 000000000..c06a1fe0a --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/empty.replay @@ -0,0 +1,321 @@ +{ + "Initial": "AQAAAA7ffPPuKQj18wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "ab61636d4aad6cbf", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "cIcU06wGzThuiLAApmAEvCp8gXfiNy7wvh77c6hokfymGIPWy96vLe6mMQsgsP/bRp01A0KAPvi5sdyHlP/CdA==" + ], + "X-Amz-Request-Id": [ + "NXJ9T9CQ6VRN4680" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "e8c0efa54218683c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "nAL+SSGh4tqTMwR0xQwCytoI+WgYofdVgfdoYWTwSDo7tjU5lxfkKKJYrLoIQpEff3YOxe4tEXxeHHk1YUWmfQ==" + ], + "X-Amz-Request-Id": [ + "NXJFSJ9E0MP91J34" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "2f4f7ece21606120", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "DHPKmRhXkLiWNgHjOwycRoqn7PyoB3qUONZHgggychUyEOREd2e3n8Vv7tbPMW8ZLbRDE4vJZ3WwiS8p9jq9YQ==" + ], + "X-Amz-Request-Id": [ + "NXJFR09DCY9Z2GMD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a20947189b429681", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Bujwcn5O5+rO1xdo0Dp2W75+SumAHjn9V7ZPN0b8a0hpc2pQpZfk2C6lJGJC0JFQhOZOGW8HuvpugsD/WQCerA==" + ], + "X-Amz-Request-Id": [ + "NXJ7629KHGWERE7X" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/empty_key_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/empty_key_fails.replay new file mode 100644 index 000000000..8fea8804a --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/empty_key_fails.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPPuNBmGWwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/non-utf8_metadata_key.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/non-utf8_metadata_key.replay new file mode 100644 index 000000000..f78dc4c10 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/non-utf8_metadata_key.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPPvJSV+igAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/non-utf8_metadata_value.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/non-utf8_metadata_value.replay new file mode 100644 index 000000000..a7b9ee320 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/non-utf8_metadata_value.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPPvJTEpuQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/valid_metadata.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/valid_metadata.replay new file mode 100644 index 000000000..7db6258af --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/valid_metadata.replay @@ -0,0 +1,348 @@ +{ + "Initial": "AQAAAA7ffPPuNC5ZfQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "5d7bb6456e38a863", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Meta-Key_a": [ + "value-a" + ], + "X-Amz-Meta-Key_b": [ + "value-b" + ], + "X-Amz-Meta-Key_c": [ + "vAlUe-c" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "/ea2RK2BBldFQTyQkeu+mv8OW5aMt6QVUWvbB+BNzOWzImpxQ6N/qrJiBxFpL7NzA16dvjTh3tG5RRw8xW6yHA==" + ], + "X-Amz-Request-Id": [ + "NXJ0Y158JS634X8N" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0eda6e751df8ac66", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "BB8oZQg1v8YFiXxX+IQQUikNGo1AVlZ1hXbmqsTqrrH9EFcSJ1QCBIGC/7HjPvoh4MNGu5Z4SYwIaADdJNe/DQ==" + ], + "X-Amz-Meta-Key_a": [ + "value-a" + ], + "X-Amz-Meta-Key_b": [ + "value-b" + ], + "X-Amz-Meta-Key_c": [ + "vAlUe-c" + ], + "X-Amz-Request-Id": [ + "NXJ8S9020Y1X3EZV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "d67f6cdce17669fe", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "PYduqXXSw/0Ue8QiTnHEtC2uaeSZ8xBrFmiBu7r9bYhTKsHj45Ot/0LGBsqmigU1Tk7BliB5ks4RAmbHN3yW2w==" + ], + "X-Amz-Meta-Key_a": [ + "value-a" + ], + "X-Amz-Meta-Key_b": [ + "value-b" + ], + "X-Amz-Meta-Key_c": [ + "vAlUe-c" + ], + "X-Amz-Request-Id": [ + "VNEMGH8FDWDANSHZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "78f79910a8256894", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "gA9648RlEQcJjNGkh5dzhr6LgEiOl+oacTdyZlZzBZR9oPXuS7l8C7sG0dq0nK/y00sRv2tcYGM26P4xkPVUkw==" + ], + "X-Amz-Request-Id": [ + "VNEHYS8AQ49Y387V" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/valid_metadata_with_content_type.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/valid_metadata_with_content_type.replay new file mode 100644 index 000000000..233e2593c --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/valid_metadata_with_content_type.replay @@ -0,0 +1,330 @@ +{ + "Initial": "AQAAAA7ffPPvDkvjzQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "a29216406a611efd", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ZUVEvSjEY25b9SdFQR0h6+mHBCkW2yKLlgFmZqwCLMZHM2Qx7wxoC+E1RxUJX5F+NhmWFF1LhQg=" + ], + "X-Amz-Request-Id": [ + "VNEGR5KR1FWDP27R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "70260e82a27affb1", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "B2BLLTrEweL5J7iYfGySaZqQMBUIzPVfKgmf9Nc0u1SzkJf+jf3BX/heLzrYlrAF/3wByrHnby4=" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "VNEMX7DYVYXSSSGM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "38b13308d6f5de3a", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "sg0evL/Kt7BI9se5tADbce8i8KpM72vbgr8Gk/TtkpoJgDkhXCnPyNNgvjDlwzt4hFfYb4W+H/s=" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "VNERGZQTTKNHPRQ4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "cbad6afd09ab26d3", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Zh1kKmjFJIqj1ItKMvd/If3A6vNeDwfNYQo1r+Zv2X5vmmNHcvUsBbyHNoeVR9p/qheRARGKU7g=" + ], + "X-Amz-Request-Id": [ + "VNETZ0X2FXQ7TCE1" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/valid_metadata_with_empty_body.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/valid_metadata_with_empty_body.replay new file mode 100644 index 000000000..338fc7b63 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/valid_metadata_with_empty_body.replay @@ -0,0 +1,330 @@ +{ + "Initial": "AQAAAA7ffPPvA3iYHQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "d2731798fb80e52f", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "g4kJ0qM/28Gjz1nXGzajrkjmuvkF0ox4MQdeuw2/ExNADHfcDv4TR1vnCey7uMN/iLtbF5fzIhg=" + ], + "X-Amz-Request-Id": [ + "VNEG5PJMXG24A1BB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "77feacaba5d10d6d", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "tVRALAiqVr9zazUqdzfZgFtC5QuWuqFeUAUMs6vKWLJFfz27cVSzMB5vIrItkb0nWqhF0/lA+KM=" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "VNEP1JQXMZ1XAVNZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0f18f33a6a54f2f8", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "4efntmePu1wFwelY3wAx+HCGJyxYlYWFCSwJRT2l5o6NlRlWvr+dHOfW4GNG97mM0AYmgGoJEEs=" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "VNEY5V13WQAWT329" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "824eb3adbccb921a", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "eYWqc4vZT5Fz/4qqgCgBqkOoh6soYTY98lY+Q5JmPRXD3oH5Wn9vYJSybv3+aaQgiwe7uLbEAbs=" + ], + "X-Amz-Request-Id": [ + "VNEPTK5Q2YJ5W5SF" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/weird_metadata_keys.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/weird_metadata_keys.replay new file mode 100644 index 000000000..a3f7c62fc --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestMetadata/weird_metadata_keys.replay @@ -0,0 +1,483 @@ +{ + "Initial": "AQAAAA7ffPPvGWPc7QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "9da9ca0283948657", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Meta-%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f": [ + "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F" + ], + "X-Amz-Meta-%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f": [ + "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F" + ], + "X-Amz-Meta-%20%21%22%23$%25\u0026%27%28%29%2a+%2c-.%2f": [ + "%20%21%22%23$%25\u0026%27%28%29%2A+%2C-.%2F" + ], + "X-Amz-Meta-%5b%5c%5d%5e_": [ + "%5B%5C%5D%5E_" + ], + "X-Amz-Meta-%60": [ + "%60" + ], + "X-Amz-Meta-%7b%7c%7d~%7f": [ + "%7B%7C%7D~%7F" + ], + "X-Amz-Meta-%e2%98%ba%e2%98%ba%e2%98%ba": [ + "%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Amz-Meta-..%2ffoo%2f..%2fbar%2f..%2f..%2fbaz..%2f": [ + "..%2Ffoo%2F..%2Fbar%2F..%2F..%2Fbaz..%2F" + ], + "X-Amz-Meta-..%5cfoo%5c%5cbar%5c%5c%5cbaz": [ + "..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz" + ], + "X-Amz-Meta-..%5cfoo%5c..%5cbar%5c..%5c..%5cbaz..%5c": [ + "..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C" + ], + "X-Amz-Meta-12345": [ + "12345" + ], + "X-Amz-Meta-Foo%20bar%20baz": [ + "foo%20bar%20baz" + ], + "X-Amz-Meta-Foo%22bar%22baz": [ + "foo%22bar%22baz" + ], + "X-Amz-Meta-Foo%2f%2fbar%2f%2f%2fbaz": [ + "foo%2F%2Fbar%2F%2F%2Fbaz" + ], + "X-Amz-Meta-Foo%2fbar%2fbaz": [ + "foo%2Fbar%2Fbaz" + ], + "X-Amz-Meta-Foo%5cbar%5cbaz": [ + "foo%5Cbar%5Cbaz" + ], + "X-Amz-Meta-__0x3a__%3b%3c__0x3d__%3e%3f": [ + ":%3B%3C=%3E%3F" + ], + "X-Amz-Meta-__0x40__": [ + "@" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Dmfa3hFmtNXzBPPdsNyMCgC4+49u6yGOj7nf59nSe32QFEH9Ox1e6zFqTLtbVHUlG886SKxuTxo=" + ], + "X-Amz-Request-Id": [ + "VNEW529YKZAK4FCZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "2f17a0a9f13d5a5a", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "qi6CADF8L1qOYb6bHYV45XB+9raoUXNhhyNC90LaZeaxr013tc1MR6c1UK3cf1bwEXfWpyZF/l8=" + ], + "X-Amz-Meta-%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f": [ + "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F" + ], + "X-Amz-Meta-%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f": [ + "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F" + ], + "X-Amz-Meta-%20%21%22%23$%25\u0026%27%28%29%2a+%2c-.%2f": [ + "%20%21%22%23$%25\u0026%27%28%29%2A+%2C-.%2F" + ], + "X-Amz-Meta-%5b%5c%5d%5e_": [ + "%5B%5C%5D%5E_" + ], + "X-Amz-Meta-%60": [ + "%60" + ], + "X-Amz-Meta-%7b%7c%7d~%7f": [ + "%7B%7C%7D~%7F" + ], + "X-Amz-Meta-%e2%98%ba%e2%98%ba%e2%98%ba": [ + "%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Amz-Meta-..%2ffoo%2f..%2fbar%2f..%2f..%2fbaz..%2f": [ + "..%2Ffoo%2F..%2Fbar%2F..%2F..%2Fbaz..%2F" + ], + "X-Amz-Meta-..%5cfoo%5c%5cbar%5c%5c%5cbaz": [ + "..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz" + ], + "X-Amz-Meta-..%5cfoo%5c..%5cbar%5c..%5c..%5cbaz..%5c": [ + "..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C" + ], + "X-Amz-Meta-12345": [ + "12345" + ], + "X-Amz-Meta-Foo%20bar%20baz": [ + "foo%20bar%20baz" + ], + "X-Amz-Meta-Foo%22bar%22baz": [ + "foo%22bar%22baz" + ], + "X-Amz-Meta-Foo%2f%2fbar%2f%2f%2fbaz": [ + "foo%2F%2Fbar%2F%2F%2Fbaz" + ], + "X-Amz-Meta-Foo%2fbar%2fbaz": [ + "foo%2Fbar%2Fbaz" + ], + "X-Amz-Meta-Foo%5cbar%5cbaz": [ + "foo%5Cbar%5Cbaz" + ], + "X-Amz-Meta-__0x3a__%3b%3c__0x3d__%3e%3f": [ + ":%3B%3C=%3E%3F" + ], + "X-Amz-Meta-__0x40__": [ + "@" + ], + "X-Amz-Request-Id": [ + "VNES8A4HSKR937VW" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "dc475c65dc3ea35f", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "nyDPM2WUKM0pjf2bcBTi0wmQpYL0x8QIOoZJCF067mE9VfaGqNaXvDA7cJfnba4145yg3oFRnA0=" + ], + "X-Amz-Meta-%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f": [ + "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F" + ], + "X-Amz-Meta-%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f": [ + "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F" + ], + "X-Amz-Meta-%20%21%22%23$%25\u0026%27%28%29%2a+%2c-.%2f": [ + "%20%21%22%23$%25\u0026%27%28%29%2A+%2C-.%2F" + ], + "X-Amz-Meta-%5b%5c%5d%5e_": [ + "%5B%5C%5D%5E_" + ], + "X-Amz-Meta-%60": [ + "%60" + ], + "X-Amz-Meta-%7b%7c%7d~%7f": [ + "%7B%7C%7D~%7F" + ], + "X-Amz-Meta-%e2%98%ba%e2%98%ba%e2%98%ba": [ + "%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Amz-Meta-..%2ffoo%2f..%2fbar%2f..%2f..%2fbaz..%2f": [ + "..%2Ffoo%2F..%2Fbar%2F..%2F..%2Fbaz..%2F" + ], + "X-Amz-Meta-..%5cfoo%5c%5cbar%5c%5c%5cbaz": [ + "..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz" + ], + "X-Amz-Meta-..%5cfoo%5c..%5cbar%5c..%5c..%5cbaz..%5c": [ + "..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C" + ], + "X-Amz-Meta-12345": [ + "12345" + ], + "X-Amz-Meta-Foo%20bar%20baz": [ + "foo%20bar%20baz" + ], + "X-Amz-Meta-Foo%22bar%22baz": [ + "foo%22bar%22baz" + ], + "X-Amz-Meta-Foo%2f%2fbar%2f%2f%2fbaz": [ + "foo%2F%2Fbar%2F%2F%2Fbaz" + ], + "X-Amz-Meta-Foo%2fbar%2fbaz": [ + "foo%2Fbar%2Fbaz" + ], + "X-Amz-Meta-Foo%5cbar%5cbaz": [ + "foo%5Cbar%5Cbaz" + ], + "X-Amz-Meta-__0x3a__%3b%3c__0x3d__%3e%3f": [ + ":%3B%3C=%3E%3F" + ], + "X-Amz-Meta-__0x40__": [ + "@" + ], + "X-Amz-Request-Id": [ + "VNEVDRYZPK57NGSK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ea63297d65967d4e", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:04 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "qBVwmB7HZ7baY1NfgjYJqyJ2kNsIuJ3kn3jiOC7URKwfoeGNqHfhj2JYT0f1MJ9bXkp+jRSD8R0=" + ], + "X-Amz-Request-Id": [ + "VNEQGMXR70H7NB8H" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestNonexistentBucket.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestNonexistentBucket.replay new file mode 100644 index 000000000..bf845bb04 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestNonexistentBucket.replay @@ -0,0 +1,160 @@ +{ + "Initial": "AQAAAA7ffPPjDlXWDQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "919536bbbfdaeabd", + "Request": { + "Method": "GET", + "URL": "https://go-cdk-bucket-does-not-exist.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:51 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "e1DluF6BUa4jsZsEFqTpXQ7WcKkxH5lNRkX1PSnaGCyoM5jzzUdWFk0jEAfhdkGbWGVnfudp2V0=" + ], + "X-Amz-Request-Id": [ + "BFYFDVYYTA5SAPFM" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEJ1Y2tldDwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGJ1Y2tldCBkb2VzIG5vdCBleGlzdDwvTWVzc2FnZT48QnVja2V0TmFtZT5nby1jZGstYnVja2V0LWRvZXMtbm90LWV4aXN0PC9CdWNrZXROYW1lPjxSZXF1ZXN0SWQ+QkZZRkRWWVlUQTVTQVBGTTwvUmVxdWVzdElkPjxIb3N0SWQ+ZTFEbHVGNkJVYTRqc1pzRUZxVHBYUTdXY0treEg1bE5Sa1gxUFNuYUdDeW9NNWp6elVkV0ZrMGpFQWZoZGtHYldHVm5mdWRwMlYwPTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "af7723969ed8f4d1", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?list-type=2\u0026max-keys=1", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:53 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "ckZ4tdX6N9d0JUpqlAwoovPUj5mF+bjEgpTF78xeesq0AQcWdSV6w+9+20QwTCv4o5KcKxEFdE9K0oa+NFbQ1mIh8FK2KU8gzSS8hlv4u4Q=" + ], + "X-Amz-Request-Id": [ + "GZ50GRAW0F3R0YVJ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+PC9QcmVmaXg+PE5leHRDb250aW51YXRpb25Ub2tlbj4xMGc3Yzl4QVRuSERSOFZZZ3FhNllsalpuckVEemt0bUVkYUNyazA3SjB0MjRQdEs4SWJ5TnNseXNwSFRjWVhiRTdzZEgzZUVzeWpZaTNsU1NOdVZCVVE9PTwvTmV4dENvbnRpbnVhdGlvblRva2VuPjxLZXlDb3VudD4xPC9LZXlDb3VudD48TWF4S2V5cz4xPC9NYXhLZXlzPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1jb3B5aW5nLWRlc3Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzBUMTc6MDE6MjUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90O2IxMGE4ZGIxNjRlMDc1NDEwNWI3YTk5YmU3MmUzZmU1JnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjExPC9TaXplPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/length_0_read.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/length_0_read.replay new file mode 100644 index 000000000..9139ec426 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/length_0_read.replay @@ -0,0 +1,409 @@ +{ + "Initial": "AQAAAA7ffPPnJc797AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "ad5c9fcdcbaefb22", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "cH8xc2J362VNlLUj/wimzjZzrBg21UVh5k7LoHvj8YKDGEsueVAsx6HaRqW7+7/JXPBl6TGqjjLY3ib5tnF1I8QXrftpKF9ug9/8nPPtkXc=" + ], + "X-Amz-Request-Id": [ + "2DCZFK14ZQVZWEFY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7d5f50e64f169558", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=0-0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 0-0/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ojglzHeJe3zbjB5HvuCBxiwo0w3aHOuajmH9yHHDDlt0EAGq5YcJfcDbyTTrmBcQR/KQX+GNt+gkVnXRRNXDUfniGHfO+2KJywXgapagEJ8=" + ], + "X-Amz-Request-Id": [ + "2DCXX1DWZZBG69AK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YQ==" + } + }, + { + "ID": "1082a93cb71c2ce7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=0-0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 0-0/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "kizTN+Umdz3MeUG6erk9daf9CLSlP/rY8PS1grWvMPZXTpM0o0wGVwT3++r6fnkovk98ZN09HcPXJTjn7H0iy1dFUH8ygUAz9HwyHro98q0=" + ], + "X-Amz-Request-Id": [ + "2DCVX7SEFHFRQ70F" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YQ==" + } + }, + { + "ID": "f748af6557b8ab87", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "i70b3NUUh0UPWtOvnCGAfFqp9OWNEPdQZ8C6taMZnJALLb/FrthHoWLTcwizK0w6DGCWb39dGrhV/Q79s/5IcJkikr8yC5zTFNIN4g1dhpA=" + ], + "X-Amz-Request-Id": [ + "2DCPYAF15WKGR7QY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "8611f2a2220fbd1d", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "poiTsVjObcWdM4kvWDkM0foTWwB3VzcBtHaP8HeDY74i1rtzPiO8FFa9417kgcvJOGvyGiu65yboXLtTz19cnPHYZPW2RumN5+B7aodhwYQ=" + ], + "X-Amz-Request-Id": [ + "2DCWZHPGZ2WAW508" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/negative_offset_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/negative_offset_fails.replay new file mode 100644 index 000000000..8eb2aea5b --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/negative_offset_fails.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPPnJcPSMgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_a_part_in_middle.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_a_part_in_middle.replay new file mode 100644 index 000000000..9cad0dfac --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_a_part_in_middle.replay @@ -0,0 +1,646 @@ +{ + "Initial": "AQAAAA7ffPPoCg3BewAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "96c26ad4a72d75e0", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "EDne4oEFqyqvioJA7qS6EnSuRBDvZytg8cIMuEAJYd2iVgAxYQMNkTo/h76Kllua8RRL/Kyrms0=" + ], + "X-Amz-Request-Id": [ + "Z1DGX10KAM9Q1D0G" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "33315bed2350c714", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=10-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 10-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "/LHT3PzihPu4Hiwgv+p1B6ScQ0hMmYKCufV1grtHjvvKUyOQodxI+5NtcdPRidGXbHxjCdGoUCw=" + ], + "X-Amz-Request-Id": [ + "Z1DWBY1RH7YMA91G" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "a2xtbm8=" + } + }, + { + "ID": "f631ad984f8ad1d2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=10-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 10-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "OuXCUgcZfqa+WNJEGA0OUosffgytFOYn3qLczcLBBVQ0JIrTkyNa02rWSfGfx9rCWjjnRHvuYhQ=" + ], + "X-Amz-Request-Id": [ + "Z1DXTMXM5NFBKNVR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "a2xtbm8=" + } + }, + { + "ID": "d97f0dd25ece5c08", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=14-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 14-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "cxyZoLOe2O27oUgLauitdf8peu8WjSR7BLre5AxkwAtLk5jnouZq0CnD6WWy4kkEh49GIQcdhF0=" + ], + "X-Amz-Request-Id": [ + "Z1DJ0C5HN5PE7T8Y" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "bw==" + } + }, + { + "ID": "3d11a5bad7ef6d9b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=14-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 14-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "P11VwZvFG3yMTUJ4KHiO4EfDfONBBDBhztZI5ucsH2jbzTDhPdGy1X9QHdTQUlb5R+t6S+LHpzk=" + ], + "X-Amz-Request-Id": [ + "Z1DQT7NVS8DBYTH6" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "bw==" + } + }, + { + "ID": "c7f2121c17c80981", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=12-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "3" + ], + "Content-Range": [ + "bytes 12-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "iffLOmkLhkwgvaA2w83ZYtUlvMqATsLdbKuWhtABtRRJKiYWpIqiDSnAWVO+216Rww71RWX/7yM=" + ], + "X-Amz-Request-Id": [ + "Z1DZ95JHKH5BC1D7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "bW5v" + } + }, + { + "ID": "4790b2bb547c7424", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "KZi2MZol74dc9/7UkgDGydT6/OUFkGpTnZWdHhXRYSkf5BggyeUZEs7h7SYmIUBu2Ge4kSlK8eg=" + ], + "X-Amz-Request-Id": [ + "Z1DPSNS90T4KBP5W" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "40a36a705d0692cd", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "B9ErwnW8LgwW0PWLYjt6mcnFH1ex8zLOrPqqVEHNCPqKfRBj8cMeNHJsfLoeWwFXWRbFZKHKfUY=" + ], + "X-Amz-Request-Id": [ + "Z1DW8YNJ2F7JMRH8" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_from_positive_offset_to_end.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_from_positive_offset_to_end.replay new file mode 100644 index 000000000..17e7d5e0e --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_from_positive_offset_to_end.replay @@ -0,0 +1,646 @@ +{ + "Initial": "AQAAAA7ffPPnMpkkRQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "45d6d521762c9976", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "UMmem4Ym5YfSR+qoAeDQ+vj+vwuj2Bwi97FreP+Yjg55P5lMnyMp0zODMUuOM4Ab08DrcBRO+kU=" + ], + "X-Amz-Request-Id": [ + "2DCYT7JXTV2BK94Z" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1ddc533677c4db7e", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=10-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "17" + ], + "Content-Range": [ + "bytes 10-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "6u8TF/3KHtKEBLUoZgUohQ6lvGKYh6bQgf1YUD/Ib0hP2hX4U6v+YHOQXKIDk4N/qZF/r9M4jpc=" + ], + "X-Amz-Request-Id": [ + "2DCYJAZ4393K55ZD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "a2xtbm9wcXVyc3R1dnd4eXo=" + } + }, + { + "ID": "4ef7753080fe0652", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=10-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "17" + ], + "Content-Range": [ + "bytes 10-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "/dfwTQqrxRMiTb+J8ZnYkNKR89pN9Yhgq80losIGyvmT5xXFzTiki+0i4Sha5pV3XLwoLg6i3bI=" + ], + "X-Amz-Request-Id": [ + "2DCR8WDVC25EVR5Z" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "a2xtbm9wcXVyc3R1dnd4eXo=" + } + }, + { + "ID": "7a6aef9e2bf50433", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=22-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 22-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "KY2nNMzaqql3wpoPrzU1bQyX9u07srEQCv6bQ0zDoVBY5Qlmbjjx4V8DA4OTaWfPrLVOvA32phA=" + ], + "X-Amz-Request-Id": [ + "Z1DHXKKGXW6FN1A5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "dnd4eXo=" + } + }, + { + "ID": "20137e93d4b749c9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=22-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 22-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "OKxu8B14ZlCYfor0P3fyl/p3vQ3EiSzTxPi8PQD4LynKz5inKFyJdV5INZAqnkFk99i9q8nEnJ4=" + ], + "X-Amz-Request-Id": [ + "Z1DT2Z0KZD31ENKB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "dnd4eXo=" + } + }, + { + "ID": "054aabaee841999a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=16-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Range": [ + "bytes 16-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "EAriOHTG6/NRy0LLnruzSVu12tAin6yRYZnzfNc1nYR/+pPMZmWfCt/0oHGIq8gCTJQnpXQyoUI=" + ], + "X-Amz-Request-Id": [ + "Z1DN9VEYD61549BX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "cXVyc3R1dnd4eXo=" + } + }, + { + "ID": "df8b08bcd07daa1c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "qc3J5080OmFTx5INEMcXW6hYyDIWcQrkiYm7CfWErw3gHfcb8GiJR7WDvru+dkz+3NHoUzaICTw=" + ], + "X-Amz-Request-Id": [ + "Z1DZTFEQJFJECEY3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "bfcd5bbf47436b23", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ka2z+J7RsW/9w8LcGqFcRDQCuUWotTSgRaUdiJPAtcjV07cYwpxve5Hv8qsLtlsN0xuLzjxoQos=" + ], + "X-Amz-Request-Id": [ + "Z1DZ2HVNZKJC60N1" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_in_full.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_in_full.replay new file mode 100644 index 000000000..f145d15b4 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_in_full.replay @@ -0,0 +1,646 @@ +{ + "Initial": "AQAAAA7ffPPoKbGfdAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "5c37e7c9a64625f1", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "8PrLI1RSNkhCHSwZvJ/CqgdJjkzfpwmYK1EF/c5jJWo6/5hCztac4F31s8wZP2cANEVqowsbWwQ=" + ], + "X-Amz-Request-Id": [ + "Z1DQE7VHGYA2EGK9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "bad81aa5121ede4c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ILs1GWeV+9JEevwRvZJubBy6ORjwCRLHEPkoozXAb4RR1sTDBRfgpirrKxvmg3bhT9fhMcu8y/k=" + ], + "X-Amz-Request-Id": [ + "Z1DS8J0AYF9EFZVP" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "d3b614ee9c2db786", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "GOsv3BHsvxG/HltqU3J9A9KQSJ6r8u4VXFSu1pwTh4gIR2UQU8TnKRTUXx3nzy8FFHV7aNssaII=" + ], + "X-Amz-Request-Id": [ + "Z1DP9A3VCW4ADRHN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "53fca76b2ef71c57", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "l4/Ide3RmJiZyx2mYgmgkn8JhrHQCb/LNDdMuceHOwnusvxJ2A0bLKZB2oQ1b5OOCYF29gKDnvI=" + ], + "X-Amz-Request-Id": [ + "Z1DWVCQDY6DQZS18" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "907cbe289e15466f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Fb70G4fm3zZNtscNg9HBdaLKhiV2YMNZdzErIzUqWBxTQ5DJyDHlJA9E0fPh2+f8rNE+gG3Q8gA=" + ], + "X-Amz-Request-Id": [ + "Z1DYMHRYM7MQW566" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "67c78ec779a4283e", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=9-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "18" + ], + "Content-Range": [ + "bytes 9-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "VkzRiWY7pxnCz3NNPXmefVNVx132bwfnClv1Yo7lPSL8pu9xJ4ksWaDgZNOOkAkwmpKaLFsEgsQ=" + ], + "X-Amz-Request-Id": [ + "Z1DVP7SMJR3CYSAG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "amtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "8c3a64e1d1b3d6b3", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "YqfFFyN+VMTijmPBWxniEOMxA7Qju9fB6GbimkERBHsdd6tziM+p9QKyIb0pVlPTGxkF3d81D5U=" + ], + "X-Amz-Request-Id": [ + "Z1DZTYV9ZMX9W0VH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c08448a2f8915f49", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "kh9PiZblXJXlkX9P9wNedbEFqnkgPkJLhI6PbDLKu/bFEM0I/OZiVPqoUfUc1948BhwxfVdZBiU=" + ], + "X-Amz-Request-Id": [ + "Z1DRXFCXQEZ9MK98" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_in_full_with_negative_length_not_-1.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_in_full_with_negative_length_not_-1.replay new file mode 100644 index 000000000..8bc5a9bfb --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_in_full_with_negative_length_not_-1.replay @@ -0,0 +1,646 @@ +{ + "Initial": "AQAAAA7ffPPoO2brfQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "8215fa1e610d866d", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "y1ozGYy72rGGFTPArMAXe6+zPm7MHLRUa0FU8iA+iw6LbY8dUpWJ0u0fkqQviC6eaRCD+SzstrvhC2x8tOis0Q==" + ], + "X-Amz-Request-Id": [ + "4NSE6N2M1S11R52S" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6cc78cb43dcc1f2c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "kF3vEyldWA3u61i4VyB+TbHOR6av+/whTFaPMEWfIftzmM4fNna/k+pKMF4KzB16IySIaVR1O4OeHnq2D0Z2jA==" + ], + "X-Amz-Request-Id": [ + "4NS7JGZEQ8GTMYKX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "d7b7588e6b911c84", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "kEv8sN/5QjDbfs80SZrQPKxQYbWGTGLjJpwHOpMWAO8XY9GzkV7WIamr5oolNpwhYXWHsz5SbINrNNVdt5zDkQ==" + ], + "X-Amz-Request-Id": [ + "4NSFPSG0NN2EGFQN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "95d7aca6117c62da", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "qDXh5i4Q/pHHS4ACy2PVSkYrVnebhBz3IVfpYoVsNPMafamQ8LKOHVfjW+NarBQ2BnBKzbVS9lWiU74MtDt1CQ==" + ], + "X-Amz-Request-Id": [ + "4NS9TVH9E99B3PMV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "e7175c12425321f8", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "D3AfhV5xZ28HQC+UZe2ew7TKSZ6rHxyLzpw8rCaWGZnGZDg8/xQyyjOpX3D/87rzALZ+65w5SAMbJ6wMdOr6XQ==" + ], + "X-Amz-Request-Id": [ + "4NS26VFSX994VM2H" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "c7f7c917151e85b4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=9-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "18" + ], + "Content-Range": [ + "bytes 9-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "crKyV5hRWKnjRS7Wp3CmEl+CQSHboSGZHIj8nuxxcUiMENKp4ANfhI+OEHgYBYO/vrzlaiQE24YvH+1KvNFbIw==" + ], + "X-Amz-Request-Id": [ + "4NS67K87GS5DT0T4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "amtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "554d543fa0131e58", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "d/SdYQQPyphhIrm+4LpNTuIIvkKWiQ5xzJNWs8bNW4V+kDlQyWeTqDRGc1izNa8LaWc+bpgApCybIeI80AsQ9w==" + ], + "X-Amz-Request-Id": [ + "4NS6J6S0EMRB58CK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "66727a29cb7f0c54", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "6qSDgwTgkBthUIqmjVs1CxRBlh2U7OZqGHVJYxDt0fxawvhn2mjujSMVI/gOHFqyT3cGrR8IlfQzNJaZ6Gdsfw==" + ], + "X-Amz-Request-Id": [ + "4NS78Z1N7WE9RHHZ" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_of_nonexistent_key_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_of_nonexistent_key_fails.replay new file mode 100644 index 000000000..e4ea8696a --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestRead/read_of_nonexistent_key_fails.replay @@ -0,0 +1,309 @@ +{ + "Initial": "AQAAAA7ffPPnGuBpFgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "0f2473ffabafcf4c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "mX8/Y5ihcRngtx3K2JvtTlp+m881W79l6cjfU1tNCZKngyxaZUWCFKgWUloSNPKPJHsk1z0MBoM=" + ], + "X-Amz-Request-Id": [ + "2DCWG4PV4X0H483Z" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "fcc2f63d355127ed", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key-does-not-exist?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "LZmCOFluytUzm7UCuW02gkl9qoxl+StiTeHv8B54OHQ8ij58Qp+PZnvpcX2gMAk2tFzLgaxXb6I=" + ], + "X-Amz-Request-Id": [ + "2DCWJNQHNQDMY0YE" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5rZXktZG9lcy1ub3QtZXhpc3Q8L0tleT48UmVxdWVzdElkPjJEQ1dKTlFITlFETVkwWUU8L1JlcXVlc3RJZD48SG9zdElkPkxabUNPRmx1eXRVem03VUN1VzAyZ2tsOXFveGwrU3RpVGVIdjhCNTRPSFE4aWo1OFFwK1BabnZwY1gyZ01BazJ0RnpMZ2F4WGI2ST08L0hvc3RJZD48L0Vycm9yPg==" + } + }, + { + "ID": "142aa2e3ad24de56", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "xKyfnwwmUgk6+8H1NDvnO6glI8MU/NykMaEj37fekSKxo01D+J5/Roc6pEEwFP9mSqCs8TDAtPQ=" + ], + "X-Amz-Request-Id": [ + "2DCVBYD4CRGGT9FC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "425297a48d47b34d", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:56 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "eWFiJrprIYpZpzoP6yTHFmwZYbi9Y7fZv5PnO7zH7terapba2I5pE+BG7ahT1Qwrwu8X5so8Hhw=" + ], + "X-Amz-Request-Id": [ + "2DCKTYQZE03VDG4W" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestSignedURL.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestSignedURL.replay new file mode 100644 index 000000000..00d9ec488 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestSignedURL.replay @@ -0,0 +1,381 @@ +{ + "Initial": "AQAAAA7ffPP3GsMgZwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "bc56d94d0b866f41", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rs2CBMTCwZed/+17oYniTXoYv1NtNfovbEjuwD7y7EMhP+GcEgZndadPdZB5A+UShh2EqvriEe8=" + ], + "X-Amz-Request-Id": [ + "EEN3P45PNRDGVQS5" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPlNpZ25hdHVyZURvZXNOb3RNYXRjaDwvQ29kZT48TWVzc2FnZT5UaGUgcmVxdWVzdCBzaWduYXR1cmUgd2UgY2FsY3VsYXRlZCBkb2VzIG5vdCBtYXRjaCB0aGUgc2lnbmF0dXJlIHlvdSBwcm92aWRlZC4gQ2hlY2sgeW91ciBrZXkgYW5kIHNpZ25pbmcgbWV0aG9kLjwvTWVzc2FnZT48QVdTQWNjZXNzS2V5SWQ+QUtJQVdVV0VVU1BVTFlYM0JMM008L0FXU0FjY2Vzc0tleUlkPjxTdHJpbmdUb1NpZ24+QVdTNC1ITUFDLVNIQTI1NgoyMDI1MDMzMVQyMDM3MTFaCjIwMjUwMzMxL3VzLXdlc3QtMS9zMy9hd3M0X3JlcXVlc3QKZjFjOTc4NTk3MDJjNWE3Y2UyOTEyN2Q4NzEwNDQ0ZTE1YzRlYzgzNmEzNGE2NTVkNGUxZWU5NWU3OTk1Mzc2ZjwvU3RyaW5nVG9TaWduPjxTaWduYXR1cmVQcm92aWRlZD4xYTZjMjQ1MGUzOGQyZjZkZjg0YTMxZWUzYjE4NjYyMzhhZDRkZTMzODJjZWQxODljZDc3MmZlZjMyNWJjOThmPC9TaWduYXR1cmVQcm92aWRlZD48U3RyaW5nVG9TaWduQnl0ZXM+NDEgNTcgNTMgMzQgMmQgNDggNGQgNDEgNDMgMmQgNTMgNDggNDEgMzIgMzUgMzYgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgNTQgMzIgMzAgMzMgMzcgMzEgMzEgNWEgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgMmYgNzUgNzMgMmQgNzcgNjUgNzMgNzQgMmQgMzEgMmYgNzMgMzMgMmYgNjEgNzcgNzMgMzQgNWYgNzIgNjUgNzEgNzUgNjUgNzMgNzQgMGEgNjYgMzEgNjMgMzkgMzcgMzggMzUgMzkgMzcgMzAgMzIgNjMgMzUgNjEgMzcgNjMgNjUgMzIgMzkgMzEgMzIgMzcgNjQgMzggMzcgMzEgMzAgMzQgMzQgMzQgNjUgMzEgMzUgNjMgMzQgNjUgNjMgMzggMzMgMzYgNjEgMzMgMzQgNjEgMzYgMzUgMzUgNjQgMzQgNjUgMzEgNjUgNjUgMzkgMzUgNjUgMzcgMzkgMzkgMzUgMzMgMzcgMzYgNjY8L1N0cmluZ1RvU2lnbkJ5dGVzPjxDYW5vbmljYWxSZXF1ZXN0PlBVVAovYmxvYi1mb3Itc2lnbmluZwpYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZhbXA7WC1BbXotQ2hlY2tzdW0tTW9kZT1FTkFCTEVEJmFtcDtYLUFtei1DcmVkZW50aWFsPUFLSUFXVVdFVVNQVUxZWDNCTDNNJTJGMjAyNTAzMzElMkZ1cy13ZXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZhbXA7WC1BbXotRGF0ZT0yMDI1MDMzMVQyMDM3MTFaJmFtcDtYLUFtei1FeHBpcmVzPTM2MDAmYW1wO1gtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhbXA7eC1pZD1HZXRPYmplY3QKaG9zdDpnby1jbG91ZC10ZXN0aW5nLTIuczMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20KCmhvc3QKVU5TSUdORUQtUEFZTE9BRDwvQ2Fub25pY2FsUmVxdWVzdD48Q2Fub25pY2FsUmVxdWVzdEJ5dGVzPjUwIDU1IDU0IDBhIDJmIDYyIDZjIDZmIDYyIDJkIDY2IDZmIDcyIDJkIDczIDY5IDY3IDZlIDY5IDZlIDY3IDBhIDU4IDJkIDQxIDZkIDdhIDJkIDQxIDZjIDY3IDZmIDcyIDY5IDc0IDY4IDZkIDNkIDQxIDU3IDUzIDM0IDJkIDQ4IDRkIDQxIDQzIDJkIDUzIDQ4IDQxIDMyIDM1IDM2IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQzIDY4IDY1IDYzIDZiIDczIDc1IDZkIDJkIDRkIDZmIDY0IDY1IDNkIDQ1IDRlIDQxIDQyIDRjIDQ1IDQ0IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQzIDcyIDY1IDY0IDY1IDZlIDc0IDY5IDYxIDZjIDNkIDQxIDRiIDQ5IDQxIDU3IDU1IDU3IDQ1IDU1IDUzIDUwIDU1IDRjIDU5IDU4IDMzIDQyIDRjIDMzIDRkIDI1IDMyIDQ2IDMyIDMwIDMyIDM1IDMwIDMzIDMzIDMxIDI1IDMyIDQ2IDc1IDczIDJkIDc3IDY1IDczIDc0IDJkIDMxIDI1IDMyIDQ2IDczIDMzIDI1IDMyIDQ2IDYxIDc3IDczIDM0IDVmIDcyIDY1IDcxIDc1IDY1IDczIDc0IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQ0IDYxIDc0IDY1IDNkIDMyIDMwIDMyIDM1IDMwIDMzIDMzIDMxIDU0IDMyIDMwIDMzIDM3IDMxIDMxIDVhIDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQ1IDc4IDcwIDY5IDcyIDY1IDczIDNkIDMzIDM2IDMwIDMwIDI2IDU4IDJkIDQxIDZkIDdhIDJkIDUzIDY5IDY3IDZlIDY1IDY0IDQ4IDY1IDYxIDY0IDY1IDcyIDczIDNkIDY4IDZmIDczIDc0IDI2IDc4IDJkIDY5IDY0IDNkIDQ3IDY1IDc0IDRmIDYyIDZhIDY1IDYzIDc0IDBhIDY4IDZmIDczIDc0IDNhIDY3IDZmIDJkIDYzIDZjIDZmIDc1IDY0IDJkIDc0IDY1IDczIDc0IDY5IDZlIDY3IDJkIDMyIDJlIDczIDMzIDJlIDc1IDczIDJkIDc3IDY1IDczIDc0IDJkIDMxIDJlIDYxIDZkIDYxIDdhIDZmIDZlIDYxIDc3IDczIDJlIDYzIDZmIDZkIDBhIDBhIDY4IDZmIDczIDc0IDBhIDU1IDRlIDUzIDQ5IDQ3IDRlIDQ1IDQ0IDJkIDUwIDQxIDU5IDRjIDRmIDQxIDQ0PC9DYW5vbmljYWxSZXF1ZXN0Qnl0ZXM+PFJlcXVlc3RJZD5FRU4zUDQ1UE5SREdWUVM1PC9SZXF1ZXN0SWQ+PEhvc3RJZD5yczJDQk1UQ3daZWQvKzE3b1luaVRYb1l2MU50TmZvdmJFanV3RDd5N0VNaFArR2NFZ1puZGFkUGRaQjVBK1VTaGgyRXF2cmlFZTg9PC9Ib3N0SWQ+PC9FcnJvcj4=" + } + }, + { + "ID": "9885928e4a8e72f7", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc64nvme": [ + "jSnVw/bqjr4=" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "8qBHp0jYL7ens/C1DqmZkYWP02UXy9AaA7UVGTvnVmnMVd0193BBGZHWeqGA0Wh1NsVUhIrOIIo=" + ], + "X-Amz-Request-Id": [ + "EEN3QZPZRFG7Q826" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "23af168937e75ee4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "j2kqKX85iF+LcbqEyH3+fpbhOnvN9tXAAxGl0QI28KJYic0lhhQVBSKgGqgaWk3zhVRmovyFF70=" + ], + "X-Amz-Request-Id": [ + "EEN6FPDD78857H1M" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPlNpZ25hdHVyZURvZXNOb3RNYXRjaDwvQ29kZT48TWVzc2FnZT5UaGUgcmVxdWVzdCBzaWduYXR1cmUgd2UgY2FsY3VsYXRlZCBkb2VzIG5vdCBtYXRjaCB0aGUgc2lnbmF0dXJlIHlvdSBwcm92aWRlZC4gQ2hlY2sgeW91ciBrZXkgYW5kIHNpZ25pbmcgbWV0aG9kLjwvTWVzc2FnZT48QVdTQWNjZXNzS2V5SWQ+QUtJQVdVV0VVU1BVTFlYM0JMM008L0FXU0FjY2Vzc0tleUlkPjxTdHJpbmdUb1NpZ24+QVdTNC1ITUFDLVNIQTI1NgoyMDI1MDMzMVQyMDM3MTFaCjIwMjUwMzMxL3VzLXdlc3QtMS9zMy9hd3M0X3JlcXVlc3QKOTNlNjJlNzc5NjIzZWFjYmUyZDE2Zjk1ZWJkZTgxNTZhODVlNjEwNThkYjU0Zjk1ZjFiZWI4MzJiZGViMWFmMzwvU3RyaW5nVG9TaWduPjxTaWduYXR1cmVQcm92aWRlZD45N2YxMzI1NDFmNTBkOGY1ZTFkZDI1ZWI3OWQxMjBhZTc5ZjE5ZDA0MGE0NzUwMGYwZDgxNTJkYTUzZTFlODQxPC9TaWduYXR1cmVQcm92aWRlZD48U3RyaW5nVG9TaWduQnl0ZXM+NDEgNTcgNTMgMzQgMmQgNDggNGQgNDEgNDMgMmQgNTMgNDggNDEgMzIgMzUgMzYgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgNTQgMzIgMzAgMzMgMzcgMzEgMzEgNWEgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgMmYgNzUgNzMgMmQgNzcgNjUgNzMgNzQgMmQgMzEgMmYgNzMgMzMgMmYgNjEgNzcgNzMgMzQgNWYgNzIgNjUgNzEgNzUgNjUgNzMgNzQgMGEgMzkgMzMgNjUgMzYgMzIgNjUgMzcgMzcgMzkgMzYgMzIgMzMgNjUgNjEgNjMgNjIgNjUgMzIgNjQgMzEgMzYgNjYgMzkgMzUgNjUgNjIgNjQgNjUgMzggMzEgMzUgMzYgNjEgMzggMzUgNjUgMzYgMzEgMzAgMzUgMzggNjQgNjIgMzUgMzQgNjYgMzkgMzUgNjYgMzEgNjIgNjUgNjIgMzggMzMgMzIgNjIgNjQgNjUgNjIgMzEgNjEgNjYgMzM8L1N0cmluZ1RvU2lnbkJ5dGVzPjxDYW5vbmljYWxSZXF1ZXN0PkdFVAovYmxvYi1mb3Itc2lnbmluZwpYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZhbXA7WC1BbXotQ3JlZGVudGlhbD1BS0lBV1VXRVVTUFVMWVgzQkwzTSUyRjIwMjUwMzMxJTJGdXMtd2VzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmYW1wO1gtQW16LURhdGU9MjAyNTAzMzFUMjAzNzExWiZhbXA7WC1BbXotRXhwaXJlcz0zNjAwJmFtcDtYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYW1wO3gtaWQ9UHV0T2JqZWN0Cmhvc3Q6Z28tY2xvdWQtdGVzdGluZy0yLnMzLnVzLXdlc3QtMS5hbWF6b25hd3MuY29tCgpob3N0ClVOU0lHTkVELVBBWUxPQUQ8L0Nhbm9uaWNhbFJlcXVlc3Q+PENhbm9uaWNhbFJlcXVlc3RCeXRlcz40NyA0NSA1NCAwYSAyZiA2MiA2YyA2ZiA2MiAyZCA2NiA2ZiA3MiAyZCA3MyA2OSA2NyA2ZSA2OSA2ZSA2NyAwYSA1OCAyZCA0MSA2ZCA3YSAyZCA0MSA2YyA2NyA2ZiA3MiA2OSA3NCA2OCA2ZCAzZCA0MSA1NyA1MyAzNCAyZCA0OCA0ZCA0MSA0MyAyZCA1MyA0OCA0MSAzMiAzNSAzNiAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0MyA3MiA2NSA2NCA2NSA2ZSA3NCA2OSA2MSA2YyAzZCA0MSA0YiA0OSA0MSA1NyA1NSA1NyA0NSA1NSA1MyA1MCA1NSA0YyA1OSA1OCAzMyA0MiA0YyAzMyA0ZCAyNSAzMiA0NiAzMiAzMCAzMiAzNSAzMCAzMyAzMyAzMSAyNSAzMiA0NiA3NSA3MyAyZCA3NyA2NSA3MyA3NCAyZCAzMSAyNSAzMiA0NiA3MyAzMyAyNSAzMiA0NiA2MSA3NyA3MyAzNCA1ZiA3MiA2NSA3MSA3NSA2NSA3MyA3NCAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0NCA2MSA3NCA2NSAzZCAzMiAzMCAzMiAzNSAzMCAzMyAzMyAzMSA1NCAzMiAzMCAzMyAzNyAzMSAzMSA1YSAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0NSA3OCA3MCA2OSA3MiA2NSA3MyAzZCAzMyAzNiAzMCAzMCAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA1MyA2OSA2NyA2ZSA2NSA2NCA0OCA2NSA2MSA2NCA2NSA3MiA3MyAzZCA2OCA2ZiA3MyA3NCAyNiA3OCAyZCA2OSA2NCAzZCA1MCA3NSA3NCA0ZiA2MiA2YSA2NSA2MyA3NCAwYSA2OCA2ZiA3MyA3NCAzYSA2NyA2ZiAyZCA2MyA2YyA2ZiA3NSA2NCAyZCA3NCA2NSA3MyA3NCA2OSA2ZSA2NyAyZCAzMiAyZSA3MyAzMyAyZSA3NSA3MyAyZCA3NyA2NSA3MyA3NCAyZCAzMSAyZSA2MSA2ZCA2MSA3YSA2ZiA2ZSA2MSA3NyA3MyAyZSA2MyA2ZiA2ZCAwYSAwYSA2OCA2ZiA3MyA3NCAwYSA1NSA0ZSA1MyA0OSA0NyA0ZSA0NSA0NCAyZCA1MCA0MSA1OSA0YyA0ZiA0MSA0NDwvQ2Fub25pY2FsUmVxdWVzdEJ5dGVzPjxSZXF1ZXN0SWQ+RUVONkZQREQ3ODg1N0gxTTwvUmVxdWVzdElkPjxIb3N0SWQ+ajJrcUtYODVpRitMY2JxRXlIMytmcGJoT252Tjl0WEFBeEdsMFFJMjhLSllpYzBsaGhRVkJTS2dHcWdhV2szemhWUm1vdnlGRjcwPTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "af78a48cb3fcb7aa", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "UsdhAWF220rl76sDnfo+pM+syt60+rl2kIGzJIWqPyX8zKMeOp2QcsVWAtd72Iu72xFjJlOP5Ak=" + ], + "X-Amz-Request-Id": [ + "EEN6DWY7R85MYQQ0" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPkFjY2Vzc0RlbmllZDwvQ29kZT48TWVzc2FnZT5BY2Nlc3MgRGVuaWVkPC9NZXNzYWdlPjxSZXF1ZXN0SWQ+RUVONkRXWTdSODVNWVFRMDwvUmVxdWVzdElkPjxIb3N0SWQ+VXNkaEFXRjIyMHJsNzZzRG5mbytwTStzeXQ2MCtybDJrSUd6SklXcVB5WDh6S01lT3AyUWNzVldBdGQ3Mkl1NzJ4RmpKbE9QNUFrPTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "382eecfa2f969d76", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "binary/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "K+hbvOPR+JR8yI0CkeM0F89S+LgPVspeqgXj8RhagS2+BfXu94GtemE3rK7MsZmIOOeNlqABYSs=" + ], + "X-Amz-Request-Id": [ + "EENB4Z9Z2PD7P47R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "9273aa0f35cf721a", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9cHGYWAoUd4UtUXA9zJSQcHnUk0F3P2n8FgI5EN4jYgfAFB4IE3Lv8KeNl7G/KJjm0avxb7oP9s=" + ], + "X-Amz-Request-Id": [ + "EENFQKDZRW2GMEWX" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPlNpZ25hdHVyZURvZXNOb3RNYXRjaDwvQ29kZT48TWVzc2FnZT5UaGUgcmVxdWVzdCBzaWduYXR1cmUgd2UgY2FsY3VsYXRlZCBkb2VzIG5vdCBtYXRjaCB0aGUgc2lnbmF0dXJlIHlvdSBwcm92aWRlZC4gQ2hlY2sgeW91ciBrZXkgYW5kIHNpZ25pbmcgbWV0aG9kLjwvTWVzc2FnZT48QVdTQWNjZXNzS2V5SWQ+QUtJQVdVV0VVU1BVTFlYM0JMM008L0FXU0FjY2Vzc0tleUlkPjxTdHJpbmdUb1NpZ24+QVdTNC1ITUFDLVNIQTI1NgoyMDI1MDMzMVQyMDM3MTFaCjIwMjUwMzMxL3VzLXdlc3QtMS9zMy9hd3M0X3JlcXVlc3QKMjUxNmE4ZDAyYmRlZWE2MjBmOGQwMTkwYmJmYjFhODQ3Y2UyNmZiZWFhOTZmOWYwMTMyMDU5ZmM0M2RhZWU4ODwvU3RyaW5nVG9TaWduPjxTaWduYXR1cmVQcm92aWRlZD4xYTZjMjQ1MGUzOGQyZjZkZjg0YTMxZWUzYjE4NjYyMzhhZDRkZTMzODJjZWQxODljZDc3MmZlZjMyNWJjOThmPC9TaWduYXR1cmVQcm92aWRlZD48U3RyaW5nVG9TaWduQnl0ZXM+NDEgNTcgNTMgMzQgMmQgNDggNGQgNDEgNDMgMmQgNTMgNDggNDEgMzIgMzUgMzYgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgNTQgMzIgMzAgMzMgMzcgMzEgMzEgNWEgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgMmYgNzUgNzMgMmQgNzcgNjUgNzMgNzQgMmQgMzEgMmYgNzMgMzMgMmYgNjEgNzcgNzMgMzQgNWYgNzIgNjUgNzEgNzUgNjUgNzMgNzQgMGEgMzIgMzUgMzEgMzYgNjEgMzggNjQgMzAgMzIgNjIgNjQgNjUgNjUgNjEgMzYgMzIgMzAgNjYgMzggNjQgMzAgMzEgMzkgMzAgNjIgNjIgNjYgNjIgMzEgNjEgMzggMzQgMzcgNjMgNjUgMzIgMzYgNjYgNjIgNjUgNjEgNjEgMzkgMzYgNjYgMzkgNjYgMzAgMzEgMzMgMzIgMzAgMzUgMzkgNjYgNjMgMzQgMzMgNjQgNjEgNjUgNjUgMzggMzg8L1N0cmluZ1RvU2lnbkJ5dGVzPjxDYW5vbmljYWxSZXF1ZXN0PkRFTEVURQovYmxvYi1mb3Itc2lnbmluZwpYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZhbXA7WC1BbXotQ2hlY2tzdW0tTW9kZT1FTkFCTEVEJmFtcDtYLUFtei1DcmVkZW50aWFsPUFLSUFXVVdFVVNQVUxZWDNCTDNNJTJGMjAyNTAzMzElMkZ1cy13ZXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZhbXA7WC1BbXotRGF0ZT0yMDI1MDMzMVQyMDM3MTFaJmFtcDtYLUFtei1FeHBpcmVzPTM2MDAmYW1wO1gtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhbXA7eC1pZD1HZXRPYmplY3QKaG9zdDpnby1jbG91ZC10ZXN0aW5nLTIuczMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20KCmhvc3QKVU5TSUdORUQtUEFZTE9BRDwvQ2Fub25pY2FsUmVxdWVzdD48Q2Fub25pY2FsUmVxdWVzdEJ5dGVzPjQ0IDQ1IDRjIDQ1IDU0IDQ1IDBhIDJmIDYyIDZjIDZmIDYyIDJkIDY2IDZmIDcyIDJkIDczIDY5IDY3IDZlIDY5IDZlIDY3IDBhIDU4IDJkIDQxIDZkIDdhIDJkIDQxIDZjIDY3IDZmIDcyIDY5IDc0IDY4IDZkIDNkIDQxIDU3IDUzIDM0IDJkIDQ4IDRkIDQxIDQzIDJkIDUzIDQ4IDQxIDMyIDM1IDM2IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQzIDY4IDY1IDYzIDZiIDczIDc1IDZkIDJkIDRkIDZmIDY0IDY1IDNkIDQ1IDRlIDQxIDQyIDRjIDQ1IDQ0IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQzIDcyIDY1IDY0IDY1IDZlIDc0IDY5IDYxIDZjIDNkIDQxIDRiIDQ5IDQxIDU3IDU1IDU3IDQ1IDU1IDUzIDUwIDU1IDRjIDU5IDU4IDMzIDQyIDRjIDMzIDRkIDI1IDMyIDQ2IDMyIDMwIDMyIDM1IDMwIDMzIDMzIDMxIDI1IDMyIDQ2IDc1IDczIDJkIDc3IDY1IDczIDc0IDJkIDMxIDI1IDMyIDQ2IDczIDMzIDI1IDMyIDQ2IDYxIDc3IDczIDM0IDVmIDcyIDY1IDcxIDc1IDY1IDczIDc0IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQ0IDYxIDc0IDY1IDNkIDMyIDMwIDMyIDM1IDMwIDMzIDMzIDMxIDU0IDMyIDMwIDMzIDM3IDMxIDMxIDVhIDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQ1IDc4IDcwIDY5IDcyIDY1IDczIDNkIDMzIDM2IDMwIDMwIDI2IDU4IDJkIDQxIDZkIDdhIDJkIDUzIDY5IDY3IDZlIDY1IDY0IDQ4IDY1IDYxIDY0IDY1IDcyIDczIDNkIDY4IDZmIDczIDc0IDI2IDc4IDJkIDY5IDY0IDNkIDQ3IDY1IDc0IDRmIDYyIDZhIDY1IDYzIDc0IDBhIDY4IDZmIDczIDc0IDNhIDY3IDZmIDJkIDYzIDZjIDZmIDc1IDY0IDJkIDc0IDY1IDczIDc0IDY5IDZlIDY3IDJkIDMyIDJlIDczIDMzIDJlIDc1IDczIDJkIDc3IDY1IDczIDc0IDJkIDMxIDJlIDYxIDZkIDYxIDdhIDZmIDZlIDYxIDc3IDczIDJlIDYzIDZmIDZkIDBhIDBhIDY4IDZmIDczIDc0IDBhIDU1IDRlIDUzIDQ5IDQ3IDRlIDQ1IDQ0IDJkIDUwIDQxIDU5IDRjIDRmIDQxIDQ0PC9DYW5vbmljYWxSZXF1ZXN0Qnl0ZXM+PFJlcXVlc3RJZD5FRU5GUUtEWlJXMkdNRVdYPC9SZXF1ZXN0SWQ+PEhvc3RJZD45Y0hHWVdBb1VkNFV0VVhBOXpKU1FjSG5VazBGM1AybjhGZ0k1RU40allnZkFGQjRJRTNMdjhLZU5sN0cvS0pqbTBhdnhiN29QOXM9PC9Ib3N0SWQ+PC9FcnJvcj4=" + } + }, + { + "ID": "826897ec8f2568b0", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:11 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "wjQUm/ssHEwjE/n0Ywt5cltxKpzmcJmz2ZfJ9MVo1LOr7NJaVYg/9+QBcAwsQp+yCIuAP2vfD+Q=" + ], + "X-Amz-Request-Id": [ + "EEN98R031QH33D4R" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPlNpZ25hdHVyZURvZXNOb3RNYXRjaDwvQ29kZT48TWVzc2FnZT5UaGUgcmVxdWVzdCBzaWduYXR1cmUgd2UgY2FsY3VsYXRlZCBkb2VzIG5vdCBtYXRjaCB0aGUgc2lnbmF0dXJlIHlvdSBwcm92aWRlZC4gQ2hlY2sgeW91ciBrZXkgYW5kIHNpZ25pbmcgbWV0aG9kLjwvTWVzc2FnZT48QVdTQWNjZXNzS2V5SWQ+QUtJQVdVV0VVU1BVTFlYM0JMM008L0FXU0FjY2Vzc0tleUlkPjxTdHJpbmdUb1NpZ24+QVdTNC1ITUFDLVNIQTI1NgoyMDI1MDMzMVQyMDM3MTFaCjIwMjUwMzMxL3VzLXdlc3QtMS9zMy9hd3M0X3JlcXVlc3QKMjY2MzU1NWU2NmQwYjE3ZjNhZDdhZjA2Mzc2ODEyMzAwZjliOGIzMDljYjVkMTZlODhkYjc3NWI5YTJhYjRiMjwvU3RyaW5nVG9TaWduPjxTaWduYXR1cmVQcm92aWRlZD45N2YxMzI1NDFmNTBkOGY1ZTFkZDI1ZWI3OWQxMjBhZTc5ZjE5ZDA0MGE0NzUwMGYwZDgxNTJkYTUzZTFlODQxPC9TaWduYXR1cmVQcm92aWRlZD48U3RyaW5nVG9TaWduQnl0ZXM+NDEgNTcgNTMgMzQgMmQgNDggNGQgNDEgNDMgMmQgNTMgNDggNDEgMzIgMzUgMzYgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgNTQgMzIgMzAgMzMgMzcgMzEgMzEgNWEgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgMmYgNzUgNzMgMmQgNzcgNjUgNzMgNzQgMmQgMzEgMmYgNzMgMzMgMmYgNjEgNzcgNzMgMzQgNWYgNzIgNjUgNzEgNzUgNjUgNzMgNzQgMGEgMzIgMzYgMzYgMzMgMzUgMzUgMzUgNjUgMzYgMzYgNjQgMzAgNjIgMzEgMzcgNjYgMzMgNjEgNjQgMzcgNjEgNjYgMzAgMzYgMzMgMzcgMzYgMzggMzEgMzIgMzMgMzAgMzAgNjYgMzkgNjIgMzggNjIgMzMgMzAgMzkgNjMgNjIgMzUgNjQgMzEgMzYgNjUgMzggMzggNjQgNjIgMzcgMzcgMzUgNjIgMzkgNjEgMzIgNjEgNjIgMzQgNjIgMzI8L1N0cmluZ1RvU2lnbkJ5dGVzPjxDYW5vbmljYWxSZXF1ZXN0PkRFTEVURQovYmxvYi1mb3Itc2lnbmluZwpYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZhbXA7WC1BbXotQ3JlZGVudGlhbD1BS0lBV1VXRVVTUFVMWVgzQkwzTSUyRjIwMjUwMzMxJTJGdXMtd2VzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmYW1wO1gtQW16LURhdGU9MjAyNTAzMzFUMjAzNzExWiZhbXA7WC1BbXotRXhwaXJlcz0zNjAwJmFtcDtYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYW1wO3gtaWQ9UHV0T2JqZWN0Cmhvc3Q6Z28tY2xvdWQtdGVzdGluZy0yLnMzLnVzLXdlc3QtMS5hbWF6b25hd3MuY29tCgpob3N0ClVOU0lHTkVELVBBWUxPQUQ8L0Nhbm9uaWNhbFJlcXVlc3Q+PENhbm9uaWNhbFJlcXVlc3RCeXRlcz40NCA0NSA0YyA0NSA1NCA0NSAwYSAyZiA2MiA2YyA2ZiA2MiAyZCA2NiA2ZiA3MiAyZCA3MyA2OSA2NyA2ZSA2OSA2ZSA2NyAwYSA1OCAyZCA0MSA2ZCA3YSAyZCA0MSA2YyA2NyA2ZiA3MiA2OSA3NCA2OCA2ZCAzZCA0MSA1NyA1MyAzNCAyZCA0OCA0ZCA0MSA0MyAyZCA1MyA0OCA0MSAzMiAzNSAzNiAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0MyA3MiA2NSA2NCA2NSA2ZSA3NCA2OSA2MSA2YyAzZCA0MSA0YiA0OSA0MSA1NyA1NSA1NyA0NSA1NSA1MyA1MCA1NSA0YyA1OSA1OCAzMyA0MiA0YyAzMyA0ZCAyNSAzMiA0NiAzMiAzMCAzMiAzNSAzMCAzMyAzMyAzMSAyNSAzMiA0NiA3NSA3MyAyZCA3NyA2NSA3MyA3NCAyZCAzMSAyNSAzMiA0NiA3MyAzMyAyNSAzMiA0NiA2MSA3NyA3MyAzNCA1ZiA3MiA2NSA3MSA3NSA2NSA3MyA3NCAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0NCA2MSA3NCA2NSAzZCAzMiAzMCAzMiAzNSAzMCAzMyAzMyAzMSA1NCAzMiAzMCAzMyAzNyAzMSAzMSA1YSAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0NSA3OCA3MCA2OSA3MiA2NSA3MyAzZCAzMyAzNiAzMCAzMCAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA1MyA2OSA2NyA2ZSA2NSA2NCA0OCA2NSA2MSA2NCA2NSA3MiA3MyAzZCA2OCA2ZiA3MyA3NCAyNiA3OCAyZCA2OSA2NCAzZCA1MCA3NSA3NCA0ZiA2MiA2YSA2NSA2MyA3NCAwYSA2OCA2ZiA3MyA3NCAzYSA2NyA2ZiAyZCA2MyA2YyA2ZiA3NSA2NCAyZCA3NCA2NSA3MyA3NCA2OSA2ZSA2NyAyZCAzMiAyZSA3MyAzMyAyZSA3NSA3MyAyZCA3NyA2NSA3MyA3NCAyZCAzMSAyZSA2MSA2ZCA2MSA3YSA2ZiA2ZSA2MSA3NyA3MyAyZSA2MyA2ZiA2ZCAwYSAwYSA2OCA2ZiA3MyA3NCAwYSA1NSA0ZSA1MyA0OSA0NyA0ZSA0NSA0NCAyZCA1MCA0MSA1OSA0YyA0ZiA0MSA0NDwvQ2Fub25pY2FsUmVxdWVzdEJ5dGVzPjxSZXF1ZXN0SWQ+RUVOOThSMDMxUUgzM0Q0UjwvUmVxdWVzdElkPjxIb3N0SWQ+d2pRVW0vc3NIRXdqRS9uMFl3dDVjbHR4S3B6bWNKbXoyWmZKOU1WbzFMT3I3TkphVllnLzkrUUJjQXdzUXAreUNJdUFQMnZmRCtRPTwvSG9zdElkPjwvRXJyb3I+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestUploadDownload.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestUploadDownload.replay new file mode 100644 index 000000000..f7beab6fc --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestUploadDownload.replay @@ -0,0 +1,464 @@ +{ + "Initial": "AQAAAA7ffPPuCBz/iwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "2042819ad5e86e41", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text", + "BodyParts": [ + "Yg0KdXAgYW5kIGRvd24NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk9KM3lsQT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OJ3ylA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "HGZ/szi3Z7n3660dA2yhnYixiM+tOAIGb1rLmIWdTpg03Bh1QGf8LkOJSLxtBhG58xqxJzD9ArPlaNxLgyDD4g==" + ], + "X-Amz-Request-Id": [ + "NXJ87DNJK69V89EX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "19c3ac8defd9abf1", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OJ3ylA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "fWFsDwAk4fz2/6zjBe00WPDu2h1s1i/v82sB+KGDknd9XDCAqpWAutGyHRJ0643BE8RR6mFJnfVz/kTex2mOyQ==" + ], + "X-Amz-Request-Id": [ + "NXJ0FBDXNSFKKDXV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "dXAgYW5kIGRvd24=" + } + }, + { + "ID": "f39ee4045a9e49a9", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "G3VTPtWoaf9vOuAzbQwzIA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text", + "BodyParts": [ + "Yg0KdXAgYW5kIGRvd24NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk9KM3lsQT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OJ3ylA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "AMfXUkdiVy1zhXNVLUHX2tdp2241B9LJZDGX7pEBl/sxCM24883j6TUDv5RJkJsD5deSQ5r6E8ipkyvNxpD8RQ==" + ], + "X-Amz-Request-Id": [ + "NXJEWBJTFNPDAS59" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "f1a44d3da44aa277", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "f3ZgKBL9uZuzA4ZZOklSerXkGRy5QHysDxi+j/sXAkGvIzBefM/r5k4pfmgNNWnQHPRm/LrVm4oSsDK0FDuoeQ==" + ], + "X-Amz-Request-Id": [ + "NXJ1R16ZD8F7H5AH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "85fa67cdd94846c0", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:03 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "B9e9GTq2uOuImdoY/JKFTqP/Pg6T7QY7bNj87IIbke4NGUIuCOOBEw1dbxK0YbPWWh7M978UhWzsZG2fxJeC4A==" + ], + "X-Amz-Request-Id": [ + "NXJEX2ATXYB01Y0Q" + ] + }, + "Body": "" + } + }, + { + "ID": "0a4ad6d4f773c2cb", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:02 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "FT1LXj3PRJKbfZH0kqsWDg2BKflvQE/rlJarhyCNgdKvBNJiX/BIOOuq1bSHChoIetKKNm2PYmo9nJbnCTSYbA==" + ], + "X-Amz-Request-Id": [ + "NXJAJF2KFEABZE55" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/ContentType_is_discovered_if_not_provided.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/ContentType_is_discovered_if_not_provided.replay new file mode 100644 index 000000000..968118dcb --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/ContentType_is_discovered_if_not_provided.replay @@ -0,0 +1,397 @@ +{ + "Initial": "AQAAAA7ffPPqBeS+OQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "5e52e6b301372f5c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "6398" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "6354" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/html", + "BodyParts": [ + "MThkMg0KPCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+DQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjplQ01DcWc9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "s/gsQ1j7Glnd2U2liysl7V3SdRslvGpzxcqCbMhLUpAV/R4jrqinZyDg8yCPRz0aW43d9JZtFzE=" + ], + "X-Amz-Request-Id": [ + "2033M24EM2B8FWVW" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c016f59f25b5ae71", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "text/html; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "4ApAT8G7cd5Ik23ToOlGwC1XprS/9MELHxZXs7gX0MXg7kMttWCvHw0ILhgNgL2izE8YaC4ev34=" + ], + "X-Amz-Request-Id": [ + "203F20RSJ2KQHHVK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "66f2ac24dccfd924", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "text/html; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "yMYXQKPxZgrBwQhR+HS8rd22iWhRdWILktkKFi+lPOc9S5uHw0VzjPfWwTuN5FCtXbrx6/kjSmk=" + ], + "X-Amz-Request-Id": [ + "2030RACVNASG9WJ7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "61586fa7e3e19961", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "text/html; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "FbOXYOvxOZxNKdsxR2T70Q3kS9xC4acpZlvmpEd56/pWQa/FQ2nrLT4t3GJqAy1qARtaNny3pro=" + ], + "X-Amz-Request-Id": [ + "203BZ1511SJG1CQQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6967d2f477f4a373", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "0a3KEqDy3/QHKW+ZMkNbKeC8wJmPmZBIad3II3ZD+83EQHUBXWHkF9mONweqaA2gK1dVzVSgx9Y=" + ], + "X-Amz-Request-Id": [ + "203AFYMJS0NTHGXE" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay new file mode 100644 index 000000000..7e3faa8aa --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay @@ -0,0 +1,327 @@ +{ + "Initial": "AQAAAA7ffPPqE7HZDAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "d580c67b7f8cb1bc", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "6398" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "6354" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "", + "BodyParts": [ + "MThkMg0KPCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+DQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjplQ01DcWc9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "w6UmiFtJ1a8kBur01tbpsmzmzl44BVUgGzlSBf3CF6vjE74d3YGvh1e3T9CT6jEHJ/swOJBWUmnYQkH561geFw==" + ], + "X-Amz-Request-Id": [ + "2033KQ34SYDA87RK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a70ada4f168e4900", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "cUC3vFa9/tOMq2eUgtunq1VJRMsNe/07gPg4XaVytGPRyS0QSeB4ik/l5Qro0gl4DlpMprgK0JLeG8zS9J+JXQ==" + ], + "X-Amz-Request-Id": [ + "2038SENPG2P4VQAY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "199c11b2197b650c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "nisb3Eo9lZND+6Sl9N81Aql4JZuXy7w7NHmo8U8KJRBy53En8Mr6iVqmMt+l5g0U0/KdPBrRUVGwz6+DF0WykA==" + ], + "X-Amz-Request-Id": [ + "2039K9CREWD330WM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0f5213e16bc4a066", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "sdgF3FZdeY0dEeMz6oa82I+ykGc2PTwxqzw3ma0+wUm4Wf87pkA0uYbUMFKfpwubC/JXMNUW9mcwERkGycKO7g==" + ], + "X-Amz-Request-Id": [ + "2032Y3QY2J5VS6C0" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/Content_md5_did_not_match,_blob_existed.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/Content_md5_did_not_match,_blob_existed.replay new file mode 100644 index 000000000..d334c3740 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/Content_md5_did_not_match,_blob_existed.replay @@ -0,0 +1,330 @@ +{ + "Initial": "AQAAAA7ffPPrBpNr7gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "6a9120d6bdc17e05", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "58" + ], + "Content-Md5": [ + "dH9B/ScP7BuCvgMMwc1IAQ==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "16" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTANCmV4aXN0aW5nIGNvbnRlbnQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOkl1VXExUT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"747f41fd270fec1b82be030cc1cd4801\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "IuUq1Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "MqeeK1/e1v1bsaU812hrEuu0FpJVAnVBG8HBHnOkIQ+hQ6Dvqpcljwe1K7xTjt08h6ShQ5qRxV5LwdP44wVUzaFUZ2siOYMO9F4kqow/Ah4=" + ], + "X-Amz-Request-Id": [ + "D61TME9XRZW1T4Y3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6a915f74f27c9ce3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "16" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"747f41fd270fec1b82be030cc1cd4801\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "IuUq1Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "mc7/fXODi+TubHXgb2IsoZlls4lE6Bc1ymOYUl1qOaYmQV6ud/Fvjq9BE+l+oKhL20gjHfKqfH4VSLrnZPxVogYqLl8qHm/Tr4FP1juqW9s=" + ], + "X-Amz-Request-Id": [ + "D61G12EXQAPBTR2R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "ZXhpc3RpbmcgY29udGVudA==" + } + }, + { + "ID": "28786ed9cae185f5", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "16" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"747f41fd270fec1b82be030cc1cd4801\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "d+3Tz9Ol1nIG6VxzO1YhDhOujHq3qI7QhnQvYuzx83jgg/AyP4N9bdLx/IcNXyDE+FGtYjFo2ItaF5jO5rEkEpi/gFxxjKEujVW9n9SSTno=" + ], + "X-Amz-Request-Id": [ + "D61VN9TN14YASZCJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7831e7c7f8367e35", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "kUgV/d1HVxXOaL2Ili2xKLOYL7+IH2bgdmXpe4eIv4zCRPYInPI1y38XUv2PvxeIYNVSoPv4Pa56q6CRQJxzVQI1ty/T4M/gh1qbxPfNOQI=" + ], + "X-Amz-Request-Id": [ + "D61YXG35100TEV6B" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/Content_md5_did_not_match.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/Content_md5_did_not_match.replay new file mode 100644 index 000000000..3b500bbac --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/Content_md5_did_not_match.replay @@ -0,0 +1,105 @@ +{ + "Initial": "AQAAAA7ffPPrAfakBwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "5308a62687e139c7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ShRFIbw3jqVjruH6xV0cgHXyiSM/uxk+nimlqR0AQM/aBDPP45F5S3iVRM52huiuRMtpviyyiILtbj/dWs9HnQ==" + ], + "X-Amz-Request-Id": [ + "D61HRHA4X3EYBS5S" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1yZWFkaW5nPC9LZXk+PFJlcXVlc3RJZD5ENjFIUkhBNFgzRVlCUzVTPC9SZXF1ZXN0SWQ+PEhvc3RJZD5TaFJGSWJ3M2pxVmpydUg2eFYwY2dIWHlpU00vdXhrK25pbWxxUjBBUU0vYUJEUFA0NUY1UzNpVlJNNTJodWl1Uk10cHZpeXlpSUx0YmovZFdzOUhuUT09PC9Ib3N0SWQ+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/Content_md5_match.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/Content_md5_match.replay new file mode 100644 index 000000000..9fcd52550 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/Content_md5_match.replay @@ -0,0 +1,330 @@ +{ + "Initial": "AQAAAA7ffPPqK9zAqgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "3e60d3c8f2999d82", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KaGVsbG8gd29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOkRVb1JoUT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Q+b6i3AGygBT7ICJ3CXhyEsJwRlJvOPq5tcZQpT91YVoNV7c//CgQ6DVA5dFpzkj8aKcnxFlNloBuPzqnix2yQ==" + ], + "X-Amz-Request-Id": [ + "20341SSAJQ3GH112" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "674807fa9714c7ab", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "NScPxTV67mc4D9yVeQwgJwE1z1RZmk1vggQoxHdRgEEbcMQoH43jGJRg5r3A7xy2EtU5Nulwc8zF0FT6XHXv/w==" + ], + "X-Amz-Request-Id": [ + "203ECM9EPTR0V9FS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "b8fbdbd67a192e24", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Iu+5ugBjVkMKjInt/fAPeet110uYafZeocvKhEC8WGDs0/16VFO3hf8wP2i51pdr8hg6zHUMDHDJAfgYoHJOAQ==" + ], + "X-Amz-Request-Id": [ + "203DAFZJXHEPGDAG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "f567974b8f4a8490", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "lni+KwZrZ7nRB1bm4FWHE8Yrl+o5A75xUiWgnCPk1e5Fp9sibhW8quV2XKJn4dEbGX1bntN4D6Q2SE+WhqO83Q==" + ], + "X-Amz-Request-Id": [ + "20325EZJ0Q832SKC" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/a_large_jpg_file_gets_a_ContentType.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/a_large_jpg_file_gets_a_ContentType.replay new file mode 100644 index 000000000..08edcefe9 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/a_large_jpg_file_gets_a_ContentType.replay @@ -0,0 +1,397 @@ +{ + "Initial": "AQAAAA7ffPPrIC8aUAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "4cae39fab8c151df", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "38474" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "38430" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "image/jpeg", + "BodyParts": [ + "OTYxZQ0K/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAH0A+gDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigAooooAKKKKACiiigAooooAKKDRzQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFMkkSJS7sFUdSTQA+iq/wBth3Fd65xnGamV1YZByKAHUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAAGBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFNd1QEsQAOpNADqKwr3xhoVg+y41O2jbjgyDv0qXSfE+ka2hfT76GcA7TtbkH6UAbFFICD0NLQAUUUUAFFGRRQAUUmaTcPWgB1FN3j1FKWA7igAZgqknoK8H+InjWbVNZfSLB7zCtsWOA43sD349vf8ACvV/Getx6H4Wvb9tx2R4G3sTwDXm3wm8OQS2cmuXRWe6uJGdXcElBnpzQBg23w/8ZzWx1VdRe2ugQ8VqJTwPQt612HgDx3qt/q02haxAqXlumWIBBbnuO3avTFjQRYwOBXjscsQ+O935TNkxBWA4Gdo6468etAHtkbbkBp9RQf6sfSpaACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAzzRRRQAUUUhIHU0ALRTd6+op2QaACiiigAooooAKKKSgBaKKKACiiigAooooAKKKKACkzzS0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAjHCk+leGfFLx1Lcu+jaeWVt+C5yuSO3PHPrXtWoXAtrCaYnARCa+f/CsVpr/AMTrm4kh27GJH/TQjvQBteDPhLb3lrDqOuhppZIx+5YkY5zzg81ual8Jbe0/03wzdy6bfpkptfcjcdDnJ/KvTII0hhAHAAqG21S0unZIpkZkOGAPSgDzjw58R7iz1FNC8URi11PzCgbGFcdiPY9K9PhuEmQMjAgjNeY/GDwuuraL/adoyx31mCwbpuTuMiuK0r4u3dn4dWK2t/PvEUKzHO1T0+tAH0M0iqMkiqN7rVhYQmS5uooVHJLuAAK8bt9b8b+I51tSk1sHhwxQfu8nnduAz07Z61sxfDDU7u1SS91udpjy6uisufUZHB/GgDrbvx5pdtG0yTfaI1++0QyE6dfzFY//AAtrRxbzvtuGkjJxEqZLc4GCOOfrUtn8KdFifzLjzbgk5Ikbg57YHaujtPB+iWciywWECSKMbggzigDz+/8AjEpkENhp879N7MCpXjJ4I7fWs+38ZeM9TZpNP064G9SYy8W5Poc4A7cjNewLo1gq4FrCBnOAg61Zjto4wAqKAOmBQB5E918S4oTO0NvgA5QqWJ54IA6fmaW3uPiUbIl4UM8pUpkj5Fzzn3wf0r2DYuMYFARR2FAHjEuieP8AVdMeO+lhk8zG23lVQFI65I/+vUdnYfELSVjgiht4oUXhLeNNuc/d59QeuO1e17B6UFAe1AHkJ1P4kral5LW3B3bQvl7mJ9eD07Dp71xOneIbnS/HtzfavpzQXHypcm35AY45Oe2PSvpQxqR0FUP7HsvPkmFvGJJDl22DLfWgDldD+JWg6mgCzvC27afPQqAc9CwyM/jXaQXUU6bkdWHqDmuO8Q/DTStaVmiZ7Nnbe4twArtggMR689f8K4dPCPjvwlqAbR7yXUbJWBWIyhV285BDd/cUAe35FLXmWj/FKKG6+xeI7cabMuMlycZ98jjPNei2l9b30KTW0qyRsMqynINAFiiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACkJAHNDMFUk14/8Svik2ku+j6Q2b8nYxGcqT6Y70AdX4z+I+l+E0WJmE94+QkKHOD746V5i+vfEfxvI0mnIdOt1YDumee2eTWt4E+Hd3qdxFrPibdNPnekbnOOc5P8AhXssNjDCiqiABemBQB4LeeGPiNpdp9rbV5rnaQzJFKxbaBzycelbPgv4k6hFd29lrMwlE+7bIy4KlTjHGc+tezmNSuCARXm/xA8HW0Wh3OraVFFb3to5vC2OHI5bd+FAHpEUgkjV1OQRmn1zHgjXBrfh2zuiyF3jBYIcgHvXT0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUCigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDm/HAu/8AhGLr7Jy+35lClsr36V4F4V1P+yvHscqPuieQq+8EHBPvX09KgkQowyCMGvCvif4Hk066XW9LgJgiO6ZUYIUHc5oA9vgkE1sD1BFeF+LdS1Dwd4s8+CSRoZpCxYrhR7H1r0jwf4lh1Tw/bzLICdoUgsD04NR+JfCFr4ihfdEjyEEpuJ2nPrigCDw74ms/F2nK6uCRw6MO/wBK85tLaDwf8UrnT57Um01Ah4eBjJI7exroPCngHWfC3irfAXksHHzlnGB9PU/hXoeueD9M8Q/ZpL2FvPt23wzRsVdD7EUAatlbxrEpRQBjjAq6BUdtCIIEjBJCgDJ6mpaACiiigAooooAKKKKACiiigAooooAKTaKWigDmPFnhKz1+xYmygmukH7vzRgH2J9K8ut18VfDAtcmyku9IL5ljik3LCM9VHX8694qOWFJkKOoKngg0AYnhrxXpvifTY72wuFkVuGXoynuCOxrf615l4h+H13pt1Jrng2b7Dfg7pLVR+5n9iOgPvT/C/wAUoL27Ok65bHS9WiKpJDKRhiRxtNAHpVFRxyrIqkHORUlABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRVa/keOxnaLmURsUGcZOOOaAPNfix4/Gh6c+l6dMpv5/kyhyUB6/Q1zfw5+Hvk3S6xrDia4kXKIQSFzzk5715idahtvFM97rllNc3CSNiLO75857mtS/8AiP4k1W+SbSEmtYYQFjRTlQfU9j+NAH1NbNFHGFUjgVP5qk4Br5k0i6+J2syzPb3txFIcYUqFTBHXNbF/YfEnwzbNrl7rxniiw0sSMSAM+mAMc0AfQqnNRXltFd2c1vMu6KVCjqe4IwRWT4T1pdd8P2t9n5pE+b69622+6aAPHfhQyaTr+r6MVdHimb5cgrgMRwevQDrXsleFWVw9l8b9SSGDejNyzM3yBgDkDpyT+le4RSB0BHTFAEtFFFABRRRQAUUUUAFFFFABSb1zjIzXGePfHEXhayEEGJNQnGIowRkZ4Bx1PPavJp7nxvcvJqckOooWVZPMVDwvU4xyOO2B0oA+jcg0V4l4d+KN3pl3Fb6zPFd2Uj7Eu425QcD5hjOM8ZNeyWV/b39vHPbyrJG43KVOcigCzRRRQAUUUUAFFFFABQM45oooAKKKKACiijFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFACMcKTXkvxX8cPpsf9iWNsZ7q4jOcgNt/4Dg5rr/GfjO28Lae0hTz7huEhVwGOe/Nee/D7wzceINduvFOsRyM0r/6OJjk7fXGPyxQBw2gp4m8Hz2zzwsIZz54DcKOuVx2r6D8Oa7bavYQTxkB3UNs3AkfXFR+KPCNt4j0OWwfZG5H7qUpkxt6iub8HfDm88MysTdpIdy/OAQWUHoc0AekqB1xwafSKMACloAKKKKACiiigAprNtHNQXN5DbRs8jgBQTXk/ib4nHzZLPSZvtN0GwIYoWLNg84PT/P4UAeszXkNuheWRVAGck4rIu/FemWgQyXMY3HH3xgcZ5ryo6J498TuiNs0q0YjIaUvJj/P0rorH4M6SrmW/uru9Z1AkE0nBPqMcigDoJviT4bhKhtTg2scAq2f5fStey8UaTfQiWC+hlQ91auePwm8KnP/ABLEyV2n526enWqFz8GNAaN0s3u7TcAMxTH8+c0Ad/FqdrM5RJkZ1ALKGyRmrSyK3Qg14xqnwl8QQSxz6T4ou96YUGWRgQmOmRwfyrNtPGPi/wAATxw+KIzdWJcr5wIZwBnBOPXjrQB73RWFoXifTtds457KdZFYZ6YrcBB6UALRRRQAhFcJ49+Hdl4rtvtEP+j6nD80M6Hbkjs3qK7ykIzQB5R4E8Z3sOoyeGPEMMkGp254ZyMSDtg9+Oc16Y+o2kKAyzxp0HzMBzXnvxb8L3F5ow1zSJHh1PTyZQ0fV1A5B+grzz4e+H38d2klze63dvMshEyMxJz26nGPwoA9guviV4dtZpInumby+rJEzL+YFRzfE/w5FKsYuJZCcZ8uJm2k9jgdam0L4f6Nom54YmllY5LytuPTFaR8JaOZXm+wwiRyCzBcE4II/kKADRvFuk65G72dyGCMVIYFTkdeDWzHPFKMo6kH0NcNq3wt0W6gdrKN7O5bJEsUjDJPrz0rjLHwd448Jy3UtnqsdxCpXyoSSxcDtg8LQB7gKK8x0T4pQrNFYa7by2V8ZPJIdMBnx25OByOtekwXEdxGHjYEHmgCWiiigAooooAKKKKACop4EnQqyg5GOalooA4w/D3QU1c3rWELvJnJdQ3P49K37fRbC0j2Q20SKOgVQBVy9uBbWrykZCjNeHax8ZNdu76Wy0DSVkkRmBcqzAAH0GKAPZha28N0SgVc8kCuU+JGrWVn4N1SNp4RNJAyohkClieOK4C3n+J/iLT3hZ1t1n+UyeRtKg475+tOh+Ceu6iqHWvEUsgUAbFLNx+JoAr/AAv8fW+neGja3swQ20nVmABB5rvY/i74edMO86ZztYxHDfTFZGkfArSLOM/apnncjjtiuug+G/huGFY/7LtzjqdnJ/GgD551/wAW3f8Awnd/renxXAjlOFDcE4AwenT2r0X4ffFu8vNTTSfEVutrLJgRSlSgY+hB716oPCejKBixiyvQlc15x8Z9MtLfw/aXcapFcRXAMbKBu6HPHftQB7DG4kQOpyD0p1c74L1JdT8M2M6ur7ohyvTI4NdFQAUUUUAFFFFABRRQelAHhHjRbfVPi5psMkhZVlAIC4K7e3X1HoK9straMQKAoxivEviXbxaX8QLK+l3ojyK4kCA7TkdDn869ig1W2h0xLiWZFiCbixPbGaAMzXPAWga4h+1WSh+MPESjDGccj6mvJdO1zUvhd4wk0vVJrm40eXLRyMdwRScAj+tdzqXxp8KWbvGLiWR1BxsjPzEehryHxr42/wCEs1azbStMupkjyNkiEs+e3HbvQB9M6Xq9pq1lHdWkySxSKCrKcgiru9c4yM18ueHrr4hWmbDR7C6tY2zKUlQquTzwx/lXXaXp/wATpA1zdPtfj5GlGT/hQB7o0iKOWA+ppv2mHOPNTJ7bhXicvhrx9NObi9kNwrc7DKCI/YAde361Wm8MeLZFP+hlkzgMu4MuAexP+c0Ae7+bGf41/OnBgehFeFjSPFltNvlhvmhUqMRTMMdOncioodZ8RaYRFNdarHwSEADgEDOORn8M96APeqK8LtPilrxkSGYwCQrv2zRMm0e/ua6nTfig77Beaa7DgGS2bzByM5xjNAHpdFc7pnjXRNUYRxXqJKf+WcvyN+RrfSVJEDI4ZT0INAD6O9FFAATiiikJA70ALRWXqHiLSdLLC8v4IioywZxkD1I9KXT9f0vVP+PK+gmOM4RwePWgDTooBzRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABWXr+s2+haRPf3LAJGucE9T6CtMnAzXivxZ11tV1a18PWe+TDBpFRScseAOv40AUfD+lTePPF82ramubVCNsbgMCOw9OPpXt9nZx2kKxxqFUAAADpXO+CfDkPh/R0hXl3O52xjJNdZQAmDmloooAKKKKACiiigAqlql9Hp1jJcybiqDkKuTVwkKCT0FeR/EfxfcXV3F4e0O6zcXLbGePDAdiCCD/kUAZN/wCI9V8feJZNG0WdodNjH76dAQR0zyRj1GPavRvC/gbS/DlikVvCrPnc0rqNzH1zVfwF4Pg8M6UIgTJPJ880p/iau0AxQA1Y1UABQKfRRQAYooqGS6gibDyKp9CaAJsVla34e07X7NrbULWOeMjow6e4q7He28rFUlViOuDnFTggjigDwTVvhz4g8BiTVfCt956oWJgeL5tp984OPwrrfhv8R28Ro1jqqRW+pxHDRA/f9wK9MkjWRSrAEHgg14P8QdHk8F+L7LxHpqxpDJIA0YQD6gdOtAHvKtuAPrTqzdGvl1HTYLlCdsiBgD15FaVABRRRQAySNZEKsMg14TfwN8NvifHIg26Vq0pdnx91jnK+mM4Ne8E4ryv46WLXXgoTxKDLbzrJnbkgdyD2oA9OtpVlhRgc5GanriPhjrX9s+ELO4aQvIF2Mx6kjiu3oAKjlhWUEEdqkoPFAHnfjz4f2OtW73xkliniG7zIkBbAHbHNc58PPGFxp+tTeG9SnMsasRaXDnHmqOwzn1r1y5vII0bzXVVA5LHAr56+JNsPDnjTT9SslIidlKOvRSDyue/rz69aAPo5G3qD606sjw5qMeqaNb3URJSRAwJrXoAKKKKACiiigBAc0tFFAFbUI5JLGZIQpkKELuOBXh3wndYvFmtabc7fO8zeFYc5BINe8P8AcOOteFJatofxw3hfLivSJAAf73X9aAPdFjVVACin4pFOQDUN1KYbaWRQSVUsAO/FAEjyIn3iBVG81zTrBS11ewQgcnfIBXzh4h8b+KNf197SK+e0j3lFjU7dpH6nGOtdDYfCaS/ijudR1qeYnDlVUDJ7gk5yKAOz1z41eHNOLw2bvf3A4CRDg/jXnkms+Lfibqf2eO3+yWBYqf3WVVfUk9T0/wDrVn6r4RtPCfj/AEvZt+wTSKhDqXOT65GBzivofTLWCGBPLRQMdhQBB4S0NtA0SCyaUysg5Y1vZAqB50RCSwGBXG+LPGkOjWMsguFj2jO88ge31NAHaS3UMK7nkAHua5/UfHvh3Sw/2jUoA6ZygbJ4ryG2m8U+O939mh7ezJ+a4uMjPsq9xXf+HfhjpOnW0RuIlubnO6SWZAxY49xwPpQBHN8aPD6k+Rb6hcjGf3VuTn/PP5Vp23xS8MzwCSW7kt2xuMc8LowHrjHT36V0UGhWFsoEVvGvrtQDNU9a8JaPrsCRahYwzKhyu5RkcY4PUUAWNK8UaPrW7+z7+CfacNscEj6itOS4jijLs4CgZJJ7V4V4u+HVl4WE2r6Nq8mmyKMxopPJx0zye1cTB428aeLbVNEgnlcr8ssiDLOM9WIHHTtQB1/xj+IOkalZLpVhH9qm35EwyAuCRx69PpXLaJoni/x7NaQXc9zHp6KoYlWRCAPTuceld34P+DjJNb3+uXUk86YYIrEgY6ZJ5/CvZrWyhtYwkaKoA4AFAHlenfAvRIh/pFxcOOcgEKCCc449Oa9A0zwlpOlIgtrSJSi7Q+3LY+vWt2igCAWsS8BAB9KlVAO1OozQAmB6UYHpS0UAJtB6io3toZCC8asR0yKlooA5rUfAuh6lcG4kt2jmJyXicqc4x2rm7v4R2hG+x1S7gnByGZtw/Hpnv3716TSDmgDya/8Ah3rJRxFdLKcD95Kfm4HGMDP+etY2nah4x8JsZbi1urm3UBXjPzIuDjIORj6V7nUFzaQXcLRTxJIjdVYZFAHlA+NsEF6IbuzZEwFJCk/N39gOnevSdI8QWGs6el5aXCSRN3U5xXC+NvhtHqjJLYfut/EgXAI989ef6V5Ott4s8Naw3hjTdQjuTdgB4kcv5fr6Y/OgD3XxP8RNL8PObcCS6u8f6qIcLxkbieBXmVx4x8ceMb1k0ZZLe23gDyU28d8sc812nhr4W6Xa20c+qxte3jANI0zs4yPQE13ltbWtogSNEQKOmMAUAeMWfwc1XUpEutY1yVpicsMb+vXkn+lZPibwXP8ADyS1vrPVbpYDwSqA5YHOCMgdK+hYriCVikUiMy8EA5Irj/im0cfgm6aRcncojwoOGz15B96ANPwTq11rHh6C6u12uw44xx27mukrlfh/A9v4UtY5EVCF4CnII9eAP5V1VABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSc59qAFooooAKKKKACiiigAooooAqahdJZ2cszkBUUkk15R4Mg/4STxdf6424xiQqFKbVyMY4z1/Kui+KmpT23h2W2gKDzxsYnOcHrjHSrPw60ZdI8PQRhQHb53Oc5J96AO0jQIoApxOBmgUY5oAWiiigAopOc0tABRRRQBn63ci00e6mJj+WM4EjbQTj1rxz4W6NJrOv3fiO7WM7mKRbVHH+feu2+Ld4bXwZMBHG+9guHzx9MEc1Z+G+mLp3hKxQRorNGGbb0JPNAHYxoEXAFOxz1paKACiiigDL13U10vTZZ2YDapPNeAya/rHjTxI+n2N09umCfMychRxxj616F8YL2W20CfbIEwuef4vYVz/wAOpdG07w6l9LeReaylmZ35XuR1oA841lfEvgzxFFanVy0sieYpVyARngH8q9J+H3xdm1C6+xawYxtGBIhwD065NeOeO/EUfiTxfNewybrYYSLdkAKPr0qnpDSWt7bnywQScYbryMGgD7bjdZEDKQQRkEVxfxS0WHVvBN6XQGW3QzRt02kVueFJZJvDlm8ow5jGQauavbQXml3NvcIrwyRsrq3QgigDjPhTqp1HwrbBiN0WU4AxgdOhPavQa8I+Dxex1a7sFuEkiDHYglDYXPXivdh0oAWs7WNasdEsZLy/uI4YkBOWOM47D1NaDHAJrwDxdcXPjz4iHSFYrZ2WV2FhgHPLEevTFAGzqPxqvri3E+heG7q5g3bTNIDt/DaP61yPij4keJdX0a50+/0IQRXKmMSbGyT3IB/Hv2r2/RNNstO0+G0hRVjiAAHrir17ptld25SaBHVieCOh9aAPHPhd8QtP063h0S7gkt5VYIHCcEn1A5Fe8RSCRAw7186/EDwQnhvVDrsChLNSoCxMcq3bg/QdK9l8C6s+s+F7K8dSrPGMg9/egDqKyfEeprpGjXF2zbQi5zWtXEfFSC4n8F3KW5+Y4zzjigDxXxDq3inxL52oAyw6cD5aNGTgehIzyCa4bU77VIZDb3k8m1lD7AeGB75966q48ciw8Ox6R9nDRyQiMhSQyMD1+hri9S1D7b5UqhVZE2YBycDj9aAPpv4Oagt34MtEVyxjyrcjr+dek15F8C7Ka28JiWZcedIWXjHHT+leu0AFFFFABRRRQAUUUUAFeR/Fy0bT9V0XXoY8eU5ilcYz1BX3PU165XC/Fuy+2eAbxhnMLLINoyeuP60Adfpl0t5psE6nIdAaluU3wOvPIxxXCfCPWxqvg+3RnJkg/dtnrxXfuMqRQB8eeNLJ9L12+cMFkt7xl256huc4/D9a6ew+J3i06Y89lo6PaQx4eRkbHAPOcit34reFmg8Y22rLBFLaXWEdXYcyZxyD2x6e9Fzf65daFLYWGgW9laeSY3a4k2AAjnAx2H8qAOGtb3xR438T2d1MGlEbJKViPyqoOMgZ69a9g8WeO5PDYs9NtPKlvZgAyOx3L6YA7nPWsb4PNaPplxAGVp4JWViMHjPrXn/xL1WWH4gXE7xIzQN5akkg4HTvigC9rHxB8VaBf+Tc38d15iBpIj/B7AjHvVnwvYaj8Q9fS+1NSunxkFYP4WI9fWvP7O0u9c1t+EaR2BkLHjH+RX058PvD66Vo8AZFD4GcUAdbpelwWFtHHFGEVRjaBWkAAMDigDA4paACuN8beO7XwtaeXGonvnB2RBgNvuf8O9a3inxHb+GdEn1CcFyg+SNfvOx6AV8/WcepeOteuLmOEy3EjL5ssg2rGM5A4OfyoAzb0+IPHOrNLKJ23Z89yfkiXP3QO3Tp717p4A8E2XhnR1ihiJdzuZ2AySfU1c8L+DrHRtNWD7OhJO6Q4J3N68k11kcaRqFVcAdB6UAKqhRgDFOorE8SeKdM8L6c15qM4jQfdXqXPoB60AbLOqAlmAArifEHxO0TR5TbW7PqF7natvajexPpx0ric+KfifetOlzPpWgZxHEpKvMvckg85rvPDnw70Xw+Ee3tVMw5MrElifxNAHOP4w8fajI/9neF47WNV3gXbks49iMAH2rPufEvxVtQssvh+3cAfMIjuz+TZzXsSxIowFFKY1JyQKAPH4vjHdaazReINDurORDgkKSCfyrtfDvxC0LxHEDZ3aeaesTHDj8K6Sawtp1IkhVs9ciuE1X4R6HcM1zpYk029GSk0DkAH/dzigD0BJ436MKkr5+Os+KvAXiu3ttenlnsGJVLnPyOOMZHY/417XomvWetWaT2sySKw6qc0Aa1FFFABRRRQBw/xK8Wjw5oyW9uUa/uzsiRienc8c1mfD7wU+nvLrWpYa/uuTxwg64Gcmum1nwXpuua7Z6peoZHtfuIWO3PqRVnxLcSad4fuGtreaWQLhUhByPy7UAYnirx1baLK1hbI0t1tyzKQREMdSM8/SvLYtR8RatqLz3V5ESzhYvNl2q6/wC7yMnPTPatbw58Mv8AhI5zrWqQzWrSSEm2cnp+hFdNL8JrCKB/sckgZnDAO5wv0oA6Pwnoh02JriY5nlUBjuzgAdM964v4iXuoeIvE9n4c0uPzIIWDXDldwVscZ9MCur8Ua5F4L8IlizNNtEMA5ZmfHFZPww8PtbWMusXiyfb79vMl8zg/l2oA73S7c22nwxMAGVACBxVygDFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFBz2ooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKQnAzQAtFFIehoA8j+KMd1qOr2NhDCH3Nkhmxx+dekaDaiz0uCAY+RAP0ryv4nGX/hI9IljRWj8/BwOc5H5V61pf8Ax4xk+goAv0UA5ooAKKKKACiiigAooooA80+MshXw7bKFDbpwMbAx/wDrV2XhtFj0W1RcYEajj6Vz/wAU4oz4RlmktoZjGw2+b/CfUe9X/Ad+L7wxZSblY+WAdvTigDqqKKKACiiigDiviR4VTxPoDQiOR5UPGyQJx3znjFfLeseHLnQbuSO5RpIgzKAHwwIOORX2yRmue1bwXomsySSXVmheT77AAFvxoA+NYrP5opUO5sj92BuOa9P+HPw7v9X1aLVL6F4bYPkApjOOePSvb7P4deHrSbetjG+37gYZ2109vaw2sQjhjVEHQKMCgBbeEQQrGowAMCo9QkSKwnkfOxY2Jx6YqzWJ4s1CHTPDl7czyrGixHk+vpxQB4/8IAlx4o1WaNsRpIwiDDJZSfX8K943BUyTgDqa8b+EFhJFDPeSs3znKq3JAPI5zzVj4g+O7xrkeHdAUy3U+Y5GUZx2IHpj6UAdT4n+I2kaFA4VzcyjK7IumcZxu6flmvCNRuPFUeuN4l0rw/cWkc56rGZC2fX/APUK9e8HfDDTLGwguNRt1ub0/vGaTkKevA/E16JHp9vHEI1jUKOgAoA8d0HxjqMUKi/huBdbctE8YTp/KtmT4iNLbSRxeRDOB0d84+uK7vUPDWmajzPZxOQD1Xr9ao2ngnRreR5P7PtvNcYZljxkUAeE+MvEK6pFLA95LqFzKoAjQYii56jjn617N8NLZrPwjYxSkbxGMjPSqviT4W6LrVqVigS2nUYjkjXla4PRPEOr+AddbStXQGAyEq2f9YpOAw6gHjpkUAe+jpVW/sYtQtWgmUFT2IyKWxu1vLVJl6OMgelWc0AeJeJvgdBfX013ZzkNK5YpkIFznpwe9cLrngay8KaHHDcxxtrN3KURPMDMieoXv6cetfSut6raaNpFzf3kgSGFSSSQM+3NeH+EBdePvHUmuXkSG3hYhI2G7YoztA464Oc5/pQB6x4B0uHTPC1lDDGUXywcHrzya6qo4IlhhVFAAUYAFSUAFFFFABRRRQAUUUUAFQXkC3NnLCyqwdCuCM9qnoPSgDxH4SSHTPE+taQ6vEySbhE+Mr+XFe29q8Q8SN/winxntbyOVxb6gAZVJ4BORxx0yPevbIXEkSsO4oA8++L1oJvCDXAVQ0EgbcewPB/nXD2fhHSbnRLS/wBW165MEZEjxyXAK57g/wAuK9h8W2B1Lw1f2qHDvC2364yK+fvDEOkarbXH9vSMyW2WUtOQBnqCAeuR+vtQBtaTrOk6J8Sha6GEktL1AjJbgAIwHU/lWV8V9GW18QNrE1s09tKgA2gkI3Oc8/SpIry01fxHpx8I6LO0Vq582QAKrDPU/TrzXQ/FuSWDw40bYVnUjGPzoA5H4S6TLqmqG5C/ulfLkqCD7V9IWdqlrH8q4z79K8o+CdtCNBWVRyxORjpzXsDOQvt60AWBTC4+b2FVJL1Ily7AAVzHiXxna6VoF9dLIFkjjbZ0OW+lAHmPjO+vPHPxDbSLFRLY2eEcknCt3OM8/iK9W8LeF7bRLbEMYDNy5AxmvN/g9plxI95rOoFlkvJCyqc4xk817fCFCDGKAJdvHFLQKDQBl+INdtPD2kT6jeNiOIZxnlj2A968S8K6ZqPxJ8Tv4h1ku+mo5EFu5ynXgAZ6Ditzx/d/8Jr40tvCVm5NvaMJLx19f7v4f1r0vw7oVroenpa2sYSNRwPegC/ZWENnGEiRVUDAAGAKt0UhYAckUALR3pokU9CD+NOoAKKKKAMvXdFtNc0qexu4leKVCpBFeCSrq3wo8RKsJa40x3AAkJ+QZ/lX0fXHfELw1Hr2gy/JukjXIGOooA3dD1eDWNNiuYXDB1ycHoa1K8K+E/iSbS9en8N37MFOWgL9cZ6GvdQcjNABRRRQAU1kVxhgCO4NOooAQKFGAAKpatqlpo+ny3t7MsUMalmZjir1cV4z8GXPi+7tYpbxoLGDLbUGSzHjnnH060AeO+Pdd1DxRP8A27H50VhYufsymEFAM4DE55Jx36V6R8MfHttr2nJazMiXsfyug4z7iu007wxp2maSNPgt08kLtKlevrmvD/G/hOX4d+IrTW9FaSOzdyTGgJ2nOSCfQ0AfRQIIyKWud8IeJLbxJosF7A3DLyDjKnuDXQigBaKKKACiiigAooooAKTvS0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAYooooAKQ9KWkPQ4oA8p+KER/tLRpASo+0c7VyfWvStN/484sN/CO1edfFaNo7SyuFk2vFPuBLAf8A167DwlNLLpMQlkEhA4YelAHRUUUUAFFFFABRRRQAUUUUAY/ifTV1Xw9eWjRmQtGdqrjJPbGeK86+FWoy2kt5o1yJQ8EmR5iBcZ7cfhXrhGRivF/iNp8nhDxBbeJbESRwyuRP5fOW9/rj6UAe0KdwzS1zXhXxRZ+INOjnt36qCVPUV0uaACiiigAooooAKKKKACvIfjJrjzxWvhuyaRprlszLF1C9uMc+uPavRvEGv2eg6ZNd3UqosakjJxk+lfPmhy6j8QPHf9qyNK0UUoxj5cLngfSgD03RLCbwt4LmuBExuIoSThMlsAgHArifhht1fxlfahcyyyPHlsSnjcTzgHpXtxsEn0uS2dcq6bSD0rwXXNM1X4c+I4NbgSSYSZN4GcFWUkdB2Pt7UAfRUIGwYPGKmrkfDPjjRdesY5LO/hdyoLR7huX2Ircm1uwt0LzXUaIBklmAxQBpUV5re/GzwraX5tRPLIB1mRMoPTmr/h34maPr+9UuYkkUn5d3UevNAHdHGK8I+OTJDrOkSLG5fDBnHCquR37fX2r0HWviRoWlWjyLqNpLKpwUE44+uM/lXhHiHxZH4x8dW15eMDptsAI3RSuR75HqaAPozwk06+H7UXMwlcoDvxjIqzrfiTTNAtPP1C7jgQ8DceW9gO9eLP8AFfV7uX7DoFjHFGija8rZd+3yjpSxeDfEviy7tbrVrgyZOWVmJQDqeM4BwcYAxQBoXWp6j8WNZeyspZ7XQIGwzKoPnng5Ofr79K9Y0DQLXQ7JYLeNQepIUDJ7nApdC0Gz0W0WG1gSNRzhRitigAooooAKKKKACiiigAooooAKKO9FAHlvxksHXTbTVE2f6PKC27OcjpjA+td34avl1HQrS4V1bfGCSp4zjmmeK9P/ALS8OXkIClwm5d0Yfkc9DxXG/CLVml0a402YAS2czIQD2/pQB6POgeNge4r5W8Q6Jp+l/ES5s5jLLbzzbmiVyig57k9e9fVcgJQ7etfPXxU0yWy8YfblTEbqG+Xg479/XNAHsnhnRbDT9NjS0hREK547nrnPeuP+MfhufU/C8lxbAmSD5iAccZGf0zXZ+DLoXvhqynByWiGeMVt3NulzA8UgyrAjFAHlXwckhPhtYhgSox344zzXomr38en24kkYKGOMnoK8sjM/gX4gS27tEumXpBRVwNnYEj6it74ka3pw8Kuk1ygkJDxKG+YkZweo4z9elAHBalquufETxHdWFhcz2WlWhKl4iQ0pzjr+dYOq/C7U4pEgs7uYhz+881sgj6d6m+G/jSw0PWbiDUJVSC7ffHIpyqE9Q3pXvNvLY6msN3a3Mbqw+UqQVagD57jvPGHgFh9te4+z7R5ZiQvEOehz0r2bwD8RrPxPH5DsI7tFBZOua6vULWxlsGW4jjZcfMGAxjvXzppd3aL8TpE0SJo7Vpx+7GUAOec4yMZoA+pVYMOKralcrZ6dcXDttEcbNn6D8afasWgQnrjmuN+LV89n4AvtkojaVkjB9csOP0oA5X4SWH2681PX5iWmu5my2zAIBPSvYRhVznAFcZ8NrJbTwlYoFAPlhjjuTXYzgtA6gZJUjrigDkPE3jqz01Ta2dzA964by1Ykgkdsj34rgb/WPFuo2VvLNJOEkILJaJuXBPdsfpivO/HUs+l+IZ0k8ouHYIyqcsOnOeKl0b4matpOiQqUimCsQc5+YDoPY/SgDes/iNrGl+I/ImnuGskc71kGWUZ6gDBwMdK958Oa9ba9psdzbzCTI54wQfcdq+NdT1mTWNflv58hZHLbOoUGvbvgtq0gPkuVCynjjrxxjigD3WigdKKACmuoZSD0NOpD0oA+cvGbJoXxbsbiByjtKoZuMYPFfQtlL5tpG+c5UV89fGtVXxbBNG2243KoVRnPIINe7eG3Z9GtixO7y1znr0oA2KKKKACiiigAooooAMjOM81l+IdKGs6FeWGdpmiZAwxxkVqUUAfOfw21O68J+Mn0G83QxO7JscgDcDwR65r6JikEkYYHORXhvxk8NvpuoR+JrVz5gYFUCDhgcn3NeleAtbOu+GrW8dBHI6AugOcHvQB1dFFFABRRRQAUYxRRQAUUUUAFFFFABRRRQAUUCigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooPSgDz34rWiXPhp3Eqo8Tq4JXPetDwBdC40K2bdlig3cY/SpfG1mb3wzqETAH92xGcdcVzvwx1JTp8FoxBkQYJ3g5oA9PooFFABRRRQAUUUUAFFFFABVW+sob63aGeNZEbqrDINWqKAPDPEHg/UPAesNrfhoS/ZWy00G75R9FA6V3fhPx/Ya1bJ50ghuMfOjHofr0rsri3juI2R1DAjBB715rr3w1b7c99o5t4ZpOGDIRge2Dj9KAPTEmjkUFHUg+hp+R614kqeN9HeKKGykdR8pZZiRj3pD4+8T2N60U2nSsq5BPPJ/GgD27Io3D1rxVvi7fRK/2jS3DKORG27Jzjr+tRz/FTUZYGFtbOJ84VNnA4/vZ65NAHtM11DAuZJFUe5rmta8d6RpNu8k1wFUA8txkjsPU15ZDf+OPEMa3kQjt/mICzIxJXjkD/APVWh4b+Heo6hqDXviV/tknVA4IVPoM0Ac/qVzqvxL1weTI66ZFINsbKBuP0NeveDPCkOhaeF+zrFK2d5AHzcnmtrTNCsdOQC3t44yBj5VArVAA6UAIq4GKpalpNlq1v5F7bRzx/3XXIq/RQB4d8RfhPpVnpl1rOm28ySRDeYbchRj1HHbFeJw2T3dzaeZcu6TuAElcjd6+o6n9a+2J4lmiZHUMrDBB7188a94Z02w+IX2ax08ukcqsIlB2xs2Dnjtx06UAa/wDwo7RnslkhuLmNzgsd2eO4HpXA6Z8OIta1iaCwvybaNjlzndgHoQQPzr6L1e9XTPCN3ckf6qBjgE56e1ef/DLQsPcagzNIJCdrOoBz36cnt1oA898EeBdP1Dxze6XqMTSxWpIGZB8xDegr3qH4ceHFVR/Z6BRztUkL+Q+tee6BaJZfGO+CMz7pSWIUbVyM4Jx1r3EdKAMu38O6XasGhsoEYcAiMZ9K0kiRBhVAHsKfRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQA2RBJGyHowwa8T8Pr/AMIp8Wp9KiMgguwSS4zuPUYPsK9urxT4qRDSPHeg6xDGVZ5AHcHAPIH8sUAe1A5WvMfjHooufDyanFbwyzWjZPmHGV9M5FekWcnm2kb+qg1neKdObVvDOo2MePMmt3VM/wB7HH60AYfw3uUl8KWjJkKV6Z7967M8ivGvg9q/lW8mizNtlgdvkPHfng89TXsg5X8O1AHiHxq1SEPaxR2iG7RxiVlG5Bntn1qh4R+FEeqQW99r1xcXTMAyQPISqDqB71Q8eadLJ8VYoL0vOkrxlW2cFc9DgEHnive9KtkitY1RQAoGMelAHC6z8ItF1VFMUP2V17w/LmuZtvhLr+hyl9I1yVU2kbM4wexH6V7mAKMA0AeFX3gTx3rkE8F/rZFucKqtnLDB5O09efyri/D1g/gDxqLPXrdM+Z+7nIwMHHzAntX1OYwe1ebfGTSLa48I/a3jXzYJkKv3UE46igDv9NuUubNJI2VlIyCD1rz742XGzwhHGIg+Zw5J52gd8fjU3wtuZf7GMDRukKN+6Ehydp5pnxasp7rw+xjRpFQEkHbtHB5we/T/AD1AOp8Hbf8AhHbLAH+pX7vTpXQ9RXBfC+/e88I2O+QSSKoVmxjOOK76gDwn4z+BNS1C/wD7YsLT7UDGI9qhiynvwOPxNeFXlpqFq4tbiylt2iXDqUIPPc190socYYZrkPEXw28P+JJZJbu02zOMNJGxUn0Jx1/GgD4/sd32sKkIdmGMNX0L8F9AniWfUJ7fy0ZsRluWbGcn9T9a6DTfgr4b02YyJHM2eu+TOB6V6FY6fb6fbpBbxLHGgwFUYAoAtUUUUAFNY4Uk9BTqp6rdLZaZcXDZwiEnFAHzv46Da38ULK0jZiZJgeuRtB9vpX0LpUPk2iLjGFFeBeCI/wDhIfifdXjqGSzVsOpyCxP696+hbWPy4VBOeO9AE9FFFABRRRQAUUUUAFFFFAGbrulwaxo9zZTxq6yIQAw4Bxwa8n+Et3Jo2saj4duE2SRyGRDn7w6GvajXjnjWOPwp8SNN1wQsLe7BSVk3Yz79qAPYgcilqvZXEdzaxzRsCjqCCKsUAFFFFABRRRQAUUUUAFFFFABRRjmigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKAc0UAFFFFABRRRQAUUUUAcx4sndNKu0RAT5ZIz9K4D4SyedFI8gj84SnJCkMfrmu88WuV066ZRkqmQM15b8KGuBrF5OwJSSXGc5GcmgD3sdKWmocoKdQAUUUUAFFFFABRRRQAUUUUAFIQDS0UAMaFGHKiqs2m28v3olJHTirtFAGM/h2xfrbx/lSxeHbCI5W3jUn0UVsUUAU4tPhhUBUAx6VZWJVPAFPooAKKKKACiiigAPIrznxR4Y1xtdbVdIKyFlz5TSEAMBxxnmvRefWloA8c1HRPiHqtjLY3L2ogniIfaq8HGNvuD17Yz36V1vgTwpc+GdDW1uZVkk+8SOxPOPf0zXa4FB6GgDxfQ4tnxg1ElSZGkJbKbdoxkYPft+dezqflFeR6TcxH4wasvlksBjzDn0HHP0x+FeozajbWluZbiZIkXqzsAP1oAu0Vwd98W/C1nM0S3pnK/eaFCyjr3/AA7VLpfxQ8N6kqEXqxF32Kso2kn6envQB29FRQzx3EayRMGVhkEd6loAKKKKACiiigAooooAKKKKACiiigArhfirpMeoeDri68oPPZ4mjwuWHrjiu6qjrMJuNHu4lfYzRNhtu7Bx6d6AMPwBria54XtZ1I3qgR19GFdSwypFeO/BLUvk1TS9+5YLgsp6ZyT2r2OgD5+80+F/i41nPvWOW5d48NwRJyM/nXvVs/mQqeua8V+MsX9k+KdI1yEojqRvZhuztPpj0NeuaFex3+mwzxtuR1DA4xQB5z8ZPDN/eJY65pURe6siS2xdzYHIxx65/OpPBfxW0i+05ItUuobO9iXbMkp2jI4PWvU5YlmjZHAKkcg14l8TfBnhzRbKTU4NPUXkz/KsZKj1JwCKAPUbfxloFyF8jVrNy3ACzKea2UuYpACrr+deC+HPhbZa/wCGob3dLZ3cy71YMWHXIJB/lWN4hk8W/DzW9OWPWptQixvMOSflGAcg5wDQB9M7ga4P4u7T4CuuMv5ke0Zxk7x/9eubsPjno4IivbO9t5ApPMYIJHbg1znijxZffEkxWWlWcyafG4Ylg2ZmHbjpjNAHoPw2i8rRYFdt8pHzHIPP4V1+tWEd/p0sL5wQQcHFZfg3SptM0WCC4ULIi845/nXTlQRzQB4n4N1mXwj4sl8O6gsiwTyM1rLK2c+2e9e1RyK6ggjpXCeOvCY1e03wuyXEZ3xupxyO2fWuV8K/ES/0WV9O8UAgRfKk4jPzdOD70Ae0UVU0/UbbUrVLi2lWSNxkMpyDVugAopCM0tABRRSE4oAUnAryj4weK/7P0mSxglKyMMHGO4+tdf4x8TR6FYHZMFuCCQNueB36182XKXnxB8ZQ21mHZHbEsyg4x3PPTjtQB6Z8DtFZdMudSYbDdPkADoBXtqABQB0FYXhXQY9A0iGziHyIoUZrfoAKKKKACiiigAooooAKKKKACuJ+KOhLrfg25VYEkmhxJGWbG3HU5+ldtVTU0Mmm3KL1aNgMru7enegDmfhxqX2/wnZklS0a+W23kZHHBrsa8h+D+puZ9V0x2/497liq7duAT6dBXrw6UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFHagDjPGd7b2VvN9oLbTExwBngCuV+E2mo9hJd+WVEkxZM9evemfFnV2hBsxcbDKMKofBb1GB1rpPhjaiDwzbsHlfeN2ZVw3PtQB3YGBiloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigApG+6aWo5shGIOAAc0AfOOp+KtQT4j6ymgQxzTSSbfMyxxjjGDx1Hb1rck8BeKvE0cEuqamXz8xV84U56AduKvfD2ztLzxbq99GdrySsGRmD55PINexxxIqqQOgoA87034V2NuwNzcTzKQCRuI55z0NaGr/DnRL2waKO2W2mVT5c8Q2lD1z+YrtyQv4V5/8AETx9YeH9JubSC6zqcqFIkVd2Ce59KAM34TeIL+8ju9JvJjP9icxiQgAnkjGB2GOteqDkV5Z8HdDmsdBN1OiLLO5c7VwfxOa9ToAKMc5oooAKZLKsMLyucKilifQCn1U1S3+16XdW5yRLCyEDGTkY70AeeW+seI/FM017pmoJZWyTFBCUB3KDwTnkEg/qPStPwJ4rutRnudI1Vw+p2rsJCq4BGeORwa8fk13xH4f0290dUS2MUuZZwuGUFh0PTjpxXs3gXw8ml28l48rTXN2RLJISeTj0J4zQB2tFFBGRigAooooAKbIu6Mr6inUUAeDac0nhT4zzWjs6W1zgICMBs9PXgYx2r3dG3ICO9eI/G2xmsNV03XreFgUdFeXOBkNwP0r13QL4ahotrdA58yNW/MUAcZ8YNNW48NR3oCbreTBZlzhW4P8ASovhRrq32jtYkYktTtJHQ57j05zxXa+JrBdS8PXtsVDFoiVBz94cjp7gV4t8K7oWXjK5s8ALPCHyWJJYHB+v1oA9+rxT4pw/2v4007THIEbKE+YE4JOSwHA/nXtanIFch488H/8ACT6Uy2xhgv05juWTLL7Aj2zQBo6JbQ2OlwW8WAsahcAdhXkfxLunm+I+l28UgHlhGGxcuGycjA9RWLr2s/EH4cQRW1xdxXNs7FY53G4sfTk5o8Faf4k8TeMYtZ1GJ8CQOZJIAOMEYHHFAHuNnoNjd2ym4tIZCy4O+MHI961LPRrGwjKWttFEpOdqIFH6VZtYjHCqnqBU9ACAAAAcYpaKKAGuiyLtYZFcH4x8FpqKm6tYF+0KwORxkZHX8BXfUhAIwRQB4Jpeq+IPA3nCGNbuwLFhb5IeP1Ht616J4e+Juh615MRuFguHH+rkYAhvT610up6Bp2rWr293axyI/XI5/OuGv/g5otzG4iaeMliwxKeCRjP8vyoA9GiuYpV3I4I9ql3DPWvJLX4eeK9IumbT/EDeSVCiOZmbA46e/v8A/rqvLoPxLt2VYtRRw2QX8zJXPc54/SgD1i61Ozs1Zri4jjCjJ3MBgV5t4s+N2haKWttNzqN2QQPJ5RT2ye/4Vhv8G9X1b5tT1uUO77ppASzP7e3Wuw8N/CTw54fWORLJJ7pP+W03zHPr6D8KAPII/D/jT4jX732pJ9jtZ2DYZcHb7D6ete4+C/BVj4X0yOCCEBhyWPJJrpYLGKDkLk9s9qs4oAUcCiiigAooooAKKKKACiiigAooooAKa4yhHqKdQelAHi/g+wm0v4parGXQBwSETAGM8ZUV7OvQV5neutj8YkYqpNzagZL9Me2P8a9LQ5UUAOooooABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFRXEohgZ2OAB1qWsXxBqMVlYyuzj5FLMO+PpQB8+/Ee+m1nxzBbQXhCq4Ux7yVUjuR75r3rwegXQLXoT5Y5AwK8K8NxR+LfG89+ke1FmAJKYORkjBGR0HevoywhEFskargAUAW6KKKACiiigAooo5zQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVk+JrlrXw3qEyffWB9v1xxWtXM+P7lbXwbqEjBDiPgPjGe1AHAeAtX0vRdIlubyVYWkmI+Zskk8nqa6a/+Keg6fa+c0xePgIUIO7Iz2PT/AANea2Pw21XxLbrNHqMVvaS/MFQu2MgBhjOOfr9K7rSPgxodl5TTB5nQ7yWxy2APTgcZAoAwNV+K+sa0VsfDekss0vy+dMwZR16bT/XrS+APh1dPqq63rayPcEhiLhdzbiOTkn1/GvWLLw9p1gQ0FqiMBjcBzWmqKvQAUAR29vHboEjUKo6AVNRRQAUUUUAFI33T9KWkb7poA+cPGEMraz4ykjjZo28tUkAxuIIyOTzjmvb/AAazP4Y09mXDG3QkZ9hXifiuCWzbxRbzxiMS3UKKAdy7C+QRgcen+Fe8eH0SLR7dEwVWNQD68UAatFFFABRRRQAUUUUAcZ8T/DreIfBd3DCm64iHmRD1I/GqHwi1t9U8JxQSxlJbQ+S2RgnHqPWu+miWaF43UMrKQQe9eRfD5Z/D3j7V9HuI/JincyQoBwQD19qAPX3UMpU9D1r5w15JfCvxHdIo2iQTboiicBCc4yMDnPT2r6Rrx740aPmG21OPeGJ8pynrzg4HXr+lAHqWk3QurKOQc7lBq8RkV518MvEBvtBt1mYCRV2uD6ivQxKpXduGPWgDxP49QJONGhOR87tuzx2HSvU/DNpHBpFsq84jHP4V5P8AF51uvHWi2zIzxqq7xztwzH0H9a9l0iNYrCJEXChQAKAL9FFFABRRRQAUUUUAFFFFABijAoooAMUUUUAFB5FFFABRRRQAUUUUAFFFFAARRRRQAUUUUAFIaCM0UAeS/EEyWPxF8P3/AJR8tj5YbHGSeefyr1W2bdAp9q82+LANvcaDftGWihuwHIXkA4744r0TT3WWyidehUEUAW6KKKACiigUAFGaKTNAC0Ug6UtABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIehrx34u6ndadpDWtvLB5l2+0/OAwHtmvYZGCoSTgYrwTxVKviz4nW1la2rSfZAUmcqQAPfIoA7D4W+HZNM0GFrhU8xgG+UDH4Yr0tRgYqjpVqtrZxxqOFUAVfFAC0UUUAFFFFABRRRQAUUUUAFFFFABRR0ooAKKKKACiiigAooooAKKKKACiiigAooooAK87+LFwjaRaae0TOLqbBYcBcDucEc9K9EryT4izw3viuztJ3k8qBA21T/GTx9e3pQB3nhawhstHgiiXamMgFcda36oaTG0dhErkltozmr9ABRRRQAUUUUAFFFFABTX4U/SlJAqveXMdtaSzOQFRCxP0FAHy34/vp08ba9pzOssVxKnlNjJQqwOOO/WvobwHK83hPT2kYM4hUMcY5AxXzx4ysZpdM/t6VAJJ9T52gjIK5GD+Fe+fDtfs/hSyRpPMLRhg315oA7KikDBuhpaACiiigAooooAK8Y8asnhr4r6bqqytEt4mJMKADjjk17PXnXxa0eO50SPU87ZLPJyIt5YHBxntyKAO+s51ubSKZTkOoIrm/H2mPqnhXUYY3ZHWEspUZPA549xkVP4Eu/tvhGwm3ht0QOcVu3MQlhdD0ZSDQB8s+CtAl1m8vI7TVrvT7qKT5WhkbH1xxkV3cWseOPAFwh1tjrWiD5WniXMiL6kdfrnP1rD0W1Xwv8V3sVkDxyllyOMt1/OveYkjuYFDKCD3xQB4B4h8YaT4w8YaPdWhkMcYVZdyYMZ3cZzwB+NfRGmEfYo8HIwK8G+JXh+10zxto88EUEUNwwEgWPbvweSccGvd9KwLGLGMbRjFAF6iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDy/41hf8AhHrNyrELcrkqM12/hh1l0K0kXODEvXr0rkfjDZJdeF0d5lj8qdW+aIuPTnHT61v+CJkn8LWRhlVh5YG4A4P580AdRRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAGD4w1VdH8N3l2WAKRkj59pP0ODzXCfDTS/PuLzVyXzdsG2tL5hHfn0PNZ/xW8RzX2rWvh7T5kZmfM2wZKgds9sntXpfhexNppMCuPn2DcffFAG4q4UCnUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFIWAGScCgMCODQAd6WiigAooooAZK4jjZ2OABkmvEReLrnje8v1dvIEnlcKGBGQP7xwcdx6V6d441X+yPCl7cq4SXYVjJGfmPt3rzbwDYzTamnKMuVllbaoPfGBjI6/5yaAPZrZdsCD2qamoMKBTqACiiigAooprOqKWYgAckmgBxOK5XxV40s/D1odrxSXLYEaM2FznHJ/zmuf8eePpbLy9K0SJLu6ugyK6PwhHY8fXj2rD0H4d3WuSi+8UlZHkXm3jyoB9yMUAVL34rX11dNBEyhAwQfZ87z7gdSMc8VkeIPEHjjWorqx0y3vXgKhWcw7fMUqR8vPAJ59a9osfCOj2USJDp9uoTG392CfzrZW0iXogoA+Y20rxdqnh86I2g3SpuWRDIAoRsk5yQOPb3rV/wCEm+IPha0gtLrSPLjwAjRJuA7fw5/Kvoj7NED9wUPaxOPmUH60AeB+G/i3rUd2sOqxMdkgSTfGYwR7ZGN3fBx1r3DSdZtNXtFuLaZHUgE7WBxkZ7VW1fwxpms6fJZ3dsjpJycDBB9QfWvKrvTPEPwvupb6zke+0IFfMiyWdBnBOPp7gUAe4UVheGfE1h4l05buylDqeozyp9DW7QAUUUUAFZ+tWLajot3aJKY3ljKq4AJU9jg1oUHpQB5X8I9Suo47/RrwtvtJiqZXAx6CvVOoryHxYsvhT4g6ZqsTWdtZ3L+VIRlWfd1yBwcHv9K9YgmE0IZTnIoA+e/jLZ3WkeL7TULGUxzSMHiOM4PQ9vWtLw98UtX0iFF8VaZJDakYjvIIiUY+/wCFb/xwtF/sbTtRa28429wcrkdxnnjkce1bHg2yttX8JWRuoIZAUBKFQVBx6HNAHm/jLxRZeLdU0W50y5ZofOZH38BSMYO0ivetIBGnwgtuIUDPrXinxM0Sw03XNMjsLS2t8/OdgVcYOc4yD29+le06Kc6ZAc9UBoA0aKKKACiiigAooooAKKKKAADFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUfSiigDzz4xO0fgtyqb8zIGG7Ax6k1Z+F8jP4TtQzqzKCp2n/OayvjRGZtBs4hgbp8klsdB9ak+D6NH4bKFw+2VuQc96APS6KKKACik5zxS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFVdRuls7CadzhUQsTkD+dWq5/xlfJp/hi9ncxhQhB8w4Bz2oA8k8F2yeKvHWpalcbpVgm/d73BK/gBg/WvdbdAkSgDHFeQ/BeGWTT7i7eCOKOR8LsGA2O+MV7Eq4AoAdRRRQAUUUUAFFFFABRRRQAUUUjEKpJoAWiqkWo20t09ssqGZBlk3cgVJdXUdpbSTyECONSzEnGBQBPRXO6N4y0vXBKbSUERyGMnPUj09RW4J49mSwxQAT3MNsm+aRUUdSxwBXOap4/0DS7d5pb+JwvQRtuLH0HrXnfxJ8RKPEKadNqTQ25AdlESkBcY69T+Vc79r8JCxVhO1yrEny/s+GJ5HpwPpQB2v8AwuqzlvUWK1YwyPsUscHHqeMAV6NZ6zb3VolwsiFGGQQeK+avtr6lo9zb6d4ftlaAlppiuxVAPB4Pp710vgPw5eeIdPQ399J9mic7YY5flP4D3z3oA9suPE2k2wbzb6AMoyy+YMj61x918TJZbsw6ZpjXSbgBIGJyCOuAOnar1j4C0+2uHmkkml34JRn+U857dR7Gt9LSzsYRHBDGgHACqABQBwe7xv4gs5J7i7XTLdSWCRIVkwB7/wBa1Pht4ludV01oL6ZpbiJuWbOWUnjtWxrniHR9BsWe+vYow3CpnczE+gHJrgPhc8S6/fwwF9hYn51AJGeD7fjQB7SORS0i/dFLQAUUUjHapJ7UAeV/GG+YwWenoVy5LEOpwc8demeTwa0vhzpX2O3MmYzvUNhMHb14Jx/n2rj9fnbXvHM91JDG8MJEEK/aVUuOTnrkfQjnPWvXdAtVttLgVYwmEAxnP60Aa1FFFACEgDJqJbiJujg/jVbWdP8A7U0m4sxK0RlQqHUnKn8K8O07w/dW+t3WjT6xe2OoRHfFJDMQrrnjIxgmgD3ozoELkgKOa8l8T+NtT8Q6tN4e8MxB40Pl3VySRgcggEdOnXNc54u1LxHoiJpdvrD6ks6hWikwJFP+8uDg4713/wAP9Bj0/Q4M2yQzOoeXGTljyeTzQBB4S8AQaXOLy8PnXjc7j0Ukc4H9a9EhhWNQAB60yJFUnjBqyuMUAKBgYFFFFABRRRQAVFNbxzxtHIoZWGCD3FS0UAeSa1pl18O/EA13TC/9iXMoF9arjERI4dc9s4GK9L07U4L+zS5jkVkdQwINS6jYwahZS21xEkkcilWVhkEV8/SXmveEtYuPC+nXiRoZMQGXn5W6YGM/5NAH0Bc6la2ah7ieOJMgbnYKOenWn2t/bXoY28ySBTg7TnBrw7VtBvpNLfUPEWtXE8MKgvChChm7AfnW18GrGa2tby7cSJHcy5RWYkY9RkUAewUUDpRQB5/8WvD8Gs+FWnaKdp7RvMiaDll9eO44q98PNdj1vwvbTAneqhXzwcjrXVX1nDf2ctrcRrJFIu1kYcEV5J4KR/CPjXU/D0sEkcUrmW3kLYUr6AE/XpQBv/GOVY/A8j7CZPNCoAMnkEVZ+GULR+DrFGCg7OgBGD+Nch8YNWGpXWn6BbqZn3ec6xjcQ38PGc9M/nXpfhayNrotspi8tigLITyDQB5f8bLVxf6RMArLlh8wBxzz29xXqnhaWOXQrVoirL5ajKnjgVwPxwQf2HZOygospzxk9Mjt/hXXfD9ETwpZLGyFfLH3elAHV0UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUmKAPNPjMsT+G7fdnzFmDIApPI9x0pnwfR00B1K7V85sEfxCofjXPGmj2IberCYkOvbirvwgj2+E4yQd29ixLZyc9aAPR6WkxS0AFFFFABQaKKAAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABXm/wAWlZtDcpH5jKjfKS2PrxxXo5615l8YHm/sZUhWVmPVVk2oR/tY5NAFv4Tqi+DrLbt+6f516EK80+EOf+ERt8ED5jwAeOenNelgcUALRRRQAUUUUAFFFFABRRmomuIk3bnA28nJoAlqOZgIzzWBf+NNIs96JP58qruKRAnA9Sewrkrz4g3+t2EQ8PabPLLOxUuVIWMDuSwAIP8AWgDP0W6ki+MupxeYTGYQcE59Oa9N1VPP0e6Qoj5jI2vjB4714Jol/feHviy8OrzJJJd91YkDPTrz+Fe/b1msmBPDLz9KAPmbTfFcvhbV7y1SwWacy71WBvl/QH07V2tm3jfxnEgmzp1ky5ASQo2fw5I9jXOaBollB8T763uIZfLVmMPnemete2WWraRaQiM3tshTjBkAx+tAHhPjbwTNot3DLPPJco4DMztkgjPrk11HwxsdPf7VaTWcBuYHJWYrkspJ55q38S9d0rXLGW10lDeX0Q+eWGLcI17/ADdK4nwbe6ydQaPTGVJLpELO7AcLwcZB54oA9O0yytbXxXrWmiNAtyqzLhcDBG0/qKx9G1vSvCGuXkN/qJhP/PGViR16qCO/tWYbPxNp/jHTNT1W9iaGV/s+Y1yQDkgE4Gc/StDWdN0qXx5BLewLJI7BQZMkYwMYAXHX1JoA3n+I91qkgi8OaNdagp+UXGNkO76+lT2/g/xHrMjSa7r8qwSEs1paDywB/d3dcf410YutM0PT/MnmgtoVzjOFHr0rJk+KvhqEER3M0zBchYoGO76cUAaGn+APD+kuJrXT4VkXkOwLEfQnOK5HQVTTfipq1qN7ediRSx+6MZ49smr8nxM1G+UnR/C+pXK54dwEUj15rl77UbmHx9puoahbyw3EqKWgXDFeSPT0x0PagD3RDlRTqhtn8yBT7VNQAVm67qEel6Ld3chQCOMkb3CAnsMngVpV5j8VNf8AIW10qEh2d1aZNxUhe3Qjg4OaAOQ8FRDUPEELgPsLmVcOGKduuD2K9MV7zAgSJVHQCuD8BaZDFEZgT8p2IrDhAOwJFd+OnFAC0UUUAFcV468M/wBq2RvrQtFqNspaF0bGT1wfUZArtazddkEGi3kpO0JCzZ9MCgDxPwhZyax4imk1W3mN1j995uDHnjgD8K9cvb2PQtFuLxkysETPtHHQZrz74YWNu9qdSgYv57YzwMY7bQOPzNdj41uFg8GalJJvCLAc7CAfzNAHG2fxusJ0klu9Kv4Ykk2NJGnmJn/eFdBp3xc8L3UzwNf+QV53XCGNT9Ca4X4UGCw8Jahf6gFW2EzOWYZOBjr610X/AAn/AIFv3CSXds2cDEsOPzyKAOoHxQ8JZCnXLMN6b/fHWrI+IvhYrIw1uy2oQCfOGMkZ4PfofyrFtrTwXc22YrfSWik9FjIPf/Cnf2J4JtY5J/selRqWy5KIBkcf5+tAFuf4seD7eTy21q3d/wDpmC4/MAiptG+JOha7q406xlleRh8r+SwU98Zxx+NRWemeH95WwgsVdeqxIufxxXC6dMy/Fq6tYGMO2UElTlXGwcY7d/zoA9xByKKZEcoM0+gAI4rxT40aS9vPZ6xbrl9wUgJkgqcjB9TyK9rrhfilaNdeFHERAmWRSjZxjsee3BNAHnD67/wnc1jpNlvWBU33RIHJIIA/D1Br2Dw9pkWnWMUEYCrGoVceleH/AA2ntLTxhc2yyjM8e9ADu7/MCfXJPbtX0HYY8v1IoAvDpRRRQAVx3jTwPF4pNvcLcSW11bEmORDz/OuxooA838IfC+HSJTfavMb/AFElSJpDu2hegGf516MqBFwo4p1FAHnvxYtPtXhyFt23y51xlAQSeOc9B/jVX4Q30s2jTQNtaOGUqhXAAHoAO1dL4/sxeeD75TH5m1d4X6enofeuE+DUuXvI4mYwrtABHT29PyoA9iooooAKKKKACiiobm6hs7d553EcSDLMe1AE1FVbLULbUIRLbSrIh6EHNOvbyDT7SW7upVigiUs7t0AFAFiiqWnarZatAJrG5jnjPdDmrtABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUdqAPF/jleNBJpcaumCWZk4J+uDXbfDe0a28JWYdcOyBiMdM1wHxlVo/ENjcu0fleSUwRk59eOccivTPA0bx+FrFXOWES8jPp780AdLRRRQAhApaMZooATvS0UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVwfxMtJrnSAVV/JXPmOjhSo+pI/ka7snArnvF9rb3+gzxT7igG7Cru6e2DQBw3wauBJpt1EpxGkxCLvLEfia9aByOteEfCDUxbaxqGmSSEYkJVPTBxjNe6xnKA+tAD6KKTGKAFooqOdmSF2RC7AZCjvQBX1DU7TTLdprqZI0UZJJrgr74waZHOLbTrC7vrgttCRgc/1/SvOtUE3iTxrfQeIdRksbVGJjV2UfLnkZ6dq7Gz8R+DfDQW3h8vzM8vDHuJx3LAUAS3XiXx5qzltL0ZrOM/dNwVXH1ByT+n40yPwn4kvZmk1zxISjAhooolGR25I/pU4+IjXpcaVpF/cKoBSQQfKx9Ac+9Z6aB4z8SytJqN4dMtpD/q4SPM2+nGf50AXDpHgnwlHvu3i8wNuPnSF2Lf7vr+FWU8ZtdkQeH9Du7xFUfP5flIue3zY/StPSPhrotjJHcTxPeXQOfOuWLnP0PArso7WKJcKgH0FAHz9438NavJbp4iurGODU42DmKIl1I4611nhb4paPcaSYr68WG4iUKVY5LHHbjn0xivRNYtoprZw2MY/CvMtW8GeFJ2FzfS28Euc4QhS/Hp1oA4Oy0uXx18QdRvIr27istxCSAkNj0Gegr17RfhpoFpaos1kty3UtcZck+vNYGjap4X8N7IrF5WL5YADG4/jj2rbuPFfiC4AbR9CeSFhlXmO3I+mRQBa8Z6Tb2vgy9t7CBIBswPLVVCjue1eN+DtThXxDYCOVwI2MZQnqCOpI4659K9HvdI8Z+IbVk1G+t7GM4HlRKSGGDnPPvXjd9oKaL4mls4L5N1uPMGS3BHJBwP5UAel+O/GWku1rp9tOkk9tcI7gAEdcYBPf6VY8c21w8NtqFsVRyiv5knKoQR6DI/Ouc8vwld+C57lvsS6iyNIN8g37/bJyPapdQ+IGlXPgizgku5ftS7VkRODx9QQelAHaeGfh/a6hHb6prN5c6lcyKr4mc+Wp68L/jXodro1jZoFhtoox/sIBXl+h/FPRLDS7azg+23lwsagKkeWbnHU4FS3XxcvJJ0j07QLiXcQBubJ6c8KCOPrQB6p5ESJwuBjHSvJvigbaz1/RJ0cPcyEoITHv3DI5HzDHWhfEXxC1qW3gg08WAlJ3zGHIC4HPJODz6c1b0T4Uyyat/aviTUJdRuQcxrIxIQ/Xj9AKAPTdLZmsIS3UoM4GO1XajhiWGJY14CjAqSgCG6uI7W1lnlYJHGpZmPYCvn24vT4o8Xz6izE/vSIIyu0FQMDkjn1/HivQ/in4ol0bS4rS0lCz3DEMuAcpg5HPTPSs/4aWAKyu8SiMgMnyjofw9jQB2vhvTG0+wijdmb5QTuYsQfxroBTEUKoA6U+gAoopkjlFyBn6UAPrnPHM8UPg/UvOdkR4ShZU3EZ46d+tb/AJq4PPSuE+Kt3Evg6VXmMcZkUO69QM9vf8qAIvh1ZPbeGrUSPIzkE5k4JGfTtxXQ+JNF/t/QrnTS4jM67QxBO0+vas/wxIkGj2sfm7isa8k9eK6MXETqPn/I0AeM51r4cyHT59Pn1XSHBc3EKEsgx90j/PWqXhqLTPGfjiW7+wwrZRw+WiPb435554xkf4V2/wASfEAsdJjtLcxtdX7+Qis3OD1PHPt269RWx4A0KDSNGijVVL9SwAyc80ARx/DPw6hEn9nQjb91RkAV538QtK8G6DIJZdPieeQlvLDN859AAe9e63MyQwMzEAAc14qLW28X+OzfyBHsrFikasvV88k888jrQBwnh3ULXTddj1WTZpflg7bS1gZ3de4Zj9K7vwDBdav48v8AXZrWWNJC3lF4tuFyMDkdce9ekRaZpRbcbaAnGCSgrRtmtYeECLjgYxQBrJ90U6qa3kQHLjripPtcIGd4x9aALFZet2y3ljJASV3DIYHkEcg1NLqlumR5i7h2z0rC1fXI442+Yb8AqM9KAPm3SZF0bxcrAqlzbam0ZPHKscdvx7mvqzSpBJao4OcqDXybPJ9o+JUplYbZLzzPlXgnqBX1P4dk/wBAjz/dFAG5RRRQAUUUUAFFFFAFe9hFxaSwkAh1K4PuK8Z+HuoDRvGGoaTcmPJk2qQ+45Hp6D+Ve2kDrXgviBTp/wARr2Wa4hzHIjxiRMMwPIUEKc9x+VAHvSnKg0tVdOuVvNPgnT7roGFWqACiiigArm/HNy9t4XuDHEZTIQhQMQxB9Md66SuR+Icbv4ZZgsZCSqx8xsDrjrketAFD4d232fTW2zq5X5CgUKBj6d/xNVfi7qjWvgt7UqfMvJFjAABHBzznp0rU8A2wTSFm2Ro0h+ZYzlVxxgHJ44rj/jFdS3GpaXpUUe5TmThsHOcD69KANf4R6fdW+kNc3U4kebAwFAwBx1HWvTK5jwNAYfDlqpQKQg4H+TXT0AFBFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSH1oA8T+MqouvaazJbFShDF8l+vtz+NereHih0e2ZM7TGvX6V5h8aIpFvtLnSKN1ZthLqeOfyr0zw1ltDtsjB8sdPpQBtUd+lNA29B1p1ABRRSUALRRRnjmgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKgurqG0geaeVY41GWZiABU5rwj4wa/dXepR6PbyuIN6q8aKQWPc5yOPwNAGx4w+LWyb+z/DLRXE4JEs+Cwj6dB3znr0rhxrHjHUUkZ9Yvyzj7hhUJg+5AH4Cuv8LfDwS20LXcKRQjDBAoDk+7D/APXXp1jotlp9qIoYlUfnzigD5z8Gi80j4g2y3VxuLyfMzIVLkj3HT3r6ftW3QKfUV478VtLj06+0vXreGMGCZRK5YcDPYGvU9DvY7vTYJUZWDoDwfagDWooooAD0pMcYpaKAPEviz4Yij1O11QFdpkBcSMcdeevQV1nhbwzoMUYubWygDSLnzMbiQeSMmuj8VaFb67pEtvNgHGQ3oa8e8JX+tJd3ujaZfW5WGQj5uGUZwSvUUAe3w21rBHtVEA9B2qG81Ww0+ESXFzBEvq7gVwI8NavNI0d5rdw8EmAYwSQVyCRmtGHwVolr5kl2RMjYOJmGF9/8aALl18QLfyS2mWNzf9iyKVXPpkiqwv8Axlq1xsSG3021I5dxvk/AZon8WeF9AgaCKWMmM48m3TJz2GBxzXN3vxWuZ9W+waFost0+4AOc4YevA4Ge5oA3JPB+oXasuoa5cyK3UKzLx6dcUyDwPoNpGBM7yhQBiaclfrgnHWsWO0+IfiC5lF2ttYWrjG0sSR7jac5+pp9l8Ir1rZ4b7XLl0LDITIBwc85JoA2pNY8IaBCR9otcx5+VDvbjHHH1H51i3fxStrlGh0Cwe6udp2qyt17cAHP510Fh8JPDtoYzJbvcFOnnyFuevTpXV6f4d03TVAtbOGED+4gFAHjsl18UdaAEFrHZxbeRLhCx7+4rgvEXgXVrDVVn1u9jfdhpJizMOegG4V9ZeSn90Vk6x4ds9XUCaJMgbd20Eken0oA+XbbRPDlvbD7Zfme5Afb5KjYcDjr7j8aqaUthBZXcd1pU0jg5glVScg8AcYyPx719KWnw50KCOVJLOOTzl2yZUDcPoOKcPhv4eimgkgsUi8kggISAR6Edx/hQBx3wz8K29zZPd3+mQFyf3TPGNwU846dK9UttKtLVQsVvGgHQKoAqa3tYrZQkMaogGAFHAqxQBGIY1OQuKdwCB3pxooAKraheR6fYy3UxIjiUs2Bk4FWa8o+K3ifJTQLRgZWIknBYqCvOBke4z+FAHD3d+njLxnLqcgmMcbKsCgj5QM8EZ/XNe7aHYR29mjrGFZlG49z9TXC+BvDENvOlylq8cW3I3OOp9ABwK9QjQKuO1ADhwKWiigBCcDNee+MPiMvh/Uo7GK0M0kgIyX2gcZ/pXoTfdNeJ6pa/2z8UDHgPHbgvknIDdP8AOaAMK+17x8JprmVZhbyDMaoGPr2U8dR37Vy+qXvjjWbGa0ZmmhdvnUfxcdOeR34r6YttIgeGNpY1JxyDUg0W1D/LDGM+goA+aLN/H9jbpFGs4xEMblx5ft78fWtiLXfH0VwjCCd45F2urqMocHnPf2r6EOmW5/5ZLgjrikGmwbcbF46cUAfKF3qPiTU/FVvDfmZ7mIkxgpjHuBX0x4ZhuodKgEoIYICQTzXAzWUP/C6yko+VLQFBt4J+ufrxXrsEYEahQABQByPj7Urmx8MXssDhJFjPNeK6NofjR9EtpNNMcSF/Mz0J69a9S+Msktt4OlaEZy6hsHB69v0q/wDDvbdeFLORkIJXJDdc0Aed/wBjfEt7YPJdRZcD5QOR9SPp+tUy/wARLOZYzpd1LKON6sChHQd/xr6ISCPGAoxT/s0eANo4oA8Js7/4lNEY5fD0JZl4LSbdv15q5DefEWKMJNpER7ZWQADj0z/WvbFgRf4RTvLT+6PyoA8JudW8c2r7W0BpQevlycZzXP694s1l4pIbzQbyKQowRmhbHTnJHBr6UaCNhyi/lWVqenwPA++IMu0kj2oA+SrQ30fiG01K3hKOyCQlssuemDnp0r2fw58Tkt4xBqto1s69XU71PuMVS8Gx6drV3qcEcI8gTYVJFBPI5FdXd/DjRbiPzFs0VwSQUJXn14oA67TPENnqFss0NwjoTjIP+cVso4dcg5ryWXwheaPbtJpt1KSSDsOOfqa7nwnqMt3pyLcLiZRhqAOjooooAKKKKAAjNeUfFvSHMdpqkEKtNG2xpCGJA4I6ds16vXI/Ea2a58I3Zjj3vEBIFyB0PuMH6UAWPAmof2j4Ws5eM7AOPaumry34RaqG02TTnJ82JskFcbQexHY+1epUAFFFFABXPeNI5ZfDF2I7eOf5clHJHA7jHJP4iuhqte2iXtpJbuAVcEHIzigDkvh/qIuvDsLi3MK5ICBiQADgYzziuL+I3max44sbWCN3+yBASgY7SxyT6DitGK08X+Ebqa3srAajZs+UkMxyoJ9McU3w14O1O71+bVNbt385nbLeeQp5zwuM45xgntQB6RoVkLHSoIB0VABWnTI02IFHQCn0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABQelFFAHjvxwQQw6ZdFJXIkIAV/l455Fd74Ju1u/DVnMq4DRg4Ncn8cNPmufCUV1Ark28uWKdlI5P+fWr3wm1JL7wjbAbgYhsO45PHrQB6HSZ5xQKWgAoopMc0AKfakIBHPNLRQAUUUUAFFFGaACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK828beBr3VdSj1TTzB58TBgZFyQB1AFek0UAeOx+PtbsporOXRXEiD96VGR+h4/GqsnjfxRqTuLeMWq7tuBAzsOevQ/yr2GXTLKWTzHtozIP4tozQmnW0WPLhRfooFAHher+G9f8bRyo9zOIkXhrkEbj6hVwMj3rY+E3iGaC4m8O33Fxa/KuZd+QOPWvYvs8YHCgV4j440O98HeMIfEGjx3LQ3JJuBFGGVfrigD3FG3AEU6ua8I+JIfEOkx3MeVb7ro3BVvSuloAKKKKAGsoYEEZB6ivHPEGg6loPi+XVdF04NCRl1xhMHk7RnrmvZaaUU9QDQB4TcQfEbX7mGSFBaQN95CxRQPww3b9a1D8KdY1VE/tPXHAXHyxK5Hb+8x9K9iEarjCgYpcAUAcBYfCTw1atulshcNxkynIOPbpXXWOh6fp0ax2tpDCijAEaAVpUYoAYI0AwBin4oooAO1FFFABRRRQAho60tFABRRRQAUUVXu7uKzt3mmcIiDJJoApeINZh0PR7m/l5ESZC56nsPzrxjQ9Hu/GHi+bVL5JGCnzFkU4UHsFIzkD19qb4g1m58fa3JFbS7LS2YJsGSeTxwOpPH0r1bwl4fGkWYLyySSOASXxx7dPrQBuWVosECKFwQMVcoooAKMUUUAMmbZCzHoBmvIPCPl3fxB1KdVfjJwWyFye49eK9P8AEF/Fpui3VxNIqKqHlumfSvIPhFP9p1jVZWDbnl3FuMHnnpwKAPcEA28UtIn3RSlgo5NABikbgU0zJn7wp2QQDQB4/wDEMTaF4/0TXEJMMw+zPnO1ee/1DcdOler2T74FPqAa474q2P2nwXPOhZZbR1nR1AJGOp59q3PCuppqOg2VxGxdZIVO4jGeOtAHP/Fm2abwXeSAHbFsY7Dhh84yQas/Di0S38K2UaoUCoDtLbsZ56961vGNi+o+EtVt42KyPbvtI6ggZ/pWd8NmR/B9g6xGMGPBB7kcZ/HrQB2KjApaKKACikyKWgAqlqcRlsJkUgMyMBn6Vdqrftts5W9EJ/SgDwT4TK0eu6gjAgo5UhjXvEaAQ7cdq8O+Dn+k6jqlwY8K8xwce9e7oMR4oA5vxX+48NXswk8po49wcdiKh8B3Au9DgmLByRyao/E+/ay8FagVYAsmOe+fSmfCuPyfCdqVZiGG7a2cjPbmgD0KigdKKACiiigAqvfWyXdnNA6grIhUg98irFB6UAfPvhidvDHjiS0mkliHnmJlcEKeeAOTzXv8T74w2eteI/FfSYNH1qHWVlECS8gsxI8z2UeuBz+NeieANei1zwzaXCS+YdgVj/tDrQB1tFFFABRRRQAhUN1FAUDpS0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAc546sH1HwfqVvGxVjEWyD6c4/SvMPgtqRNxeWRLbVwwDBvpxkmva7uPzrWWPOCylcjtXz54EaXR/iTcW01wCzyOjKAASc5BNAH0SvSlpkZyo9MU+gAooooAKQjNLRmgAooooAOlFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVk+I9Gg13Q7mwuE3pKhGM457VrUY4oA+c/BfiGXwF4hvNH1RrnyUIGWT7p+p7V9A2N7Fe20c0TBkdQQR3Fcj478BW3iW1ee1SKHUgPknaMNnHIB9q5Hwb4svdG19PDusTOZvuqHQjn2JPT/ADxQB7PRUcUqyJkGpKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooqte3sFhbSXFxKscUalmZjgAUASXFxHbQvLKwVEGWJPQV4H418Xaj4u8Q22l6Y8kdirMroCVYtnHzDg+nFL45+INx4kv4NM0iO5k04uVmaIOhJz6gdOD+ddd8N/Cr2gnuriMxrI2FgOcLjvzzQBpfD/wAGR6FYh5Ubz5Tufcc5x0/Cu/CgDApEUKoAGMU6gAooooAKKKKAMPxcJD4avPKkEbbPvHtXl3wbtDDPqEhlEpaYkkZwDk5xXo3jiWQ+Gr6CKJpJHhYqB3IHFcJ8G45Psl28vMhmJcbQMN34FAHrk0yW1s8shwiKWJz2FePajrmveLfGFzpukai1rZRxDLREOOfUjoecjB7V69eQtPZTRKcMyFQcZ7V4n4R1a28I+JtTstbZbWW4lBjkdcKevBP+cfhQAzW9D8VeEbVNSk8TXVxaRuoKc888Z56Z6+tet+GtTOqaHa3LSpI0iAlkOQT7VU1q/wBPfw7dSyTKYREzblIPAGeOtcp8HWnOhzNuU2jTsYAo4A/T+VAHomrWq3ul3Ns4VlkjZSGGRyMVwPwnuh/Yk9gH3LaTNEDjjHbsOPwr0lhlTXlfhaVLD4k6/pkXl+S7B1WM8KRwRjHB5HQmgD1G5iW4tniblXUgj1BrjPhur2Wm3WlzzCR7S5kRcEcLuOOB0rtVwYwfavOI86N8WpY12+VfweZtwAdw6njrQB6ZWdrOtWWh2LXd7JsjX8Savo25Qa4D4qC8/sMPDFGYF5llOMoM9skdf6d6AKFt4/1nWLm4bTNN821jDeW6xs24joMkgc/pir+k/EbfeW1hrGn3VldTyGNd8TBCeoGff8a2vCsNmuhWgtFUReWMAdq534ovbLosKji6SUSwlACysvOee3r9aAPRUkEi5HSsjxXP9l8K6rP/AM87SVumeimn+HbmS90O0uJV2vJErMPQkVS8cyNF4N1hlOCLSTB9PlNAHl/wMgB0+5kKEO0uc8jPHpXuJ+Vc15D8F4VGhM4i2lnI3HOWAr1xs+TnvQB5p8X5RH4QuEL4yR1HXmtP4YMW8J2I5BEYBB7Vz/xjmK+HBGzEb3AI7n6cGun+HSGLw7aoChQINpXjjFAHbY4paKKACiiigAooooA4/wCIegnWfDzNDEJLm2y8SEAgnvwa85+EesSWmtX2jysE+YyKm3b7HA7c/Wvc5oxLEyH+IYr5/wDFulXHgnxqNZtgxUsgLbc71P3iTwBQB9AowZQQadWXoWpQ6ppkN1A4aORQwI961KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAQjIxXh2qA2fxnhR7ss7Hcq7AAqkdM17lXzt8X0u0+I+n/2WwW7mVVU4OQ2cfyoA99W9giiDPIqjHc4qW3u4LoboZUcf7JzXjWn/DDVNaTz/Emv3s5PIhjkKoo9KVtJf4Y+I9ObTr6eXT76TypbeZ87T6g496APa6KjhbfEr+ozUlAAeKTrS0Y5oAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKO3FAAfeuC8f+Ax4jNtqVjItvqVo25JMZ3L1wa7wccUYoA8h8H+OtU0/Vjo/ih4I2ztjn+4GPHBzXrFtdw3MSvFIrqehU5Fc34u8Ead4lspA9tD9q6q7L3968tutY8SfC55be5MU+mn5rchcKvP3R/nvQB77RXO+EfESeI9Dt79MjzFGQRjBroqACiiigAooooAKKKKACijtSbh3oAWioZbqKEZdgB6k1mX3ifSNORnu9QtoQoyQ8gBoA2aY8qRjLMAK8t1T406YJJodGs7nUnjBLPGu1B+J5x+FcVrV34x8YQXb3V+2m28OcWseUJOM4zxu498UAer+KPiToPhlCs9yJrn+GCH5nP19PxrxzXfFeqeOb+Czu9Ri0+ynkA+xrLhth/vY5yfetT4baDp955iTwv52AxaVQTID33YJro/HfgJ5bSPUdGRUuoCp8uMY3gf4A0AbfhHwdBpUcJR1EaA4RR97Pqe9d/DEsaAKBj2rzH4a+LZdVR7a9lthMpwsaONwA7Yr1FDkAjFADqKKKACiiigAooooA434kSLF4Q1Bvl3NCUGWCjJ9zXM/ByPy9FIDpJ8331B5+tbHxZvUsvCFw7xrIGO3axIz+VUfhKmNJY+V5cZclFB4UegoA9MByOKy9Y8OaVrtv5Oo2UNwm4Nh1zyK1Fp1AHk198FbW5u2Carcx2Mjl2tx0HOcL2A7dOleiaHodroWmQ2Nom2KJQoHetXFGKAGkcGvI4oxZ/HC+KBV+0W6ltxJJOByOMdvXtXrrdK8lvrdrr40F2KqsFuuMMAxyPzI5oA9WiOYwDivKvH7f2d8SvCt4MJ5pkhZy2MjI4/8eNeqQ/6sD2rx34zSKPEXhbEsYeOd2AJIOcpj8OKAPYbVt8Kn2pmoWEGpWMtpcorxSrtZSAR+tRaS5axi3HLbRk1foA8v03wz4r8JXd0unNb32nytujikfZ5XHOB2zz+NUJtG8X+KdWifVbOOysiSrxq4J25POcZz36d69fIB6ik2gHOKAK9larZ2scCKAkahQB2Fc18Rbz7F4H1SVwOYtg43ZyQOnfrXXVwPxbVpPA1zGhjDeYmC/Tr+v0oApfCazW28LWxXb8/zHb78/hXo7DKHPFcf4BhWLw7ZqoAUIDjGO1di/Kc9PegDxn4zNGBYpIygFuVZsA+h/Miu38CxsuhwK2wsqgZQmuA+NLLLqOj242lmf7uRzyBXpnhCLZo8A8sIdgyBQB0g6UtIOlLQAUUhz2pec+1ABRRRQAVynj7Rf7X8N3KRopl24BKk/wAufeurpCoIwQDQB4x8NNcudA1Q+GNVZExnysuCc9x1r2dWDDINebfEnwxFcaadTsmhtLq2PmCQ7UyRyDk8DmsvwL8VrW8MelatOF1FTtYqMo2O+RxQB69RUUM6TKGRgRjqKloAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAIbqdLa2kmc4VFJJzXzlpl7F4s+M0l4VHkwkugycjHHOa734y+OLPRtCm0eOUtfXIGYwP4M85PavFPBcXiW51C4k8MWu15WAaZ8N5Y9MmgD6Y1zxHpvhnRjc3soGOEjU5Zz6Ad64nQNC1fxtrUXiPXyYbeM/6LZquMLnILe/frSaR8Jrm/u11DxVqc1/OGDJHvIVPYV6vZ2sdpbrFGMKowPpQBNGuyNVxjAp9JgdaWgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAry341yxx+F4oXQN50wUg+nWvUq8h+M80qTaOgO1GlIzvZf1H+FAG98MbSK38LW8cb7geT8wPX3FbHifVNW0SIXdlbC7g6OnAMY9c9xWL8Mk8rS5sNuXzTgiXzM/jWp8RtSOm+C9RnRdzmPYBkjrx2oA8+0T4620kc66tbvFMpwPJXcP51pQ/GzTmUM8ZXPCocFjjrnB47cYrK+FHh6C7spZLq1Rmb74kGck8967+T4Y+FZpzO+kQGQnJwCB+WcUAYH/C5tMMiFIS8JxudW5XIzyKuWvxa0ie9MTB1jwT5nYfX0rQk+FnhKRNraNBz/dyP1Bqm/wc8JPgNYSFR0H2mTj/AMeoA1U+IegSSpGL2MblLAswA49zWRd/GTwpatsF20jdD5abgD25HFKnwd8J7gWsGIUbQDO/TrzzzWhH8MfCqQpF/ZMJCnOSSTn65oA5K4+NaXhMOiaRc3UxOEMmEX3z9BWKviz4laope1isokcEqNvvwOfwr2K38NaXbBRFZxLtORhRWgtnCmNsYGKAPnibTfHHiC4SHVr6+kgYgukEe1VyPwz2/OrVp8I52mEksPnBehdmBP1BBFfQC20S9EFPEarnAHNAHnnhv4bWWnWXlXSCYMPmRhx34x0xya6q78P2s+mTWQhQRyJtxt46Vt4ooA+f7ayv/h54x23Twva3IBZlkKKuSBkKele1WlxFeQKyOrqwBBByDWF8QPCMXiTSHeO2SS+hQ+ST/Lr/ADryTwz421HwhdXFprZvQI2IdJEDZ5xweMfmRxQB03i7Rm8I+J4vENjAxtZJAZ9spyGOc4XGMHjnNeo+H9TTVdLguowQsqBgG61414y+JVj4h05dJ0lLuSaV1DMEwAM8jGcn6e1ereDNPGmeHrW3UMAEHBBGD347fSgDpqKQHNLQAUUUA5oAKKKDQB5d8Y7/AMnw9Cik4kl2/KMk8HpyK0fhlaNb+HomfdlxnkYrA+M8wj061QjAably5G0Y6iup+HWz/hHbfYxZcZzQB2oGBS0dqKACiiigBkjhUYnoBXlPhvfrPxC1rVD5bRRyG3RkOfukY/ka0vij4wj0jTRpVo4bUrzCJGOwJxnpVr4feHl0HRokKf6RKA8zddzkcnNAHbJhYyelfP3xkvTfeNrWGEyuljbgyBOiszDHfnqO1e5avqcOkaXc39y+2GCMyMfYV8vHWJNY183kqP5moXZnYIfuop+XPtn3/hoA+oPDrbtJtzz/AKscEYxxWvWR4dDrpNuJCC4QZwcjpWvQAUUUUAITgZNeZ/GuZk8AzbGKt50eGHY5r0xvunNeX/GCUzeG5LXA2E5x7gUAbvw7Yy+FtPdydzQLuBHtXYv9yuW8CR+V4asVCbP3K8fhXTynCE+1AHiXxMFvJ450pZIpGKgAYbAOTzXrmgxLHYRqoKgDjNeJeNbqaf4tWtuJFEaou7Jwe5H64r3LSc/Yoic/dFAGjRRRQAUUd6KACiiigApCcUtch8QPGEPhTQmmLETyHbHhd2PqMigDzn4veJ5bu4bSYWk+zJwUQ43sM9+T1H04rm9J+E92fDaarMkjXTjzDAnDBcduDz3xit74eeGJfF2sy+J9ZQsqvi2jI2huepXJ9u9e2kRWtuxYqscY5zxigDwDQPGXiDwXGyXEcuoaYkm1ssd8Ptz/APq+le4eHfFOn+IrBLqzmDA8FTwVPoRXj3jIHxZrc8dhGbaEfKJEPzSkd9vcVRvPA3iHwcbS+0m+mUkbpnjjdgTjqyjIP40AfRYIPQ0teM+D/i23nrp3iQrDcY4nwArfUDocV6xY6raajCkttMkqOMhkbINAF6ikDA9DS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABTXYKhJPSlJwK8u+KfxHttAsm0ewIuNTuVKbEbmMHucd/SgDyr4k3/8AwlvxHWxstr7XEOPLAz65IPP6V9AeD/DltoWi29tHEqbUGcDqa88+Dvglra0fWtRgYXU5yokXBUV7QiBVAHSgBcYpaKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArjviJ4YbxFoX+jxB7y3YSRYA3HHUAnpmuxooA+eND8eXPhO5ayudNlhjMzNNHIeUJ64PcDHpS+MfGzeOHh03T4m+wo4Msjgjce46jGPfrXvU+l2VyzNNbRSFhglkByKz4PCml2lx51tbrAS+91iG1XPuKAMrwH4dTRNIQDfuf5jubOPTHtXY01VCDCjAp1ABRRRQAUUUUAFFFBoAKKKKACiiigAPNc5rvgrQtfmSfULBJpU4BJI49ODXR0UAcBZfDHQbS8S7FnskVy6qJDgZ46fStDW/GWleG0iSVy5ZtuF7Duam8Z+JrXQdJmMlwYZ2Q+XhC3NYPhjwlHeJHquqg3E0igpHIvES9cAeueaAJ5viro8chjEdwTtVlYptU7unJ6fjU1l8S9LuGYTn7NGrbPMdxgn/PrWjrGmaVZ6a8k9rG0cI3AFecgYGMflXlCeCG8bu18IRp0AI8oqN24eu3oO2KAPQ5Piz4WilMX9oKxDFdwBxkenHP1HFVZfizpS2UV1HBcywyMRuRRgY9zXIX3wk02x01pjfuJflJluDnBAxwBjnFVPDmh6Ba3cfm6nLcsrMzI6bUZyeoBGfwFAHrmkeM9I1oL9luQWPRDwa6IMHFePax4ORAt/ody0LwfOYwzNk9eBng11/gnxC+q2EgmlSSSFyhZQQD+fegDkPjikv8AZVvsTcsjEOTjaBj+db3wpYDwrZxhydsYPPoaPipGlx4ZmXIDhSVwMnPtWH4H8XaVYaPZW8lyiyrEqsAp/oKAPYRS1zdt4y0eV2j+2orL1D5X+f1rQj8QabMf3d7A30cUAalQXcy29s8rttVFLEnsKpXeu2NpEZJbmNUHcsK8q8R+L73xfI+m6QG+ylgC4I2svct/QUAVbCJPGHj+81h1ka0tyogDD5D23Zz7V6vZuxiUqCFA4I71ieGNEWy0uO3djlQATk5JrS1zWLLw9pE17dyCOC3jLE9z6CgDhvjF4oistC/sSNt15qLKgjU8hN3JP16fjXlngfSxdaxOfJaSRR5UAldcjtk/TAxVVdWPibxnc6zeFwS+63i3btpH3RjqQOOldt4DtHXX7uzeQSSo6uXKksOmevA6e9AHuOhWv2PTLe3yT5cYXJPtWpVS1KpEoyM4q0CCKAFooooARuleSfGKbZpcMO1h50oUMDjBz1r1osOfavI/ivcR3Os6Dp6fO5nMjgdAg9fx/lQB3XhbbHpUEa5+RAP0rXvZlW2ZmOB+Vcbpuvw21gXWWMckBc8gjrXM+MfiPb2VqUiuYmlbIEQyxb8ulAHLeIJI7740wIJjtUIQFUnkf5/WvoHTwFtkyOa+dfA2kalrfi19beF4lZg+5c4bkdz9OlfRtpGy26buDjmgC1RRRQAUUUUAFFFFACE4rwD4i6nPc+Njpk1yfKlmSNleAYVOcYznPJ64/SvoCvOPiB4GbVLuPW7Qb7uEjcrn+Edlz0oA6vRba203SoooEVUVflCgD8q4jx74whknk0eC8SKEIfPkjAkYt3QDt/n3rL1P4h6lp+k3FsmmtFdJGNrO2RzxkAc+ntWL4F8EarrZS71gSC0di5jYjD85zggn+VAHcfDvTYNjzwRbISdwzbmMnPPf+lejeUhXaVBHvUNjZQ2NskEKBUUYAA6VZoA5TxF8P9E8Rw+XdWwQ7t2+L5Tnvn1rzK+8F+LPAU8l74ene6t2bHlld5Cj2xx+Fe8UhUHrQB45oHxheAC28SafNZXAbaG28MR14PSvRdH8W6RrKqbO9jkLDcFDcge47VJrfhTSNetmgvrKKQMMZ2jI+hry3xD8HpbGeS+8O3LxOoBjiiAVwe/Pf6cUAe2BgRkHNLXzraeNvG/hW98vVy91bg874vmB9OAK9E0P4vaBqUaC5uBay45WXgfnQB6NRWXp+v6ZqW4Wd7BPtxny3BxWmGU9CKAFooooAKKKCcUAFFJketGR60ALRSZFMeeNBlnUD60ASUhIHWuV1j4ieGNGjka61e13IM7EkDM3sAO9eX6h8QvFHjbWF0Xw3ANOtpAS0zEO+z1P936daANv4pfEG7sLiLRPDt4BqEjYl2JuaMUzwF8MJYr/APt7xBJ9qv3+Zc8qufb1rX8DfDGLQ5Dfam4u9QZtxlOT/OvSkQIgUDAFADIYEhUKigKO1S0UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRzmigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAopCcUtABRRRQAU122oW9BmnVBeRvLZzRxuUdkIDDqDQB5lp8Fx4p8X315c3E62dpN5aW8i4DEE/pz0r0y3iWJMKAMdK8j8L6zd+FtVudO1oBFlmLrOzg4JOMHvj0r1iC9ilQMrqQQORQBxXjm4N/qlhoUYyJn3z8sMIPp9O9dZZWkdvaoiIqoqjAAxgCuN8Y3KaX4o03VH2+WcxyPgZAJAHcevvXa2lzHPbIVYEEfnQB5l4quJ9cuL3yrhktrBirwKSBIVIJJJHH1FcBJcajd+Rc2cX/EvjGwOriVl9eSK9A8TB9A8STNc29t/Z2qN5X7r72ccEr375PTj8+O3aj4aWa0gtTc2Vw37uZSXVQcBQF3dvY+lAHT/DvV5r+7u7OZxIygPvyvzA9OAOOK2NGt5dL8cXlksyCCZTOkWQOvXAznrnnHeoPh5ol3psM1zfCLfJ90LGFIX0J71Jb36ah8SJ/LlXybWFRuCg7jzkZ9OaAOm1/w8uuaVcWc6qyyqeT2rx+7+D9ylwxhu2hBPygZIB+mc174L2FU5kX865PxH448P6KB9puPNm7RxJuJ59enb17UAeZD4deKEDbLq0kj6BZEznHrnr0qhrGna1oVm8+oQWqLtz8km3OOcAd+nSusm8da3rl39h0S1jhLtt84kOV5644GMZp+l+AtZ1TWTe65M2ApUIspcN055zgcdPegDymLRvEPie6DWlvKsIPzHc3AP8J/Lt717D4K8HS6HGjTA+a2N/J5Nd3pui2mlRiGKJIlJ4CjqT1NWb26ttPTzZpUjTbuJY4GB1NAFa7voNKtWnuZUijQZZ3OAPqa+ePHnje88YasttbRFtMtpOEjyzSEH7/A6f5711/jHV9T+IGoDw9oihLIMHmmZseYAcg4646H8RXUeD/hpFpGJ70pPcFt2SgO04xwev8A+vpQB4pothrVpfw3jaTclQWIl8snGe9dRb6xq2k3dxc/ZngncAnMf3+ccYPJ5r6CTTIEIXy12g56U+TSLWfiSFGGeMigDxS2+JOpQuqTz26sUVtsgZTk9QePpXS2XxNYRRNLJBLuXLbGHHX361383hrTbhcS2sLfVBWXP8PPDc+7fpVsdxyfkHNAGMfihZQSBbhkXI6hhjP1qRPirocinZcKSOvP6fyp1x8IPCk5UnTVUr02Ow/rUSfB3w0kBiWKZFJz8spz+dAEsnxM8PvF/wAhCJWY4wxwRXifjnxLHdeL4ryxnW8hVSqKhO7cc55/pXqOpfBHTJgDaXM0XB+V8MD9as+HfhLpmjNHLOi3EyfKrMv3aAPJNB0rxV4kLQ2pNnCW+Z5Mg47gc16f4d+EFhZqsl9/pM27cSxOM/jXpdppNtaALFGigdgK0FUUAZunaNbadGqQxKgxwAK1BwMUYpaACiiigAooooAKKKKACggEYIyKKKAKUukafNMJntIWlAxuKDNWY4UiGEUAe1SUUAFFFFABRRRQAUhANLRQBTu9Ms70AXFvHJg5G5Qa8z8SfCKzup3udPjjA2sPKcexxhuufrXrFFAHy5N4Q1TR1WSGa806dDiRmf5XGOMMMYPPT/Ctm21vx3pKCdNRW4BbcUl4IBOOjV9A3Vha3sLRXECSxt1V1yDWO/gzQ5GJOn2/IwcoORQB5tb/ABY1vTmA1fTbdo1GZHhlGV6Dkc+tS6h8c9Oj025VLaVbwDCRv0I9c12E3w10Sa5LNAPJP/LIcDPrx35rB8QfC3Sk069ubaFDKsDBN8QbHH0yTQB1PgTxHL4l8O29/NEEdx0Gfz5rqeK88+E11NN4St/O270Jj4GOAcV6GfXvQB498UfGGo+GfFFj9gDuSikxjJDDOMdcD69ax5PjN4jjuWtx4fiSULkBpi3b2wP1qv8AFbF58RrO1QkOYFQEHBGSeR713Wk/CzQjpQW4tS00q5kkLksTj1PNAHn83xT8Y3SsVOn2cT5UMQSQfz61yl/qeu6nEkl34kv5mlXKW0CuN2Tj1xg+tfQ1j8PdAsYfLSwhcFs5dQT9PpWrH4Z0iOUSrYQBwRg7BxigDwnwz8HL7U5o7jUkSGA4bY65Yggcdua9t8P+ENJ8Ow7LCyihz95lHJ+prfSNUGFAAp1ACAADApaKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSY4xS0UAc5r3hHTdaBea3UuevbPvx3rirjwjr2hzJLpupXrwg8Q53BQBxnJ79+K9YprIGUgjOaAPDNb1PxBf6fd2OqaNHdIn3HZgjZ52nGeO361m+FPibPokq2OqWF3FZLgJK53CMHoM+le8XOl21yuJoUfnPIrndf+Hmia/DHHc2igocq68Ef4/jQBFff2X4y0MqsqTwyqMNG344yOledXmkeJ/D8cQsXV4FYhvNcuuOMfTv0FbFx8OdV8O2bHw9qV6SPuw71C+vPT6cVjw6x8QLOTypdLS7jTAPnL5bN+vP4CgCOLxX4xuLVo30nZBICPOtkZic5HHPHY5pdC+H+orElxcRsWn3NNH9oZX5IIPoCKlPjrxDbMRP4aZIwCQAG3NgjoMe/61YPxTvYYVkOjqrM5QI7spJGAQRt96AEl+G+pSyKqXcqxA5xLKSxXGNucfr798c7enfC/To5TJetLO4AVNzk7FByFHtmqB+LhjSLzdDuE81tm8uMA8jnj2NSN8Vbsp5MHh27e8JIKg/JtHG4NjkcelAHotlpNvbRqqRKu3oQKvuYYEyzBVAySeAK8oHjrxjeSE2egpFEEDATElm57Y+uaqQ6H4v8asH166uLKzddptY22fXp1/H1oA6rxF8R9HsyyadINQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//ZDQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjo4RGhML0E9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "8DhL/A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Kz3LUSxHZUSkE5+AEPR+atVk6Yec4MMo0kpGHZpmbZ3qfZ8hHiWHIoY/G6MRf2UpmgMR1vtLDRc=" + ], + "X-Amz-Request-Id": [ + "D61PP7NBPXWY7SY1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "84bcefcc52532b8c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "8DhL/A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "IZo7Sc93onsCEXMgN/20OqnJUhp67kZC6Ayv8lzdD02b9x3B0uYZU9ByU1AL2fxbP1U9zLI1FDw=" + ], + "X-Amz-Request-Id": [ + "D61HYCG45FNW8RWZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + } + }, + { + "ID": "d4d57d526531e5c0", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "LROHt/OgX3yJIrRm9QzkKaKcqkz6kLT9XBcGZnYbOWr+w2MKu6APY1OXTcnOdjZaTZpfbfYzXBU=" + ], + "X-Amz-Request-Id": [ + "D61VMA91R8Q0RXST" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "82f8df2efdbe6c1a", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "BZcNFEXsuo9J6UM5sPg3lQF3G8xORD9s8tabOQxZgY+1MgEUhCcYq5LLuvlpkDdYG0fKd8aaALo=" + ], + "X-Amz-Request-Id": [ + "D61N5J4F9VKA4X9K" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1a6b95c515776217", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "NSXH64sqmdK0CvHYmaklu2fz39aPEHQpUA2htoC/c2fwJHsneqiFFfpBmtn9c6U56FtXw6Yu50k=" + ], + "X-Amz-Request-Id": [ + "D61G7021B3CQNPWW" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay new file mode 100644 index 000000000..a08f9870e --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay @@ -0,0 +1,397 @@ +{ + "Initial": "AQAAAA7ffPPrMY9elgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "473622a5c761817d", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "38474" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "38430" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "image/jpeg", + "BodyParts": [ + "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9HsyyadINQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//ZDQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjo4RGhML0E9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "8DhL/A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "QdMW5FuNwZ1PEHPAjaCEnPhZ+2EF5QcRREZp1v68pUzv9n4aJab4joEvnHR6jqAaEzEuQmASpYs=" + ], + "X-Amz-Request-Id": [ + "D61Z4FKX3HEM7WPC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "bc82fe6a7db32241", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "8DhL/A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "NIlVmUVcavVLJSnXYzLMohyRXDAU+hRbK1TB/F+5fZcwUeLbdYs4a9xHayKuVLKwtUyewtIIlq4=" + ], + "X-Amz-Request-Id": [ + "D61GX96J4JQB24S9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + } + }, + { + "ID": "2fbc555a45962bd1", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "BpCciJdfYgXO5jRha9E7LDXbEtRTCUvVEPFriQMYgUYBxToFW3Wany43N+hhzP/BYX8ZKzkKpfs=" + ], + "X-Amz-Request-Id": [ + "7TEFQE42HKXVTZHR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "5a04965fa64fb787", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "cLQa83cLTKP/HoLt0D5JW/rniFUZwjnw145CYpDdyeVj/OSlcv5E2/E5yn+Bxxf7YppnuyRIEWQ=" + ], + "X-Amz-Request-Id": [ + "7TE16VAS6WKYH0Z9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "60eb8a47a6b2cae4", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:01 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "60D3J26BXCmYO2GkV5EafvVBG+vbNy7UkfgAp1Yvdaz097GN55CH5FsWjY61dOPTSpXMiue5y4c=" + ], + "X-Amz-Request-Id": [ + "7TE2YZXBQQJ0RX55" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/a_small_text_file_gets_a_ContentType.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/a_small_text_file_gets_a_ContentType.replay new file mode 100644 index 000000000..715f07145 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/a_small_text_file_gets_a_ContentType.replay @@ -0,0 +1,397 @@ +{ + "Initial": "AQAAAA7ffPPrEUysFAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "75dfc01f44c2c003", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "62" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "20" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTQNClRoaXMgaXMgYSB0ZXh0IGZpbGUuDQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjpzUURpRVE9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"3f3309312cc3264a1389b2d263dece8d\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "sQDiEQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "O5n6dyBCUoAkjYKN8JndgCzmL3O3J/qfVQTKuWxnPqC1XPDiHouRjb701HleK87Gkk0aVV9WXVE=" + ], + "X-Amz-Request-Id": [ + "D61GA4F4WRQNYSCB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ee044a57bdb75b5d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "20" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"3f3309312cc3264a1389b2d263dece8d\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "sQDiEQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "MvQ1c1WBUKhaw2fvxL3o2KBcdh7Y/IKilk/ulAEWi5qFX7/sfL90ShLWXI88bl/riIXrfvjPuoQ=" + ], + "X-Amz-Request-Id": [ + "D61X4AW76C2TYK0R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "VGhpcyBpcyBhIHRleHQgZmlsZS4=" + } + }, + { + "ID": "d1df4da1aa2dee00", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "20" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"3f3309312cc3264a1389b2d263dece8d\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Hzhs8v5x2GwomqNO+zQD1Wo/Dwn84Qa7QhuHVzOfP1D4UaMbXQXpnPD2DAx4Hm9RlQ+Z/racHGE=" + ], + "X-Amz-Request-Id": [ + "D61K5JSXWGB2JHH8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a3062392508ffbdf", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "20" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Etag": [ + "\"3f3309312cc3264a1389b2d263dece8d\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "RURThuIkAGc+aa3cenSRUnuNmRhzNXLx0TzDCKPoA3Vuw5HXmTnZr9paMXnbwI6gPuMrigbd7Ig=" + ], + "X-Amz-Request-Id": [ + "D61WSX2E71N4YPA9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "67c392f1c90ea94c", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:00 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "4o83W1SmuezfZAPW0wGWxi5uuS4PmLznineTIeeolzBzCXBG3coBMd1NT+k7Lsg9ZZ1rFNPBa7g=" + ], + "X-Amz-Request-Id": [ + "D61Q93H87X0ZKKPW" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/invalid_ContentType_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/invalid_ContentType_fails.replay new file mode 100644 index 000000000..e26f37ad7 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/invalid_ContentType_fails.replay @@ -0,0 +1,105 @@ +{ + "Initial": "AQAAAA7ffPPqAQnzDQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "7d4c3ab6c8372596", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:57 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9DyjQgpwAtirr7iLtD4vuE4zZRI4DDJRL/nLA5OzRSmUHYga+tbmrETleMue6YOplf4x5VAF5+c=" + ], + "X-Amz-Request-Id": [ + "2037YJYMC90VZPXA" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1yZWFkaW5nPC9LZXk+PFJlcXVlc3RJZD4yMDM3WUpZTUM5MFZaUFhBPC9SZXF1ZXN0SWQ+PEhvc3RJZD45RHlqUWdwd0F0aXJyN2lMdEQ0dnVFNHpaUkk0RERKUkwvbkxBNU96UlNtVUhZZ2ErdGJtckVUbGVNdWU2WU9wbGY0eDVWQUY1K2M9PC9Ib3N0SWQ+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay new file mode 100644 index 000000000..55a088637 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay @@ -0,0 +1,321 @@ +{ + "Initial": "AQAAAA7ffPPpMiFzlwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "dfcbc7445e865cec", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Content-Sha256": [ + "UNSIGNED-PAYLOAD" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Ib4RNSzi+zzzVGDZU9cFLuApq+fyLQPWfK8n5J3T7l+Jinl4jiQUwWVoT3Y0cXxukY2DTGG6f/o=" + ], + "X-Amz-Request-Id": [ + "4NSFPDXGS0VYMT1J" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c8ac6eae719130c1", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "5Q9CaHhDl0i+sHZN5CHzzi2pyI1xYVQFneiLp/8WdTusrtHv6Ni5nl5V5msW1I4EAtH4fMm0etY=" + ], + "X-Amz-Request-Id": [ + "4NSA5N2BDND4PMH7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b1b74d3ea692d807", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "0/ySQYXqX52fWRmN2OsbiWbiugFQNbwKLo3Z5JKty0lvHbjIDXskSDgFAXVZCVenyZazw6LwwCE=" + ], + "X-Amz-Request-Id": [ + "4NS3MCW5VCZVPAF5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "67e44dcc80b16519", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "w8HfHPeLcySO9cYBal/Spv8HQoD+ECgRARhlSg0/lMaalcND4jxS0L4pMl3hLhjhq+kBZacvnDc=" + ], + "X-Amz-Request-Id": [ + "4NS75MPGJD0GFQCN" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob.replay new file mode 100644 index 000000000..aac239a75 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/no_write_then_close_results_in_empty_blob.replay @@ -0,0 +1,321 @@ +{ + "Initial": "AQAAAA7ffPPpJxA9cAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "02335ad04acbc120", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Content-Sha256": [ + "UNSIGNED-PAYLOAD" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "6nFsG9CnfuoxSQXO0mRHLZOEBN6A5E8JlLwdTtdL6vm1Nkx34C3cAVkSPe7VLZhdGIfxO72Av4qTHwzqpStV4iaBR3teWqOXRYhScfaXlgs=" + ], + "X-Amz-Request-Id": [ + "4NS5C0YEEYM7PDQ9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "935929884233c8c3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "uVgCOamNSSmZoNZwnxgc50EHtG+3ysJZGzZtQiBjFUrrTUbQqNqfnBbFZZ1+0JKGVIbh8ckePM8za/wHV726gpon4YJWu00x3uXKt4RjldI=" + ], + "X-Amz-Request-Id": [ + "4NS0R5XT5B7DHWX4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "17774add4685ed97", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "SoWDA0Qa++aqiQ6LP9LK28wO6KlvwN640S6IlFGZapFEK0JQjdaNIS7TNs7lGfLwSfSj4Fc2cKGzhO5QVAnXNjMY9ZyLVHF+uUSX/+YQr9U=" + ], + "X-Amz-Request-Id": [ + "4NS608WKBAMATSKE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "9a96fdcbbf1533e3", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:58 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "a4jIxIDx+MGKvbbKksXtK92JfkmtK9YeUFEPLjIrbTreXyr1wiMSYKTvMdZqnzx6hfWcyQkFLNCSjerzuDIo5hT/gUvRCBfQG4PiO+ddBqg=" + ], + "X-Amz-Request-Id": [ + "4NS9PWY1WA95GFF2" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/write_to_empty_key_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/write_to_empty_key_fails.replay new file mode 100644 index 000000000..e698adbfc --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/write_to_empty_key_fails.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPPpJv8EdAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay new file mode 100644 index 000000000..ccc516c79 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformance/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay @@ -0,0 +1,397 @@ +{ + "Initial": "AQAAAA7ffPPqHsmkbgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "5907c53365d19119", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "6398" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "6354" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "MThkMg0KPCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+DQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjplQ01DcWc9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "CLh/TAAxrYvQL8q9bIiP89n2o9XX0BjhdrJQPPgXKQrcMjylSlEnGd2M0jsOdm/rc2oQChHmJCE=" + ], + "X-Amz-Request-Id": [ + "20394DSYWTJVD54C" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "71f8608e0ceeb1ec", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "c3OkStvi/pO+W1EEkcA3HM1jMKCDwyTSNsCuSyitJ39yLc49tUtoJyOlPhJU/YbWKqnkffDp7T4=" + ], + "X-Amz-Request-Id": [ + "2033Z40GM5VE580F" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "4b795b4d47c00003", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "FIAtRbdpMvsiGh9QX+nZqnxJ2YrtDxCstpUzaSHeMssqePnBu7TtVgbKgtAiPCRrWvQFiRyj4X8=" + ], + "X-Amz-Request-Id": [ + "2033XBGCX4ZQQ51N" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "d1438d52a0b328a5", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "edTBRSKJbyg1zd248x6o9SWLNSrURimTpoGpdUHAPAMOW7js0h0ddqNn4WRdkC/Wpjo0hAFqHy0=" + ], + "X-Amz-Request-Id": [ + "2037NTJNTKAXC22P" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "94d949ec2499f911", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:36:59 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "xEDNcfwdwzmkKSy5C1iDarFOrddy94Rxt8RNR2Hyp49DB0JCFWF2WrzIb8FqhSAGwKN2CGGCrEs=" + ], + "X-Amz-Request-Id": [ + "2034J7NA74P0M2YS" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..e286e5783 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,763 @@ +{ + "Initial": "AQAAAA7ffPQNOqBcuwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "7bcb81f288f24580", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KaGVsbG8gd29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOkRVb1JoUT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "8Ysgdt49rx6y3Ezp4Avc5JD8yXAaLltQ3YbTr5fxHQOlZ6SToauy+ysYn20PdPW24SIzW8aJYPo=" + ], + "X-Amz-Request-Id": [ + "8E3EHAMBA64N0N5M" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "105dd7fe8498abfe", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "HfB6XwxpBcUXVbJFhZkXXyIi6YdmoIXWHAVLQYgKO6Ob4KoXCo9x7MBbft/FU/sK3AIENRD/+20=" + ], + "X-Amz-Request-Id": [ + "8E311AR4SXVYYPP0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "03e87e4c137185b9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "hQbGGu6ejnZ57FPBUzAi6Ii81FONlYgdAZnSvtueb6H8yi3/8TMga6wASxXrrQpurr2MlLbXH7k=" + ], + "X-Amz-Request-Id": [ + "8E36ATSZT0N4NEG8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "0d4cd67717376f92", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=1000\u0026prefix=mydir", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "a4CFBK+W+KulW1c57nvhKsUHRzXftu1bRMYHADzjVZ8x+YUd77jraa1/onUmjvoj4imxf9DNhTM=" + ], + "X-Amz-Request-Id": [ + "8E3AGZQ9HTH98AN1" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bXlkaXI8L1ByZWZpeD48TWFya2VyPjwvTWFya2VyPjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5teWRpci88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "b01eac2f91ce1960", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=mydir%2Fas-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "OJhqPpfAyWJSyZW+goQDWcK8oxyK1wn+Hfp35YoycMfBIR4/0fjrROnx7PakLA8aLljaqMy0Vig=" + ], + "X-Amz-Request-Id": [ + "8E38AB9MHA2TRRXQ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bXlkaXIvYXMtdGVzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5Pm15ZGlyL2FzLXRlc3Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzFUMjA6Mzc6MzUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjExPC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "91ee884bf96792a7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key-does-not-exist?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+dFXBhaxBJ5mNwvrCgQJtxK0BKwx3wNuj18CsVIVGnS6Ps/HmGN0Zyk5jCUcSY5Fy9y5TN0NlFA=" + ], + "X-Amz-Request-Id": [ + "8E353SR1R5R0PZMP" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5rZXktZG9lcy1ub3QtZXhpc3Q8L0tleT48UmVxdWVzdElkPjhFMzUzU1IxUjVSMFBaTVA8L1JlcXVlc3RJZD48SG9zdElkPitkRlhCaGF4Qko1bU53dnJDZ1FKdHhLMEJLd3gzd051ajE4Q3NWSVZHblM2UHMvSG1HTjBaeWs1akNVY1NZNUZ5OXk1VE4wTmxGQT08L0hvc3RJZD48L0Vycm9yPg==" + } + }, + { + "ID": "e1a1282dbdd43124", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fmydir%2Fas-test" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "YFqvFsKtUjRPBWLcq8kouS3fG6vl29ugrpKg2wdOxIkfhhuIJERViPWH0+W68kP581fiZ3HA0jc=" + ], + "X-Amz-Request-Id": [ + "8E333M0DK82KFFAG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjM1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMiPC9FVGFnPjxDaGVja3N1bUNSQzMyPkRVb1JoUT09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "399417678d95fc19", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "JLkqIF5AvHTPilbEZeCc/HUChCTNSI75ykyjj26lbPFg97TL6IVPGwfRUjkmMIJnYAVcuGfQCfY=" + ], + "X-Amz-Request-Id": [ + "8E3FSA766BTR8HNM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a46222bd3bfb2944", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "QUqkhsrHbnvUYzFvpjvajT5OTX87pHqtEirZGk1PUSArB9PHBYGFXYzTk2gUh410QJbIDYMpoIU=" + ], + "X-Amz-Request-Id": [ + "8E3F91EN545KD6K4" + ] + }, + "Body": "" + } + }, + { + "ID": "e83c82fa3a5b8de6", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "leDSTMkLeZKgZagakMTCwNuw2DKgYLKDLBPXCg48KfJnZBEwCXRtfwE9azZXBPYwO7BhCaXsrAs=" + ], + "X-Amz-Request-Id": [ + "8E37ZPF9TP0PVF6J" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "46a273a78cc93e91", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:35 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9rdWYgzkz18dLgJ1UwFITQNX61W/gfMkXc0XF0PUJ2urYFvBu0u9eSvIw5e2lZglUPrPeZoZho0=" + ], + "X-Amz-Request-Id": [ + "8E3BVJVMHSXBXDZK" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay new file mode 100644 index 000000000..2daaf1d58 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestAs/verify_ContentLanguage_can_be_written_and_read_through_As.replay @@ -0,0 +1,778 @@ +{ + "Initial": "AQAAAA7ffPQNHznjTgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "cf9bf49ff594d53c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KaGVsbG8gd29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOkRVb1JoUT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "p+tNEQWWXrNPDVAakCm2sxKVFLdWtLmitEW2o/FFBUvW/IG1uw1xuFHZZer/a7nxljDrGzSB1eZyO/QtkPLreQ==" + ], + "X-Amz-Request-Id": [ + "1RCANQT7MKPXTMEZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "faa4c9b509275e9f", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Gxb21NTOH+QSXW4fY+cly7s+T8/0A0LuKcqLEn3bT4nkDTfcK3b5+W45vcEucGR79fYcFKOi+phFz8FZpUgcUA==" + ], + "X-Amz-Request-Id": [ + "1RC03ZRE3EX7DQ9B" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "4b2f282e57376c9c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "3dgwDw2BqTDol8bt/H1JryVlCDyomseQ/ong5rNfKgYInCYkvHJDGQdKwSAYTYzlgFTXQ9vfpDDfjyGDOImafw==" + ], + "X-Amz-Request-Id": [ + "1RCEYZ0D6BFKBZ3F" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "80bbf2f5e2a275e0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=1000\u0026prefix=mydir", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "e4nppQP4dMx34Pn2YT9mR3JkrP4fTc1VG4mXlrlMfTAULWa5xRdVChKF8FrytL2CKUDBKRIvG5J7YTn3XduMNw==" + ], + "X-Amz-Request-Id": [ + "1RC5HPMR7PA5ZZF6" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bXlkaXI8L1ByZWZpeD48TWFya2VyPjwvTWFya2VyPjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5teWRpci88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "f5c4d7721099ca39", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=mydir%2Fas-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "dGPym/ioqrhj2WwhlCnT51TC4bLhq9rjZbB4zdRtARQosjrjnDXnMXjBMWXsi+eVon4zc0RMqbNX0Q3U8HwgbA==" + ], + "X-Amz-Request-Id": [ + "1RC06DFTQFQRF4HD" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bXlkaXIvYXMtdGVzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5Pm15ZGlyL2FzLXRlc3Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzFUMjA6Mzc6MzQuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjExPC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "d15128b0d88fbf77", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key-does-not-exist?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "sXa4FF7J9m2Tg9OEzlC5li7qldbaVR0KZpqraq+5G6BS+LHAcKQIJuzEvz86uQvQ3yKjRGySICsX8LfHIH6vHA==" + ], + "X-Amz-Request-Id": [ + "1RCCZ513MMT5WMZV" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5rZXktZG9lcy1ub3QtZXhpc3Q8L0tleT48UmVxdWVzdElkPjFSQ0NaNTEzTU1UNVdNWlY8L1JlcXVlc3RJZD48SG9zdElkPnNYYTRGRjdKOW0yVGc5T0V6bEM1bGk3cWxkYmFWUjBLWnBxcmFxKzVHNkJTK0xIQWNLUUlKdXpFdno4NnVRdlEzeUtqUkd5U0lDc1g4TGZISUg2dkhBPT08L0hvc3RJZD48L0Vycm9yPg==" + } + }, + { + "ID": "c08a2d31e500ba2e", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fmydir%2Fas-test" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "4Biw0kIMnCcYqpSqLlMiF2Yv9HIuY8FLnugr5TqOfa/4fOFn1ZMtpYsmOzqUjGtENbrtYoLkPbu2UY2Ngx4MjQ==" + ], + "X-Amz-Request-Id": [ + "1RC0QCBD7QTCTNWK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjM0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMiPC9FVGFnPjxDaGVja3N1bUNSQzMyPkRVb1JoUT09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "97a623fdd1460ebd", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "29AmTVTIT2eV9h/bq3PN9Fa7tu/bNX3+dh6E+xJUVeufCaEZpGCcf+6+iwg43zyRVamtKd70JB3W690+qGNDZQ==" + ], + "X-Amz-Request-Id": [ + "1RC518XH1WHS6920" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b0eb33c02f8752f7", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "vzzmWQepBa9EOoUmJk6RBEFbYqOnhvYtnZIVCw8Tzz/G75Cp9g38brxQVGxI+xvqZ/6BLv6aaFjkQlmWCABFcQ==" + ], + "X-Amz-Request-Id": [ + "1RCDGFKJRDDRZWSX" + ] + }, + "Body": "" + } + }, + { + "ID": "86bb7157adac6922", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Language": [ + "nl" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "lURM07KsVdCT0TTxEmAtDiOhQLSfbwE0vPcQA+FTf36BbiWGlfS7xVQVT/grTOU3nWX1FyUlUwCoGsbBnTk1Nw==" + ], + "X-Amz-Request-Id": [ + "1RC3ENSGCQWVC8VB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6513f23710f4e0eb", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/mydir/as-test?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "e1CPnJwUh52Ajm1+LRT9FiYojM0L8q0sHPQMh+9Jf+keFbTZgK6KsiXsxlRDTXB6Le0rBzwp18hTsP90dyaaWQ==" + ], + "X-Amz-Request-Id": [ + "1RCEVJTPZ6HBSM81" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestAttributes.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestAttributes.replay new file mode 100644 index 000000000..0abf4e899 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestAttributes.replay @@ -0,0 +1,751 @@ +{ + "Initial": "AQAAAA7ffPP/Bgo9rQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "a503e237f07ae0d0", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity", + "aws-chunked" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "53" + ], + "Content-Md5": [ + "7Qdih1MuhjZehB6Sv8UNjA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "12" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yw0KSGVsbG8gV29ybGQhDQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjpIQ2tjb3c9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "HCkcow==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "r35glFjHwDXMFfsNli6aMz7jpvraLsrNSBdj1DOCJKX34Qhap1t5l88wVdHZhnCO/q1Uzku6VQHxI5BtSTXpGQ==" + ], + "X-Amz-Request-Id": [ + "3XS32VXVN1AEXKV3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a266c815901d8e3c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/not-found", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "L/IfXmRxOp5jZkzNC7v+yCkGmnFIDn7CmyZOctRPKweOfTBDlz9986hQM6PbfvLUJKOr2KESqbcJhwRObDKSUw==" + ], + "X-Amz-Request-Id": [ + "3XS6PYW56NMACBXN" + ] + }, + "Body": "" + } + }, + { + "ID": "b87ebcfc33d52ce3", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+ppUxQ0NicqVcLhruL6Zo8URJ51vigK9MtUZ3sdGUnZ02uwVDvxB+IKsn1b3IIlheVa8M28rLUCM0pXFrmGlgg==" + ], + "X-Amz-Request-Id": [ + "3XSB13K5YZW2ZVCN" + ] + }, + "Body": "" + } + }, + { + "ID": "703b543d81b08e0f", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "uABnuHjRExn4bkUN78X33IFK/RYZq38ogrANY0owEdUYJ4RZooieiwq7gykHtDKPtBAnc92UxJav/OHe6b1UOw==" + ], + "X-Amz-Request-Id": [ + "3XSAE70DC870KJSP" + ] + }, + "Body": "" + } + }, + { + "ID": "357e28407c2c68a6", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "12" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "PUdkqeDnb2dVRcyW9X0tOA3VYUEOSWyCARMilTacbIXvVodO/OvrJoTdFGelteVt0VGOmlnHyqipvW8aSs3T+w==" + ], + "X-Amz-Request-Id": [ + "3XSDBJFDMHX7PEAQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "5e12a22fdc6167f6", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "12" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "HCkcow==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "IVczQz+ibNGfwiFq4ldApAAzO/NK3EKbpI2qqdavCQgGlC1Z7GJLI+2nHDi2i/cBIpgaEyv2Sk4kUJXDWE8IGA==" + ], + "X-Amz-Request-Id": [ + "3XSAFFZ6KWX92JEJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "SGVsbG8gV29ybGQh" + } + }, + { + "ID": "7446599e48550756", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "53" + ], + "Content-Md5": [ + "7Qdih1MuhjZehB6Sv8UNjA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "12" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yw0KSGVsbG8gV29ybGQhDQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjpIQ2tjb3c9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "HCkcow==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "VAf66Grco4+thxGZgR9pIZApXZ1yxAUluvh58vodSq9yFl8iOtjF9mRzX5+PmrE2Q4D0EfMQx7Go133ROJLiIA==" + ], + "X-Amz-Request-Id": [ + "3XS6XJMWXJB0B6Z4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a09a9c9ac85227a8", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "12" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "/EbgcQ+DP50LyzJmAvDmR9mb8k/KQLlicpZqERY3dVKGQrlPwhUmXjdCel2PLLlvu6XxaHrDk1Xo6vdzln9iIA==" + ], + "X-Amz-Request-Id": [ + "3XSAGSFFJH76FS3H" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "37dedf626348f0b1", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "12" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"ed076287532e86365e841e92bfc50d8c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "q7+dkaI3rBgdnZPtoXxLEpWOkThdi1RRwfW1D3IfMlbLLz6GJXXbMAFgGczvykeIgHx0O/8np1dfm4ji0OVjHA==" + ], + "X-Amz-Request-Id": [ + "3XSFKPB57VM41A87" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "4d8f34a00247e8a4", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/someDir/blob-for-attributes?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Rv6IkNn99HSjqZ+JxefLvVLpRi97Y5m3auEVQ7Ha9apx+dc39V2PwYQtmTgdj80Htc6ba3ke4hpHTOh7HadfbA==" + ], + "X-Amz-Request-Id": [ + "3XS35CYTY41TJ912" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCanceledWrite/BlobExists.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCanceledWrite/BlobExists.replay new file mode 100644 index 000000000..96e5cb41a --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCanceledWrite/BlobExists.replay @@ -0,0 +1,409 @@ +{ + "Initial": "AQAAAA7ffPQCCn3VPwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "608c3f231ef8d9a6", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KaGVsbG8gd29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOkRVb1JoUT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "yGG/ELYU/9U+FCaGkbm2+sst8qej5rHgutcqJFvO5U0snBtJXuJGoVwQLngs2vKCWN6Lm7RdhFXF/YCG04ZvFw==" + ], + "X-Amz-Request-Id": [ + "8WK8JCY5N4FXH4PS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "95f83ae7eb9ebf20", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "kZzfajlGNFFeAaKqVCsAXEshSqNTr7Wd1U+pOGQW/ks/vdjTbdJk98TsL7Bh6nuW/SZh175mDEeQJKSDMyDbgA==" + ], + "X-Amz-Request-Id": [ + "8WK7JGDAJPP5JCEP" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "07754d5f40cf8a02", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "6eC3q5bIvZ6eyQmhQSG4CYQSsKPMz39qKOn+PTCufyCkcW0tO+FBVu2aX+x2FnQXm+az0vyrHLB60HSXpan1SA==" + ], + "X-Amz-Request-Id": [ + "8WK0N8PFFTQYH10K" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "54aac08cc211af71", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "lKXlVwEdkCz8g41A/0EnW7InqFUbB7I4I1ZtrO6AkNGLqUN0q2KRzYsWk+FFVnj0eQuFFfpTQKfh+G/n/yqrbA==" + ], + "X-Amz-Request-Id": [ + "8WK2DWDNZZCER5W5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "31bdb93a8d4f3a0a", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Se/dL9ELKYDmIvXwIEw7A00ynOKwtnhMlsobC0UUF6VAl7tqUTo0w+99wNBNpjWvlxhR5Ik7UFubcmRICUbBeg==" + ], + "X-Amz-Request-Id": [ + "8WK2G53Y9DY02P7M" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCanceledWrite/EmptyContentType.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCanceledWrite/EmptyContentType.replay new file mode 100644 index 000000000..49bca5a3c --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCanceledWrite/EmptyContentType.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPQBOeuJqwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "403eb58f34d089b2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "JrJN84JnkR23gEjofBcM2cL4/NjzJD708E73PxTLJLeXghREFRwYWRoCWO4tcrmoTlSUa5XAqA7sRwt12Vw/Qg==" + ], + "X-Amz-Request-Id": [ + "8WK3DN26ZCY7M449" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvS2V5PjxSZXF1ZXN0SWQ+OFdLM0ROMjZaQ1k3TTQ0OTwvUmVxdWVzdElkPjxIb3N0SWQ+SnJKTjg0Sm5rUjIzZ0Vqb2ZCY00yY0w0L05qekpENzA4RTczUHhUTEpMZVhnaFJFRlJ3WVdSb0NXTzR0Y3Jtb1RsU1VhNVhBcUE3c1J3dDEyVncvUWc9PTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "9c5879bb3c8750f1", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "/O72l/XT/fUdmYc5vU1uEc4Jtkt0qaTdKMsx3iR8+5iZDYOYQ9MrgnYMGfRbHO/kyAQ6v+ZpdkKX6l/v2BLyXA==" + ], + "X-Amz-Request-Id": [ + "8WK57ZXVK2RRGHBD" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvS2V5PjxSZXF1ZXN0SWQ+OFdLNTdaWFZLMlJSR0hCRDwvUmVxdWVzdElkPjxIb3N0SWQ+L083MmwvWFQvZlVkbVljNXZVMXVFYzRKdGt0MHFhVGRLTXN4M2lSOCs1aVpEWU9ZUTlNcmduWU1HZlJiSE8va3lBUTZ2K1pwZGtLWDZsL3YyQkx5WEE9PTwvSG9zdElkPjwvRXJyb3I+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCanceledWrite/NonEmptyContentType.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCanceledWrite/NonEmptyContentType.replay new file mode 100644 index 000000000..6ae4ee11b --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCanceledWrite/NonEmptyContentType.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPQCBIYs3QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "40ec8dd171fb595b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "SatyK1jCEaUgfPV8e5wErQlGVq99t1nzszlyfstykmtmJvXpawwqPgL+oL6viF9/HN4zv4aXBHA=" + ], + "X-Amz-Request-Id": [ + "8WK1DDKPRPEXCZ8W" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvS2V5PjxSZXF1ZXN0SWQ+OFdLMURES1BSUEVYQ1o4VzwvUmVxdWVzdElkPjxIb3N0SWQ+U2F0eUsxakNFYVVnZlBWOGU1d0VyUWxHVnE5OXQxbnpzemx5ZnN0eWttdG1KdlhwYXd3cVBnTCtvTDZ2aUY5L0hONHp2NGFYQkhBPTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "732afb09752815f9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-canceled-write?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "8T/En/a5+87pNOYMw50V4ikwKIp/ETDCm+tdVNwz/DrXIsFyYAcbkMYCsTJ62+b8Aei0Zd0cGqs=" + ], + "X-Amz-Request-Id": [ + "8WK8CR5Q8YYS36NP" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1jYW5jZWxlZC13cml0ZTwvS2V5PjxSZXF1ZXN0SWQ+OFdLOENSNVE4WVlTMzZOUDwvUmVxdWVzdElkPjxIb3N0SWQ+OFQvRW4vYTUrODdwTk9ZTXc1MFY0aWt3S0lwL0VURENtK3RkVk53ei9EclhJc0Z5WUFjYmtNWUNzVEo2MitiOEFlaTBaZDBjR3FzPTwvSG9zdElkPjwvRXJyb3I+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestConcurrentWriteAndRead.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestConcurrentWriteAndRead.replay new file mode 100644 index 000000000..de3c7467d --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestConcurrentWriteAndRead.replay @@ -0,0 +1,5707 @@ +{ + "Initial": "AQAAAA7ffPQCG3hVMgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "92979d383801c9d9", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key13?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "SsTzFZ3m7R1NrIc42UKW+Q==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTAwMA0KDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6K01kQXhBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"4ac4f3159de6ed1d4dac8738d94296f9\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "+MdAxA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "907GxQ09lP5nEFZ4q32GGbrSIL8t2RLyEynP8KE7KkBulFZve+8W7qQJ9EMjNkPpXx2eC74pP2A=" + ], + "X-Amz-Request-Id": [ + "8WK1HTNDKMRWWW1B" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a995d82669427cd8", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key4?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "H06jyF3ZsJDOcwyB5gg+zw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6aHVtY1R3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"1f4ea3c85dd9b090ce730c81e6083ecf\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "humcTw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "eXQ1QLHAAlfvkKBk+v5N2Ct18zqNmxO+pc7Kz2PNBOS1yZuKrxmmgCoYMaURtOAfnw6aPZlgyFg=" + ], + "X-Amz-Request-Id": [ + "8WKCYPHZHTM6VZFG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "82d4215512de62e1", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key11?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "AbDmWR96f1VIFnW4JQ5/SA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCw0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6bWNnU3RRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"01b0e6591f7a7f55481675b8250e7f48\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "mcgStQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "HtdWjCXrHe40Zdde/XudpcabcPWwKiMkoADE0GUVmr4DA6x+fzkJJNG/AtX5p3t7vwPaLdfKpEQ=" + ], + "X-Amz-Request-Id": [ + "8WK662Z35QGCE940" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "850ca0ad845eea15", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key12?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "VkGQ+3LJseHAFopbb+BYvg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTAwMA0KDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6QlFLazh3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"564190fb72c9b1e1c0168a5b6fe058be\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "BQKk8w==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "qDgeDzgV6rzQD0c26w8GAG7VL9xPiMjcSNpk42Z5CkbKuK37dpmiTYuQiSvNe/QyO8GEeorVbBs=" + ], + "X-Amz-Request-Id": [ + "8WK6ZP9K3AAJ9MAJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6b239058a3e030d4", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key8?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "qPZPE0uAGBNKE6LhEQTA8Q==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UlBjNHJRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"a8f64f134b8018134a13a2e11104c0f1\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RPc4rQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "cJFs/oN3OFuw/HyIoKovJ7hhdVsOQhnhFlpVzhBZ2HOIlPkj6lZeAykVLDgHIlgq5NX7CauEB5Y=" + ], + "X-Amz-Request-Id": [ + "8WK62NJ60XQ7D3F2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0126b6f9ac0eb05c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key9?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "kfsiuKRZ73D7CzauKodAhg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTAwMA0KCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6dVRMY21nPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"91fb22b8a459ef70fb0b36ae2a874086\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "uTLcmg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "olIl35/w0CQTkjv/0fd80bMUxdte+JDrzWiPBHTgvY7Uh2W3Wjk5WbNCH7+Up/8H3kGkLPlEdp4=" + ], + "X-Amz-Request-Id": [ + "8WKFEP7KQHGMTRBX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b73270fc8ed93a46", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key0?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "Yg8LZ6kff3QVG8W+dFtxEA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6eHh3QUVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"620f0b67a91f7f74151bc5be745b7110\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "xxwAEQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "m/rH0Zf6OpdjqdFII1602fpSUv07B4r2ZopFYA1aesP5a4pUU8bNfEO3tiMDj03h44zK9fC3m20=" + ], + "X-Amz-Request-Id": [ + "8WK9HXVF8235SDS6" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b53f5c815f1ecb65", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key15?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "qHqy3TOCPLWABZ/YTEeiAg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6MkQyTzZ3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"a87ab2dd33823cb580059fd84c47a202\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "2D2O6w==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "x9oMhPUwofyDqJ8YlHGVEWuBPjLS0UtCYVKsemq1EI790yMd3smqY1OPI/yig2Z5KLcyFiPslTY=" + ], + "X-Amz-Request-Id": [ + "8WK6GNTVS5WVN7VS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "67dc70efd98c80ea", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key19?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "2w9S4aRqKABHoeAhyiAJMA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEw0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6eG9SZE1BPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"db0f52e1a46a280047a1e021ca200930\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "xoRdMA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "EUIBkr4/zQBbYGTTNK+H9F2wVLgnImyFZzIKsNuYNi2wgXs0l0RdcIWcU/97suXn/bFsKsCtmb8=" + ], + "X-Amz-Request-Id": [ + "8WK7V9EMQK76V87E" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "5747a0233398c842", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key18?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "wZvI1MtOgANGQD0gzZ4NUg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6TzBHNUJ3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"c19bc8d4cb4e800346403d20cd9e0d52\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "O0G5Bw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "5qMmEQ2zXOsyzaqdQMZGgISFlTPu2PWcXA4eKTLQQZy4wNVY+smXcNiu5Oi3ZGUQgFhmVYWsT34=" + ], + "X-Amz-Request-Id": [ + "8WKD5CPMWHZBS88B" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b4df666352b648af", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key6?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "lko2uDqoJrgEyYNnvcJ6vw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6cGhOU1lBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"964a36b83aa826b804c98367bdc27abf\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "phNSYA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "N3/KEADxXQMGcOwgL2h9ktSW469ynUy7yEt5YRUr5RdjRhdXmLLoN+8W/aciOwZ08zvfg+ZEB3E=" + ], + "X-Amz-Request-Id": [ + "8WK1F71S3XQ850NS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "42ff47ddc8701cd2", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key5?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "YfRaKQkG0Wv1UeeMsD1f+Q==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6ZXl4NGVBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"61f45a290906d16bf551e78cb03d5ff9\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eyx4eA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "o7E0jNgjRG1fEpsUF2a5VJ9FIrPdc3YET7UmAymeD3KAnNrhPtj3TZN1ci3Qi034T2vuRvK/E0o=" + ], + "X-Amz-Request-Id": [ + "8WKEDTMYY284SA25" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a946b605f35e6fd6", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key2?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "ZUHn/UhoC5tg7AVev6McAg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6NStiT1BnPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"6541e7fd48680b9b60ec055ebfa31c02\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "5+bOPg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "/0QZouaX06VsUHMqsvMnOg4vfnK7rsDHBsfDSxzsT8FbZeJ52TTOLotzZbnHKSm5l4kvfIWJgBg=" + ], + "X-Amz-Request-Id": [ + "8WK02ZF9TZ25NSHP" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "87e687ce710a5108", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key7?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "kbuiTp5JEugjwAkgztPoXA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6VzlhMlZ3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"91bba24e9e4912e823c00920ced3e85c\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "W9a2Vw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "j6qP2BIQVau275HSSSWTRm0qJfD/n4qDV+MehBabirHXCeop0XHoDeV/rXlpyBu4Zo1ZeJLBaCQ=" + ], + "X-Amz-Request-Id": [ + "8WKAER4VGA6Z2SEX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c6679c1231a48323", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key1?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "qo85ln3rRBpudISWOUWpYA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6T3Rua0pnPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"aa8f39967deb441a6e7484963945a960\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OtnkJg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "cWuaqy+og9QRTMVQa97h50I7v9OD6ngVZtDl2xVTT8SgPzwxmB2YI5XdoAMWs1PGEc6Wh+h+XRc=" + ], + "X-Amz-Request-Id": [ + "8WKEH4R6WD2WWJHX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1160ba809eead437", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key3?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "7tBPOyKIo0omYOmbN3Ht7w==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6R2lNcUNRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"eed04f3b2288a34a2660e99b3771edef\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "GiMqCQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "IRHZCdDY6DrYxKwVjFTJI6JMCaUmtKk/1QBOYMRn6wcqw9KF6+thavVZK38Sn2ngsTP2n1BUfcf0puQ0A56YA0oKsFmEuSPXqeIek3arNh0=" + ], + "X-Amz-Request-Id": [ + "8WKAD7QMDW2MC4R2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1d8c6b291e635b19", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key14?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "NlFDUFM0TpF1S+MXE1PxDg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KDg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6SmZocTNBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"3651435053344e91754be3171353f10e\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "Jfhq3A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "5E0AL64GKH/ob7fLpaxxO980uSxk62vum8sAR34sytBaJq3EArScDr+OtF/+yTn2nqyTmv2l1De/r6L9FcJ6iC+69AQsFbPkL8aeLzNoMv8=" + ], + "X-Amz-Request-Id": [ + "8WK1C68GA9YC42GH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "09354dcc5e6a92b6", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key16?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "65n9CjdrJkNQEaG4fFWMgQ==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEA0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6Rzd0M0tBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"eb99fd0a376b26435011a1b87c558c81\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "G7t3KA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "lQBJUG9LTiq0uWMnTpiDWRZ067OSSZUE1+b4Bk27PiumpaFJcDBJx3i4STvzSjhS2lYOzehlB68/Z7X3biLu3qIpRHrSnY6TuJq599puAAw=" + ], + "X-Amz-Request-Id": [ + "8WK59DZAMQETKQ65" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "5797124efede3415", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key17?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "32eeXsj7ZyhCl0o20wPQ/w==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/octet-stream", + "BodyParts": [ + "MTAwMA0KEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6NW42VEh3PT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"df679e5ec8fb672842974a36d303d0ff\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "5n6THw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "u/ZjkohAZig2+mzVHy8LyItU+tXwRGN6bX5zGZtpU3AfZWc6wgzDb/gaxd3RwiT+/KVPKQ9WjY83sPOqj+ugA/WYAZSwbKgGipTDLj0SUuo=" + ], + "X-Amz-Request-Id": [ + "8WK16SZZY5WM70QB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1dd23a60a9015765", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key10?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "4140" + ], + "Content-Md5": [ + "AXKK1JVcZ791KxchIXYNNg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "4096" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTAwMA0KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6WkEzMmdnPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"01728ad4955c67bf752b172121760d36\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "ZA32gg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "pHPk15gD15SP8KaPBSE+i6fDoosD3w3iJF13KzJYvgpfZX+sWFgNVqb++Rtx6EIJ85/Olrx7aihlJDHEbp/ek0uWLIxMNDpKwHaiCo72Bms=" + ], + "X-Amz-Request-Id": [ + "8WKEXVA33E4XFEFM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7e2c0ec73af7e1c0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key4?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"1f4ea3c85dd9b090ce730c81e6083ecf\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "humcTw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "6s4q/CjkX4qyKy4UVosuRfsL8VhhRtreyFyYvOzEmsY1yCoPfvdIxbQ60LABzFLH3XGEA2EP9sG/RLFjy/3so5W2muT489qnBJFN+qkpsXs=" + ], + "X-Amz-Request-Id": [ + "8WK65G9KHPZQ3QQQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA==" + } + }, + { + "ID": "5e1eb98f951b46f0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key1?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"aa8f39967deb441a6e7484963945a960\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OtnkJg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "cCD3d7aaNAB9RkHyezjIpmp3UcH1sefM03vPXvsiZylDSA06rg92/KL+ObE2piY0k8QVlp2xDfC3GZKju2stkmMdjQ2zG0IdogfasIwwyVc=" + ], + "X-Amz-Request-Id": [ + "8WK5FW5PS67AA1TA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ==" + } + }, + { + "ID": "a6631d5ce5430053", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key19?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"db0f52e1a46a280047a1e021ca200930\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "xoRdMA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "yR9nUIBVbUml3KiwWWcVcCE49BbB4BThfwfYrmcyRFIt5dXAWpvL3cGjensmwpCHv7Ep30/65F0ev8ai7XYR9ElHZhrN3pLi1WA1PNReaW4=" + ], + "X-Amz-Request-Id": [ + "8WK8AZN9CKXQDQ8R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEw==" + } + }, + { + "ID": "471a833f710d1abf", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key2?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"6541e7fd48680b9b60ec055ebfa31c02\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "5+bOPg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "+lsGOEyTPCeKjBLt+DcA0Z++O2KQAtcyyfT3C0gd+X2mzOh0yHBWJKe/SmDa7PFkTfEIVsirI7c=" + ], + "X-Amz-Request-Id": [ + "8WK3K692YPQZ8665" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg==" + } + }, + { + "ID": "3fd5cdcef89b2ef9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key12?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"564190fb72c9b1e1c0168a5b6fe058be\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "BQKk8w==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "+1aH6cbsKpxwAGyYnLWpuQL9J6ePKqZfoqA3hVMAIXHlQEYpiLGyZ93+6oExvdpIR2eLnwq4bS722nlL3j0BuKt57Z6SeVoegsX5bVpkns0=" + ], + "X-Amz-Request-Id": [ + "8WK3G00H1RCKG7H3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA==" + } + }, + { + "ID": "b7c7179b3b5d2daa", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key5?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"61f45a290906d16bf551e78cb03d5ff9\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eyx4eA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "aEAyLnbiuB5gtlR0p2bYzYF4xuiPm6ti0SUgQSx/azGPq9ByLsr5nsBFuke0Lkk927SVYNqHhCQ=" + ], + "X-Amz-Request-Id": [ + "8WK39PP5Z74ER61G" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ==" + } + }, + { + "ID": "cb115fcc41d5c3e3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key7?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"91bba24e9e4912e823c00920ced3e85c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "W9a2Vw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "MgrxFEHtz/IxfR3M0U9sJEVZCcb345JDR7lXH6eJTrn7ezB5wqTPZQzrUkoIWlK6U1YXBw1pXNE=" + ], + "X-Amz-Request-Id": [ + "8WK36RQTTZKPZHR2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw==" + } + }, + { + "ID": "6fcd7dbb9a238c58", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key16?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"eb99fd0a376b26435011a1b87c558c81\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "G7t3KA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "q4ScWDRY/ao+9XcumwE6UlKCGKSioODVpJ1pTI8cQ23k/4lXdUsKH7vBUj0JuSDzZ086UBqRD4iG+0GNueUG4mIY9S1tJTmtHby3keLrhRQ=" + ], + "X-Amz-Request-Id": [ + "8WK7QPYHSD11F5T9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEA==" + } + }, + { + "ID": "2737bdfc00b2303f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key0?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"620f0b67a91f7f74151bc5be745b7110\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "xxwAEQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "l9QdvMi0ViQazlFn2Mcq5/Do7gZPsP1xM1DTi3gAVgjwtC6zESrY17f+wgB02u3LgRDSE93z7Bs=" + ], + "X-Amz-Request-Id": [ + "8WKC1CM826JTB2P8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" + } + }, + { + "ID": "7c268809778d46d5", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key13?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"4ac4f3159de6ed1d4dac8738d94296f9\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "+MdAxA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "k1u5Lxzw/bRJA6YiNY7oiHHNL3yYP7UEL859eID9FOdb0zZkBE2fpiRHbn/rFhtx7dLbYxMTp5czZbKcwtZi7N+1MaqWZClBFfRFjYE+ZLg=" + ], + "X-Amz-Request-Id": [ + "8WK8SPJK7KE5WYHF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ==" + } + }, + { + "ID": "3dbf05e716f562bd", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key3?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"eed04f3b2288a34a2660e99b3771edef\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "GiMqCQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "N7w9VM5ihfQbz+4JstEzJtd/yb+tpJ2GMsuBevJy9f8nqQt0pFmWtznBwX5wjvh0AP9aZpk6Pqg=" + ], + "X-Amz-Request-Id": [ + "8WK20TA01S27G3WE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw==" + } + }, + { + "ID": "93a9ea57bd9d476c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key14?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"3651435053344e91754be3171353f10e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "Jfhq3A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "04WmoOamSO2VLTEr1nm2mUJ5irH8OkkaPc77qRgYcq3xk02m7BfHajpsWw4/zOGvDknyLVBsBwi998HJrR4qiFqOiA/t6/GB8ZM5FoACpOs=" + ], + "X-Amz-Request-Id": [ + "8WK4BH2HSE0Q5WQ4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "Dg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg==" + } + }, + { + "ID": "048615d1dc50b31f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key6?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"964a36b83aa826b804c98367bdc27abf\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "phNSYA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "VfWGoA9l489s9pnee0CwU1rZTJ8t3+BLuWB8EQcO8toPn9i8YrH/iVOU9UyyC6ZuIJXjWBbYsAszl4QsGcnOjdrScA3cDObdKwGMGfYCxq4=" + ], + "X-Amz-Request-Id": [ + "8WKDM9SHXMCRGTX1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg==" + } + }, + { + "ID": "ac92cc41b77aa059", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key15?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"a87ab2dd33823cb580059fd84c47a202\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "2D2O6w==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "0+g/S9PXvy4vInhw5HwDsiYQBIUtOzDzondIOMT90TycJ46DCO+6x2MZ6wQkKnH/t62H0KrdcrHySh/GrqwrpXtVi0hzhwrIZS+mRYPwrxc=" + ], + "X-Amz-Request-Id": [ + "8WK9TTD1J82JHTWW" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw==" + } + }, + { + "ID": "d3b3fbcb3050d3c7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key10?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"01728ad4955c67bf752b172121760d36\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "ZA32gg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "XsdSAch60UerH8c4fQceMIzZVNd7uktyM7/rE7mdKL0FqclmevSXAf8jCq4msseWQLsHve45+xxAhX2ydSKdn1AgXVrcXPL/r2DzEujV62E=" + ], + "X-Amz-Request-Id": [ + "8WK1KM3VFVTEH9RJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg==" + } + }, + { + "ID": "ab6d022a78f5771b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key9?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"91fb22b8a459ef70fb0b36ae2a874086\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "uTLcmg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "nZiCVQReyUMMp42sH5avMCfTXR64thsnFvSPQqQv7rvuBi0mRmGg92JA40SzBxyIL/2cIXgwMh+F566xeZYPVAk2YT5BoYt8nefcdzuxUuU=" + ], + "X-Amz-Request-Id": [ + "8WK1T6MTK7G9H0WV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQ==" + } + }, + { + "ID": "325c7e3e57446790", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key18?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"c19bc8d4cb4e800346403d20cd9e0d52\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "O0G5Bw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "8XrZ7NUzhkSNMNtMbA7vpE5Jm4aQiVPcFUVup15jS8vBqUDJG+JdiZUPb3KkKI6ZPAMCLMIodLtwu9Qhz+LZJ8U3PzaP0wAheWQOPRlu6LY=" + ], + "X-Amz-Request-Id": [ + "8WK6PM1G4NDBK3JW" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "EhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEg==" + } + }, + { + "ID": "e0107a0a9734eada", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key17?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"df679e5ec8fb672842974a36d303d0ff\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "5n6THw==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "DOs7tlIsMqrDqtEFhHvRsCSpuVVDp7bne3kNnLCWadsiges2pepvLnvQpBpCWwRn1fx3yav1wbvSfDD30rkaBQ==" + ], + "X-Amz-Request-Id": [ + "8WK4GT06E5M6GQ9M" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "EREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQ==" + } + }, + { + "ID": "f8c880c5e9d2f7f6", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key8?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"a8f64f134b8018134a13a2e11104c0f1\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RPc4rQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "+svPrVN20S2bYxd8kYm/UI8A4IzvriYhGBoTTqaTNyOMzhucSgWk0TPh83zTE/ouc6rFiU6E1VpR6b/iFZUXSg==" + ], + "X-Amz-Request-Id": [ + "8WK175XHSW7YMCH1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA==" + } + }, + { + "ID": "ff68e860d639f8b2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key11?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"01b0e6591f7a7f55481675b8250e7f48\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "mcgStQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "+qAXBCJVa6A+oiPnHFGTLHPjgfK9YFGQNJRQ7km9iilujlgpF+5IUx/p6dKSlAPC9j7urxYwV88=" + ], + "X-Amz-Request-Id": [ + "8WKCFP66D634KZ5S" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "CwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCw==" + } + }, + { + "ID": "60305c0471be1a78", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key19", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"db0f52e1a46a280047a1e021ca200930\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "QBmuK7q/HCxHcWWNCnkWS/fApCC2D0oD58OcFpn4mR4R7+zcAQh10h+t/SybhqMTrzg0JWXP+p6g6WDeY21Yu1D0DjuuevMf1ozc7HO0PDQ=" + ], + "X-Amz-Request-Id": [ + "8WK6JDCJXY2446CN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "549487901dcbe42c", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key19?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "oQ0SJpSpp/JXZCgyL+UVjJdUTjlRgG0eAoERvBPlKIezrf5ZDtuGt0j3LcsnvD4o+aKbRcGVVcMRntW6cgsGw9LH7/K2rYLfsJXtdiCzjyA=" + ], + "X-Amz-Request-Id": [ + "8WKFCJHAFZGJANGB" + ] + }, + "Body": "" + } + }, + { + "ID": "1430731a98e0af90", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key18", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"c19bc8d4cb4e800346403d20cd9e0d52\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "V8i3fjT6XhDSYcz1aWOSeHkuJf9+x5JCi/JMRSixGNfDKHjdl2SsNB4+zq1gSzU6tC/Y6wiCoa9ZetYDuIsMDp/juIeTEfcNK235chTHUfA=" + ], + "X-Amz-Request-Id": [ + "8WK1Z0T249QRJ8FV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "4bae0c673ca8d4f7", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key18?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "a/9v1Fg/6XgTfT738MVrQMO31PWs80icQfNb1xFyFp3C95WQGzrgSgNvfCyDvCz4Wysxuy7N4GaqfzPLqpUw1/KWCVrVsL+q40PcEtoC3ec=" + ], + "X-Amz-Request-Id": [ + "8WK2TDYHQ04SKNY7" + ] + }, + "Body": "" + } + }, + { + "ID": "6f480921eb0f085e", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key17", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"df679e5ec8fb672842974a36d303d0ff\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "4z+mzZBzqAe8w0HB2tFjTHfucJmuRdZgECpYzC12eWsjym/l30NW2C26twlATp5OSZmxAx1a2ki5MXeSql328v1AAggmPI4RdoPusrvbkgc=" + ], + "X-Amz-Request-Id": [ + "8WK5Q70DARA9MGFZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "9ac2b8b69e237e8f", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key17?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9krqS0P9FNzkCdPtSdS4UeSbC4oH95yLZV9SHpF1AjJs7Z8iLpy3F5bdzt4hBhf93uonRbSqdqMURGB/HAMd8ozo1Vq9ldeLxRNcX/q6jzU=" + ], + "X-Amz-Request-Id": [ + "8WKF56MVPGG5R61Z" + ] + }, + "Body": "" + } + }, + { + "ID": "fd97828d2e05412c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key16", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"eb99fd0a376b26435011a1b87c558c81\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "6kklXsYVLM9VzZ+G9hW7mBq/N8EcSe55Cs0kEGM+rglYE0fT6xzA1Mw4FUfWOcelL5S9dJKUBfqrQU4JRuVy2wnr+jfA9QxAzqPWYXmfPpM=" + ], + "X-Amz-Request-Id": [ + "8WKCNCJT70CMARPM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0ad41143ca8ce5a2", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key16?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "v64ImO9hnMF+z/vUD3LQXVGeiskGznK45kJ93WZl7h/LUJ58iPl73VpWJmZlJhHZ0mclGou8J/mq2WRGUtdsI2Ra8NzzhdOXqIdmfhTlxtk=" + ], + "X-Amz-Request-Id": [ + "8WK9HXBK1D70XJ66" + ] + }, + "Body": "" + } + }, + { + "ID": "2d918a897d2d879b", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key15", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"a87ab2dd33823cb580059fd84c47a202\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ImTU8QNYcL7c1lFtS/iJFzm5OEpteq3EnuNGOvERE4JEh3d7bc62mYyfDysNTlAQUV8ggOL+6BGZzhpExsjc2P6/InTaf9Mm9lomvas69m8=" + ], + "X-Amz-Request-Id": [ + "8WKD6WHJWSN5ZS27" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "908ee3907c699f7a", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key15?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "J7RPsBPsUZZUVdxB2caX6nr7sBTtecXhi5c5f+f6uJej6UJCeLrLTsCzRHpUkYVegTpGWOwSYeV1obvakcB6b8Av6JWrDP1Plpnp7ptaQiU=" + ], + "X-Amz-Request-Id": [ + "8WKADAZ3NV5D8SSJ" + ] + }, + "Body": "" + } + }, + { + "ID": "5bea5a018cb3e3ac", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key14", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Etag": [ + "\"3651435053344e91754be3171353f10e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "6ONRVZucZiC3QFahTf6Ul5urBUU57OwF4X4QFPm8MSON5oP7aU4nro1q+Dcm7zlh3JCEp4zkEwwi6xgKbFQJg6eQsQJ0rmqAy95FhoJ7bRE=" + ], + "X-Amz-Request-Id": [ + "8WKCVAP0ARH2GWD8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "4129cf909495d7f3", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key14?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "3gU9QvQjEUur9fvQ/dQEzQZFbQq3nGPc6sp9d3ZDgvPQ2stIlB7DEvpAcPylAJ8DBCyg8WgSTsw1j6ReyLr9+WWjjzkomC0k7otfoL0g2FY=" + ], + "X-Amz-Request-Id": [ + "YTBSTTFHY5Q5MDJJ" + ] + }, + "Body": "" + } + }, + { + "ID": "831a9d4a5192a979", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key13", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"4ac4f3159de6ed1d4dac8738d94296f9\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "LFQoJGtXRLRSqx42QIufTLgUfwiJdXnrs7DS50CNBjlSqc9RqAzUhjdkM2Crxqdf9wGBEOk7LQx/qIQDK29TvbCC4C0gBcGKO9gPUpcOL3k=" + ], + "X-Amz-Request-Id": [ + "YTBJMWF9BHG7N38P" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ed1d5f3c2bf050ed", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key13?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9/ESAP57eHZd6tWygrTtTXyx1lJBnwgyolG9qxF5pW898/frMCqr66JHSrfZt8qG/2bANUUS4YA7Ow4A9IUKvTIjIacWK0fk8Kg9kksuz5k=" + ], + "X-Amz-Request-Id": [ + "YTBS5FBYXW47SGA4" + ] + }, + "Body": "" + } + }, + { + "ID": "da26da18831319a4", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key12", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"564190fb72c9b1e1c0168a5b6fe058be\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+OK/4JmSZ9VI/NnbiO9kvU9j8AAayBcQ0jnOorimlk4KXn/Znl6OxtLT3eUY/lqqmF/VhaKAJDw2CZdj4xVPWlyv7UP7/as0xM+9WYpIBY4=" + ], + "X-Amz-Request-Id": [ + "YTBKZECK1NT8DVZV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c2632a368c77b86e", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key12?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "u9RQfBkSH+f5oqr8zEiiXrkdEBV6efYHhTRI++fSw49eJbIapG1cNICrxMlmOuewaYM3KpiVEsUkTO8+elr1aZaWfww2W1b4Rv52gFpMq0s=" + ], + "X-Amz-Request-Id": [ + "YTBQ7ZR0XGQ31NJA" + ] + }, + "Body": "" + } + }, + { + "ID": "1d5699b0b7fabad8", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key11", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"01b0e6591f7a7f55481675b8250e7f48\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "HeYsKGD1kDYiOghuJJ6H7EgONNNYvcFxndFdv4y8KAwHV1yET1rTadQ0lv9xGFgAGDmyQCktWQpjyw9SFSHfCD1dfeKGu3Ce27StESxiWeo=" + ], + "X-Amz-Request-Id": [ + "YTBZN3JE7636YRF1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "9e0fa5c0f8dbf453", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key11?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "DPaDNMPUyuAb4L8qg8j1VSs/PIC16ytvwiclNem9DlKesLCnEpUQN4vTpSUZiOY6OFe/9ZHSnaqT/F4WXMJrAsbfU+KS1iW+EP2OLVq1wgQ=" + ], + "X-Amz-Request-Id": [ + "YTBVXN7JTKRPZ941" + ] + }, + "Body": "" + } + }, + { + "ID": "b40c8cf74693e9e2", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key10", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"01728ad4955c67bf752b172121760d36\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Bjb9aIWMDIZtM1VhFUdDEdXALw+/Pnlz7VEwTg2B2IsKqViqgkhKV+DWzKbe4I4qdqCTgWkOnYgXcuJQ+oO2eEFF1ywcadbGC9GW5J6kk2M=" + ], + "X-Amz-Request-Id": [ + "YTBH68J09VV3HDBA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "dd0c641e33c08f18", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key10?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "t2Oh4vXvgmbkk805raraG8NyyP61skwZQCibJzoZyuo0SXvrgtvMJ8VghylHnDoj2n71tQGBntFUnLQN+2QdfX6zrf68T/o9VHCdEhCeQMM=" + ], + "X-Amz-Request-Id": [ + "YTBR8SBA4YPP7FP5" + ] + }, + "Body": "" + } + }, + { + "ID": "03ec81cc22d51f41", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key9", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"91fb22b8a459ef70fb0b36ae2a874086\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "3YaGEkg2P5ddaOuK3tX3igFkRMgExQUZl0vgsCWWrjFdZkdZY5JhRlPPLkkGQr+nZ7LnHVm/FYya0BXY65x31zJWrZI0GKJ3TlRpKEPJYs4=" + ], + "X-Amz-Request-Id": [ + "YTBRP6V3ZTJQFAWH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ab1f46cc45b51bf8", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key9?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "wfANaFcmcvc3Vvop0ZgGBKEcfJx51bj3pyfcpyUUJjCqDAXmDT5HsDISa03aTYVj8fonr1GT/Pc06RVzCsFFqU/O0MeZ1n0x8QMf92nzcQg=" + ], + "X-Amz-Request-Id": [ + "YTBZB052GTJ0DEZG" + ] + }, + "Body": "" + } + }, + { + "ID": "142b6bc8b02a947c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key8", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"a8f64f134b8018134a13a2e11104c0f1\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "r6Uqoq0+I7Y3sokL0+s98yUdutBAkNL5BfXn3N8upL/M08TH3bsXxBuZ0TNZMtwxGoXQrkK7hLGdlkO2l3FdGTLN3G7vyuIs/oplVyTnJoY=" + ], + "X-Amz-Request-Id": [ + "YTBR1PNXGZK6Q04Z" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c17a7a4ca5da75a9", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key8?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "wD2iig5n5H7HdXcJ4DtmSdoV1rSH8205Tu8c5E/f078pPej8DBCN40ztkiR8102Tuhd/rNT6YcRAHDIIqdvauniaRYFTKL7ehQsTecsJZmg=" + ], + "X-Amz-Request-Id": [ + "YTBQ0X3RK71EN3PB" + ] + }, + "Body": "" + } + }, + { + "ID": "0815d92bfc8a7b74", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key7", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"91bba24e9e4912e823c00920ced3e85c\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "IirKjXuaggDyGFPW8Trs3ERHdzyozqAUD7ZgoueRUXdw0MnvlIaiA3iHfTdz5x3DXfLFs9Cw5qQDt0t+E63A5Cuq7thsMYk3KoI+XhWrqAw=" + ], + "X-Amz-Request-Id": [ + "YTBQ0MWWMCR1BDX5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "9009097aa0bc5d93", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key7?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "RLqvpJVVfMYgEOIyC236qOdDcoIv9sqJL15j8zTAn8YM1/+CXCz557UiqGqvg6JASUUibq91Y687mfHX+xYXpz3k5YVGTXCy7FOSR3sPnrU=" + ], + "X-Amz-Request-Id": [ + "YTBVDT5024SDD51A" + ] + }, + "Body": "" + } + }, + { + "ID": "fb49c9a17b2e88bd", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key6", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"964a36b83aa826b804c98367bdc27abf\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "YWAvrFIy8GKKsjSw5ZQYXxjC1lbuMSt2wb6MMPfKpPy/Sm7j0QhXp6bZ4TLypqagO7eXDJqHHuD++xsn35sOiBgmPX1uzXfQxTjAK5ysxDE=" + ], + "X-Amz-Request-Id": [ + "YTBNXEFYXHABB49Y" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "d450be88474f17cd", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key6?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ldsTZO/UcYh7ZJVTBDb7wZQKXops+j7wpg1roE8j3tG8piwR2ikgc7fgbKx5gxS4jrRHgj5coPE5pYzxnVxoaTh5sBmXDamR2jgfRGWn0sg=" + ], + "X-Amz-Request-Id": [ + "YTBXHHVZD1AKJ5QK" + ] + }, + "Body": "" + } + }, + { + "ID": "03736689ababb20c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key5", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"61f45a290906d16bf551e78cb03d5ff9\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "IbE8XBCGAyf1XWqvlYG/RS07b4qdmj7B4Q271jmWj83uIerJMLKmLKMO0JAmWyFZgm+hBzFODvipQciDPFNCtMHgfZ1ApEUQQofQuheCP7U=" + ], + "X-Amz-Request-Id": [ + "YTBJ4PYR862P50FM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "87041f45dc9aa6bc", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key5?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "H8wAKdrxDLMDW/SN3a3U0r96a04FX+8Vkv3afF0cUjt6F6+iYWMRJg4biIV6gY3T9ICpc8hps36lFtbm9kdLYF4Un5aekcjgQ2lasq5Fnf8=" + ], + "X-Amz-Request-Id": [ + "YTBJTC2ZY4PWEB8E" + ] + }, + "Body": "" + } + }, + { + "ID": "b9086e3e59b86d99", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key4", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"1f4ea3c85dd9b090ce730c81e6083ecf\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "HaR2ZoxD3GpvBBnGPQf5TXQ7pHl8gpFpCG6xeMzcn4xp8mo/+Yq7cQZfPu0nx7FWLIGZ8JA0/G8pJNHgPnKyY9ov3hgshv/Wr4JcTGna3Ng=" + ], + "X-Amz-Request-Id": [ + "YTBZHVGGNFX5FZNH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "3921bb04e562686a", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key4?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "YsWeCuYS9JlONAkEgzZ/E965WUm2CV9qT7o+y2+0NmsojQRlHZ7LKaKfuIzIJQFTEY72GXLWr8gkgdkPuoOklhR2J6dHZaCHTjIrZsigfWA=" + ], + "X-Amz-Request-Id": [ + "YTBYDEZ7MEAWWD8A" + ] + }, + "Body": "" + } + }, + { + "ID": "d493fab365460b5d", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key3", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"eed04f3b2288a34a2660e99b3771edef\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "devgYAApEFvQyDn59KgmF3RLy7+uwmrbE/0PqxijYO/g8NH7wXaDZVjkxG5JZLHGqq1YCTOwdDCVXsAeOdpHibJb6KOn9SuSo7yISHpwmG4=" + ], + "X-Amz-Request-Id": [ + "YTBS49BC7VE55SM2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0e70aa1bbc5e9ee2", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key3?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "2H9B1prG7cT9WAx2sjFQpUoN9IKLf1vgoo/QGXCAMswEuRqd8SPdgRTXHRNfw5i+VTuDpW59vhIU95RBhR+TKuYvytxhHiGWP1xFhi9AdN0=" + ], + "X-Amz-Request-Id": [ + "YTBN4BH7KYSY6KHZ" + ] + }, + "Body": "" + } + }, + { + "ID": "ec765084f078bf8f", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key2", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"6541e7fd48680b9b60ec055ebfa31c02\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "5Id3MdRvYe0Wr7JDGPflLjeN34yRW2BxqA4zKEJH59HkTEZycLYyYdcsuUXqJhSGqYK3gk57dIapADfNyvSNjD1I67Ujk6uljZ1z9U41mWI=" + ], + "X-Amz-Request-Id": [ + "YTBK6E9YVB5QMMNV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "9aa11a10529c9e75", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key2?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Mx2VadMXf2hhf6fxIuZ6yfLpJccAjlz1XSw+SweMeLbgazAXqKXnfSe+CK3TV4cX0oK11ZBOp8RIWScS6qm22J/hrkxzC/BL8/BVonP55W4=" + ], + "X-Amz-Request-Id": [ + "YTBR40SMM4T554ZC" + ] + }, + "Body": "" + } + }, + { + "ID": "73af926627a1f43a", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key1", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"aa8f39967deb441a6e7484963945a960\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "X16c5onE2CrZdc5bxMYzRssakT6r9AEkGmMnxWLsWN71N8rrewrHOkpycXoGWCXL+0mQROVbK0Hw9hTGzshelk+hwI9oZRQH0/83DAsjzec=" + ], + "X-Amz-Request-Id": [ + "YTBKCDAS8EGK1P78" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c67a35a1d551b896", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key1?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "0OzGkHiNWkbwbU5gxbsgllT+RGqUQVMAfO4VoWfzz+qOSp54/81RVkrY0VrmrBwK7UiXDtZ+B09YhNTSEAZlqP2/TJV7Au7gngKGuG3FI9g=" + ], + "X-Amz-Request-Id": [ + "YTBZ2BYWECQXY8WC" + ] + }, + "Body": "" + } + }, + { + "ID": "9c58fba972dc5da3", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key0", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "4096" + ], + "Content-Type": [ + "application/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"620f0b67a91f7f74151bc5be745b7110\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Apvx1oO3lySAxVuOFI1DZNLzoMIRS+2C8B3+MasXFGfQ/03xTrxRcCoxTgX757jysQB0/sZjcBIR7LAV6pMwJM0YhdhYU+ngXRGaV/QALR4=" + ], + "X-Amz-Request-Id": [ + "YTBYDVB75FRR4DV4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a7c840738ff64fae", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key0?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Er6HCnpVGbzl6MjvRUI95f6eImubkKOsmSSsuq270VagTxO11VZdow58kpmd5sDex2l9LKGEzByaKSyEyzDyXVZJBhWNNU2W1A0gRfk/4a0=" + ], + "X-Amz-Request-Id": [ + "YTBP54MRS39FKKNY" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCopy/NonExistentSourceFails.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCopy/NonExistentSourceFails.replay new file mode 100644 index 000000000..cfc585383 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCopy/NonExistentSourceFails.replay @@ -0,0 +1,108 @@ +{ + "Initial": "AQAAAA7ffPQFH5GO0AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "7dcd26a389ea9143", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fdoes-not-exist" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+DnOcRlQO21GCLzOWGmOjIwm6yWeLomt3YFXeUroOO0FBrrUUZmNM2JtReCNc9ZnDAHhXu8wYOA=" + ], + "X-Amz-Request-Id": [ + "DTAKP756J3CMMS4C" + ] + }, + "Body": "PEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5kb2VzLW5vdC1leGlzdDwvS2V5PjxSZXF1ZXN0SWQ+RFRBS1A3NTZKM0NNTVM0QzwvUmVxdWVzdElkPjxIb3N0SWQ+K0RuT2NSbFFPMjFHQ0x6T1dHbU9qSXdtNnlXZUxvbXQzWUZYZVVyb09PMEZCcnJVVVptTk0ySnRSZUNOYzlabkRBSGhYdTh3WU9BPTwvSG9zdElkPjwvRXJyb3I+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCopy/Works.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCopy/Works.replay new file mode 100644 index 000000000..ad20ebc9e --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestCopy/Works.replay @@ -0,0 +1,801 @@ +{ + "Initial": "AQAAAA7ffPQFJGb9aAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "31328e940fce27a9", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-src?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity", + "aws-chunked" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "sQqNsWTgdUEFt6mb5y4/5Q==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KSGVsbG8gV29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOlNoZXhWZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "ShexVg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "S/34Qf9O20DRdEr/R1NiPktCq5VGqhUD2xijll0YMeGc3pN1b4eX3Orujd2G9lyWSBEKRE4pRSHWE5vzKoKKVQ==" + ], + "X-Amz-Request-Id": [ + "DTAXCD7XYR956KMR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0dc174bb5324fa57", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-src", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "x+JdYUQK36wIFSwm5pX2yqqBLoSs8/h/tX6ROJSWmKBSZaTR/A9A9Imeq7LcIyLo3BHa6GkUTGrdPV6YiIitJQ==" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "DTAXD9F8P55PCDDX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "4d71cdb9e305f06d", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest-exists?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "51" + ], + "Content-Md5": [ + "oPqafXJA1cXuvXCJlDDFlw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "10" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "YQ0KY2xvYmJlciBtZQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6ZHZHeXlBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"a0fa9a7d7240d5c5eebd70899430c597\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "dvGyyA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "iGlDb0IS/ZC4iODq9ufguJlYJtTr4aIUyeiaHjVwfbDpMBLlxNn7MHqLOTTjlcIZanjOtEwkPdFNUMdQr19veA==" + ], + "X-Amz-Request-Id": [ + "DTAV3W722TSTCXGH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "3905d4b9548f166a", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fblob-for-copying-src" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "vVozl/1/GgaS5eVnWlocE03zoynAKiqVwFHqgu+Iye4OACj0HiWEjjUBfQe1w1A6Be+o9WIwGhufkUqI4BpUwQ==" + ], + "X-Amz-Request-Id": [ + "DTAXV8RWR4D4YNTZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjI2LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iYjEwYThkYjE2NGUwNzU0MTA1YjdhOTliZTcyZTNmZTUiPC9FVGFnPjxDaGVja3N1bUNSQzMyPlNoZXhWZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "28f92cfa80050d02", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "ShexVg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ihIYi7+dvaVLQ0NeLbVlrNNJTZWvypyN6sOaou5jQ2x4qmJdPZBu0HaizAj2TshlHJSCJmOtc+8AN86jZXap/A==" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "DTAS38EKJ7H4G8H5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "SGVsbG8gV29ybGQ=" + } + }, + { + "ID": "95afdab58cfa5e8d", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+aqoSvRLYTfLSsazz4W3j4bULyGHsYdNtcUXRUIzrtPBcF+W1AV2jh25xEG87KaJTOt7HMDyRLHMqsuhGDFBig==" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "DTAQXDB6Q35W1KA9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "41191226bd072bf5", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest-exists?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fblob-for-copying-src" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "buaFVkU/lFCgESKA1DqC7NMy4qWu40JFTHCyVDJEephyB5mQ1mqazUWjenypL9S324sXbOs6YirYerCLURx/qQ==" + ], + "X-Amz-Request-Id": [ + "DTAMP3MBR10SK2B1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjI2LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iYjEwYThkYjE2NGUwNzU0MTA1YjdhOTliZTcyZTNmZTUiPC9FVGFnPjxDaGVja3N1bUNSQzMyPlNoZXhWZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "cf54027b07b75484", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest-exists?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "ShexVg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "pmz1iL4SXJE6pebO4lWKIH0+W+vWNjer7KTbk6+F0DTj8GrUMqqCL6F1ceGCM5D4jx/9SPzALBoii+lrbGvOfg==" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "DTAVQYPV40B7P8QF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "SGVsbG8gV29ybGQ=" + } + }, + { + "ID": "7581871e5319e03a", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-copying-dest-exists", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Cache-Control": [ + "no-cache" + ], + "Content-Disposition": [ + "inline" + ], + "Content-Encoding": [ + "identity" + ], + "Content-Language": [ + "en" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"b10a8db164e0754105b7a99be72e3fe5\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Zq9TFloDJwhBGt40f7A/8fBiqON2Lz/ZXo62GetsJx1TbzK+Em1s68vuMTu1LjGewYkArPljrsCMPVu3eY0DxA==" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "DTAYDWBQCRK5Q951" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestDelete/NonExistentFails.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestDelete/NonExistentFails.replay new file mode 100644 index 000000000..b9f602154 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestDelete/NonExistentFails.replay @@ -0,0 +1,102 @@ +{ + "Initial": "AQAAAA7ffPQFOrpSkwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "d02ef832818af2b4", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/does-not-exist", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "V9vuJebGf6VucYoHcO2l97eAf3T98MnNQC8vllpFglVyKalwyraSYMyaNcmiA+URvdTozuQt7Ts=" + ], + "X-Amz-Request-Id": [ + "G6DVDTB2JCKBYMF1" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestDelete/Works.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestDelete/Works.replay new file mode 100644 index 000000000..af51c087c --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestDelete/Works.replay @@ -0,0 +1,364 @@ +{ + "Initial": "AQAAAA7ffPQGAuuwagAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "adb43694edd7731f", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-deleting?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "PiWWCnnbxptnTNTsZ6csYg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KSGVsbG8gd29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOmk5YWVVZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"3e25960a79dbc69b674cd4ec67a72c62\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "i9aeUg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "5jfGyoHdr2ihAlBLZc3RK1u7BXyMVNgaqnPNCCWCDO66VODQb1+V0t9voCg9AHn6aFTlgvZljUI=" + ], + "X-Amz-Request-Id": [ + "G6DYZV04V26TGQPK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "76fc5b5382050c77", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-deleting", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"3e25960a79dbc69b674cd4ec67a72c62\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Eb0aMwe0fOr/9GOsmdMXgvlRE6tJFU/fj+xGuMP/V1TV904xCZ6DQvlWd6jqOMJlkQP9IeG7R/c=" + ], + "X-Amz-Request-Id": [ + "G6DKHX2CWP582DGT" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "448e6d009712da9b", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-deleting?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "/0hU1pKj16IF6tdTOktZKGI52bEblvYFaC5XIc4uqT7+736daTF92wj5EZif0mLLQ8Ab7opf3aY=" + ], + "X-Amz-Request-Id": [ + "G6DK70F4SZ939MJR" + ] + }, + "Body": "" + } + }, + { + "ID": "7e259b034ddcb851", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-deleting?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Aw0BOydcwrNwVbWs0s0vmnwYz5hY7xVEHjDCi+Dj2UZ7Dr5T6TvoWpfQoSlcXH2M9wMRq7NFDQ8=" + ], + "X-Amz-Request-Id": [ + "G6DRJYWB60C26VHM" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1kZWxldGluZzwvS2V5PjxSZXF1ZXN0SWQ+RzZEUkpZV0I2MEMyNlZITTwvUmVxdWVzdElkPjxIb3N0SWQ+QXcwQk95ZGN3ck53VmJXczBzMHZtbndZejVoWTd4VkVIakRDaStEajJVWjdEcjVUNlR2b1dwZlFvU2xjWEgyTTl3TVJxN05GRFE4PTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "e1dcec13d49909be", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-deleting", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "oyvCqLPADXzd0VGBYbJGWYoZXb6SMX9veL9APW72a1+lg2X6mhFJCni3404qkBwXQPUvyYR8Sz4=" + ], + "X-Amz-Request-Id": [ + "G6DNR9RSNFQ9VHNQ" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestDirsWithCharactersBeforeDelimiter.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestDirsWithCharactersBeforeDelimiter.replay new file mode 100644 index 000000000..0e21994f3 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestDirsWithCharactersBeforeDelimiter.replay @@ -0,0 +1,1265 @@ +{ + "Initial": "AQAAAA7ffPP8MHmBngAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "a3c195045dcd10f0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "iWtp1OM/moykDnpqp6MtN6AL/PKLV+sBEbmuGYzRmA/y/tjhax4HRoqEO9CtABtus7Bd8EY/TUw6g/FIY4/naA==" + ], + "X-Amz-Request-Id": [ + "6F679WNBYDMA6F6B" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS90ZXN0RmlsZTFkaXIxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyL3Rlc3RGaWxlMWRpcjI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtL3QuPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90L3QvdDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "97b5e13bb617dfb0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=10\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "Qq7bl+xpW0Bmpw3LKlJYKLQlS6PK/1bgAnVn99RR5X9k2aiKxG+Fa3CaiRK3RgQZvgFRir9PC1icui9HZE4B5g==" + ], + "X-Amz-Request-Id": [ + "6F630M2223TT4VRR" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDwvTWF4S2V5cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3Rlc3RGaWxlMTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "5b673e5209d1a4b1", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=9\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "Vdu2M67aJNnhcpyOEJvT1rAUi94dG+wXHzMbfpTCpnRYb1T7LwG+IzHm/SvFeEnxQTuxYILl1X8o+0LUbQKI3A==" + ], + "X-Amz-Request-Id": [ + "ZVV7ZRQG4V5515NZ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz45PC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "75b7c2eda49f899c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=8\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "gGoZeX4033ax04LzqE6SuYwJKITuByrwZOTyuUHXOeAqKy6dDeLSFihz7+eN++OCao/X+gyBnLk9Ewrnzu/ASQ==" + ], + "X-Amz-Request-Id": [ + "ZVV4HMMJBC106DCF" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz44PC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "c1add166afcaf270", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=7\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "e36DpqGZCyjI4/wu1lreerfLQ3rTdlqIXoz7AjEmUryyKn+xCIacVgdPOYRCtCMQ3sieZ+CY3vTI/o/Elf+DNw==" + ], + "X-Amz-Request-Id": [ + "ZVVEMECW74DKYSSA" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz43PC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "b3502daa506ac191", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=6\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "uhUttKV5pW/HJVDwmz4ltddHv3ggnavKX/ObBJP1jVntxIllA5N5lYxet3Obkc200WSvEeXCwdMiJUbO59dZ3A==" + ], + "X-Amz-Request-Id": [ + "ZVV6JHRAH53DMGQJ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz42PC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "028eb3453c933692", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=5\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "IQ/WuiHI8W8B8IunO3TytgGa4aPeALwW4DQt1sil31pGd5n9cWi/7tlQEQOw7sgxMP/vL6xILU326uw+WIM8PA==" + ], + "X-Amz-Request-Id": [ + "ZVV9SH7FNKSTCX2R" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TmV4dE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LzwvTmV4dE1hcmtlcj48TWF4S2V5cz41PC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "bf8333f8952cf385", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-dirs-with-chars-before-delimiter%2Ft%2F\u0026max-keys=5\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "3fmQzqeyyoTzadBI6WmWi3ORgOmvTfEjCzoUnA+0nLXZ4sddwiNeOFgh/yWfu1U8mARGpuIeWa4cJByxD9JhwQ==" + ], + "X-Amz-Request-Id": [ + "ZVV43QM4Y2FPMJAR" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LzwvTWFya2VyPjxNYXhLZXlzPjU8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTE8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "900cad72d0300496", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=4\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "b2YoCynqtPGGEifkYSWZ5X5ExABzxOD4CEpdVXfI2jgthiWRTjSoI5b9Y3B8+x8TpJiOQqJ948GgoseICFib3A==" + ], + "X-Amz-Request-Id": [ + "ZVV8KBS0C1MHEZNR" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TmV4dE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L05leHRNYXJrZXI+PE1heEtleXM+NDwvTWF4S2V5cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoyMC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "3665872d0cb41791", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-dirs-with-chars-before-delimiter%2Ft-%2F\u0026max-keys=4\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "dUROfz8OVtptb37V/7Gc5Szyl2S2RjAnQJsez9U6SMI3qfBpjY2mMMEUxwUSnqRd25mRavNz+qUB5cHsycUIUw==" + ], + "X-Amz-Request-Id": [ + "ZVV6PKTJZ7QD6R6D" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L01hcmtlcj48TWF4S2V5cz40PC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "e1988953eaad9340", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=3\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "LYrivK9CNFNMmxPZ9ctKUXRD6F/APZM9/O3YfO7kBiATuixaVIcbioDwquMHVFSD8AKkojXiQRcVcY67bcO0Kg==" + ], + "X-Amz-Request-Id": [ + "ZVVFJBAQNNWWJPZV" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TmV4dE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLzwvTmV4dE1hcmtlcj48TWF4S2V5cz4zPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMi88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "152cab9c0270310f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-dirs-with-chars-before-delimiter%2Fdir2%2F\u0026max-keys=3\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "eXtopFhUG25j43wgCXMIbRC3Ydhg3Ec3He7zfy2voKQ+YeLZMQEjd05roT3fMT4f2l+V+Z1uDr+HSzhDUS87+g==" + ], + "X-Amz-Request-Id": [ + "ZVVEX6J4KC0GX4GJ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLzwvTWFya2VyPjxNYXhLZXlzPjM8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTE8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "2f0a69f6b9bbba2b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=2\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "o6OH2UIcNSjs1ifcHO8AFLmYy38oeIMTK70ZXVL3cmRHUKUqQ3TZB6U0CU26FJm9pgYebLkDbyDwL/OroQ0t6Q==" + ], + "X-Amz-Request-Id": [ + "ZVV89TSH2C6NE71F" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TmV4dE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvTmV4dE1hcmtlcj48TWF4S2V5cz4yPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "df796ce7c493a474", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-dirs-with-chars-before-delimiter%2Fdir1%2F\u0026max-keys=2\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "XsarrtSkk6eLKEFYcI/pptNwp/dIZzKSdTftfXmrH8j9VPHVrFvPSNKHpZ60dPKehaymZSvkCXOqcuckBO0H+A==" + ], + "X-Amz-Request-Id": [ + "ZVV2AXBJ846BSACR" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvTWFya2VyPjxOZXh0TWFya2VyPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvTmV4dE1hcmtlcj48TWF4S2V5cz4yPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdC0vPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "8946d43d48d6d31c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-dirs-with-chars-before-delimiter%2Ft-%2F\u0026max-keys=2\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "PGkk8rcmkSPffvKYkaWfWEVwF4HXH7b/hbZQDaYTbC5eXjX8mBwZQ7q5R66s9NSism7J+QsThZnFiP3lIvo80w==" + ], + "X-Amz-Request-Id": [ + "ZVVCH5NDPXNN4RSB" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L01hcmtlcj48TWF4S2V5cz4yPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvdGVzdEZpbGUxPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjIwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "55970f40568f774d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "fhmBDdXyMm3ntqTXBazvd2YK1vPmu1CNWfyxIbbdIg27BXXS2FEkErjiCUBna6kVHpD/nWbUhKeHIW4bES307A==" + ], + "X-Amz-Request-Id": [ + "ZVVEJJK5MMHGE02Y" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TmV4dE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9OZXh0TWFya2VyPjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "6f0d10f617fdac74", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-dirs-with-chars-before-delimiter%2Fd\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "iYkdf0XOK8uz/5WjwTlclFINtcxmZlDIWrX96CMpMkV9ln/4jISeXP7VrBptC+lzMYOlpAjJ8jPePt/b04uaug==" + ], + "X-Amz-Request-Id": [ + "ZVV483MTQH2XX6P0" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kPC9NYXJrZXI+PE5leHRNYXJrZXI+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS88L05leHRNYXJrZXI+PE1heEtleXM+MTwvTWF4S2V5cz48RGVsaW1pdGVyPi88L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvZGlyMS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "831dd01e9f0f20f4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-dirs-with-chars-before-delimiter%2Fdir1%2F\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "l/XflkGJUCzzUlEJxgyO4LmFyBVw04QfszQOcZDRSyhVUsCAhwf+jbAoRCu/H+b5vClUU3CUjwU5Bzwpjv0Zew==" + ], + "X-Amz-Request-Id": [ + "ZVV8BY1JG21FDRFS" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIxLzwvTWFya2VyPjxOZXh0TWFya2VyPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvPC9OZXh0TWFya2VyPjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL2RpcjIvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "71d480505e8c1c5c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-dirs-with-chars-before-delimiter%2Fdir2%2F\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "2eTRc6U2Uhqn79GqOsBRlR04nKyNdvlaC83UaL08jjWWL2p0VMcwKx/dT+0MgKaXC654ZNUCLmzXaCFMZbmiWw==" + ], + "X-Amz-Request-Id": [ + "ZVV7Q29YWBRJRBD5" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci9kaXIyLzwvTWFya2VyPjxOZXh0TWFya2VyPmJsb2ItZm9yLWRpcnMtd2l0aC1jaGFycy1iZWZvcmUtZGVsaW1pdGVyL3QtLzwvTmV4dE1hcmtlcj48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "b922f1a144597738", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-dirs-with-chars-before-delimiter%2Ft-%2F\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "3Yovkr+s1l3j6gtdf5+yeIOEe7by2hh9ll8JmquTAyLB9Y8WfHTF/cz3ke9gy/oHJORLY1N0v7qHGfhWtnPThw==" + ], + "X-Amz-Request-Id": [ + "ZVVD512966Q7QGBA" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LS88L01hcmtlcj48TmV4dE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LzwvTmV4dE1hcmtlcj48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "5727ab9038f3e74f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-dirs-with-chars-before-delimiter%2Ft%2F\u0026max-keys=1\u0026prefix=blob-for-dirs-with-chars-before-delimiter%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "srx31YfqIyYYkCYsvhm9RSazsK+5z5CX69p6AbikbP4OOItWWRahc6hVwoZNWruTfT1qbbqxVQTEQLamG5iVDw==" + ], + "X-Amz-Request-Id": [ + "ZVV3MV971XNH04HT" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGlycy13aXRoLWNoYXJzLWJlZm9yZS1kZWxpbWl0ZXIvPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90LzwvTWFya2VyPjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kaXJzLXdpdGgtY2hhcnMtYmVmb3JlLWRlbGltaXRlci90ZXN0RmlsZTE8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MjAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestIfNotExist.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestIfNotExist.replay new file mode 100644 index 000000000..4eec7ad80 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestIfNotExist.replay @@ -0,0 +1,321 @@ +{ + "Initial": "AQAAAA7fhzwPK5xpNQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "5045d286f3eb65f6", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-if-not-exist?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "If-None-Match": [ + "*" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text", + "BodyParts": [ + "Yg0KdXAgYW5kIGRvd24NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk9KM3lsQT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Tue, 08 Apr 2025 15:47:28 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OJ3ylA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "eoHgGX2RJ39A+fTSHfuTExnt65T66shsq5uNWX56Q2YrA3mBOF+7Pp21yICq8hP+POTeE/F5sv8=" + ], + "X-Amz-Request-Id": [ + "94AP8P1N75V893Y7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "51a58645841ec2a4", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-if-not-exist?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "If-None-Match": [ + "*" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text", + "BodyParts": [ + "Yg0KdXAgYW5kIGRvd24NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk9KM3lsQT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 412, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Tue, 08 Apr 2025 15:47:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "pd3gEWE3sbFdDApXOTt3f1maBpPpyVYshsHf9LnvMkCIINWX6I674+RI89VoHphhs6pJqmUdalg=" + ], + "X-Amz-Request-Id": [ + "94AR1WXP1W5WCF4M" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPlByZWNvbmRpdGlvbkZhaWxlZDwvQ29kZT48TWVzc2FnZT5BdCBsZWFzdCBvbmUgb2YgdGhlIHByZS1jb25kaXRpb25zIHlvdSBzcGVjaWZpZWQgZGlkIG5vdCBob2xkPC9NZXNzYWdlPjxDb25kaXRpb24+SWYtTm9uZS1NYXRjaDwvQ29uZGl0aW9uPjxSZXF1ZXN0SWQ+OTRBUjFXWFAxVzVXQ0Y0TTwvUmVxdWVzdElkPjxIb3N0SWQ+cGQzZ0VXRTNzYkZkREFwWE9UdDNmMW1hQnBQcHlWWXNoc0hmOUxudk1rQ0lJTldYNkk2NzQrUkk4OVZvSHBoaHM2cEpxbVVkYWxnPTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "43b2461e7a739ba7", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-if-not-exist", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text" + ], + "Date": [ + "Tue, 08 Apr 2025 15:47:28 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Last-Modified": [ + "Tue, 08 Apr 2025 15:47:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "t1QhT37zYQCrh17WZqLRk55Vd4VO75ePCj+SjTRHgp9KXG45dGdbVnnTqI+k0hy3Hmbyo9pKQcE=" + ], + "X-Amz-Request-Id": [ + "94AX1SBFCG9HQ0BQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b8f7ef2de28d0ce9", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-if-not-exist?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Tue, 08 Apr 2025 15:47:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rg6HfXOOHqcV4EiKwOZ4WO09Q08ysoupVMygEez+xMSW9wCE/+7t9d9CADTnmmYsaX1+9QS612E=" + ], + "X-Amz-Request-Id": [ + "94AQPEXVB0PM7Y2X" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-1.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-1.replay new file mode 100644 index 000000000..ef91fcdef --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-1.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQMFcKvYAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "eeff2bd1732048dd", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "NTJOASWOCkkHi502FVWCWQXlBU9gTDwMoBVVNfldXQ/mima3qtR76jU6MhFd/SIRKmijIiCIL7Y=" + ], + "X-Amz-Request-Id": [ + "RMN7B3P828QJHRSK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b4d6d4cca10a43ea", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "WdmKk+WOBiEi43H+SN5n72tkSZ4IXWEsSQLACw7HWhMAAwaDlfNbVyIHQFO7lUtNPb68Qgpm4aI=" + ], + "X-Amz-Request-Id": [ + "RMN59Q1PM80267S0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "8538bf85c809e2a7", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "NNheVpAmtmW12skQz2aepJjZZnILiJcnxxznMM8Gdru8jDTOPs+Dr6RrrOqtIDMLMXHoDzkxdHw=" + ], + "X-Amz-Request-Id": [ + "RMN2C6PM5CDQFHV3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "516d3d04c3e9cc2d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+ZTFCE1kijCX86JXbof9LOMo7h4aeI2VAfa4jITcUtS5tVdLOZBYBu1XD1dD1swRtbgyavOS/N8=" + ], + "X-Amz-Request-Id": [ + "RMN133N750J2P58W" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "830c76f02c6a7629", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "MMdQInArsgq26FNy5x0AJFRgay2GHUA4a12LlDKmWvxfUzlPOu6pmXWTo9lwC/ZjTOTMjjN/1sA=" + ], + "X-Amz-Request-Id": [ + "RMN6JDR5H3G4JPFE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjMzLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "e4ce906e0e8f63d8", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "WxrjLJuMHappy6e9PXVSQxHIs1X9w/ZLwyDSoLvXBCwe80QtGjIYz/AOSL7ZX7TvNDPxcxPkqNU=" + ], + "X-Amz-Request-Id": [ + "RMN24P6Z9W2J4GRP" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6838cd65079ecfa2", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "obhZ8a1lNBAuZdMwphTJykoYy7u0htiAgCG0JTkUArs/sh+VEUP4wucQkv62Z1K0cK2QiZaCaog=" + ], + "X-Amz-Request-Id": [ + "RMN57VH094Y1VY6H" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6eb034cbf698fcdc", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "HheJC7kUHbLPidm82ArJEkNYDuu4CF9rJGzuqTMJtwAI9DcDMinZPq1gjD/qcAp4sGpP+07jWTc=" + ], + "X-Amz-Request-Id": [ + "RMNFWZY2TTZFQYXC" + ] + }, + "Body": "" + } + }, + { + "ID": "7f469aa16dda2094", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "5tanzG+vfClkFP3jdOhbL2OBjujhOSmc9CR8REbnV7Mjrxo/E4lBvxrMGnoNX2NCEIxwUYkczWw=" + ], + "X-Amz-Request-Id": [ + "RMN1SXA42D0Y2KXP" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "3fe71c4695c54b7d", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x0____0x1____0x2____0x3____0x4____0x5____0x6____0x7____0x8____0x9____0xa____0xb____0xc____0xd____0xe____0xf__?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "g9sbZx8Zitv1RC9ch09Bkl9RVVUXu9depgbQSjPEQTKQMXC/PBsvlxsIdrs4GhXp8kIXnvctivM=" + ], + "X-Amz-Request-Id": [ + "RMN8CDZ3D7GS4FBV" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-2.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-2.replay new file mode 100644 index 000000000..2eebc307a --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-2.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQGL0UX5AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "58faccb6b5754992", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "HMGrpY4/qsJfzz6B/c6XV62CMldzg5rkGCHe7KL0K/r2ktYlNTpacrtCwTdinEndZb0EfwryD4c=" + ], + "X-Amz-Request-Id": [ + "G6DY0Y97VEVC692Y" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "3f873e8da512ad25", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "i1twmkMKt/PCSk4Qdz06Nk0YhvF7VyK9y+g4Wci7oy/rmGH242Y6qZS6samk9pP4rB/K82stoY8=" + ], + "X-Amz-Request-Id": [ + "G6DV8XC58S9ECZS1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "b9e74bc7cd718e14", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "bjpeNXCSypWlR50kbqTCZhEA34YlKKxnx2PqJh1tUxGeq0aChX8BzxB8xtiue9FVDh9QOYaJEtE=" + ], + "X-Amz-Request-Id": [ + "G6DP6FAJNEVKXW3R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a00003eae4339f9b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "oxQ+hiYMoN3MOTGAQ0G9D5bQAx0t1vvjnBVwteM4f+hkOYy5Tyan7SUc/3Vo04Z1I3xuFbyT1L0=" + ], + "X-Amz-Request-Id": [ + "G6DNG77W5V5V60XA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "f09699624c4bf6b1", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "b58dzpY8dhoWY3WlpImK9cX9Yrou03jISi6juTCgsQkmdSaDt9/wrzjcRpqvMwqsCITAQrha7Gc=" + ], + "X-Amz-Request-Id": [ + "G6DNW7M9ZY77T7NJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjI3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "f57996e03c288085", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "HeHOO7gN1PK3gR1ukCWbVMLUGTpzy8w4vioHzYGt0FAee8yX6LZ9HvJcC50JsnX1DE1aScPstcA=" + ], + "X-Amz-Request-Id": [ + "1Q3NR96C6NJ7A31N" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "d0376d55affcd9fd", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "hk/COyCreoUOPDlu5VCwnEb98R/d602JKfv7LE8ORsh2VmhQQS5xiCnRcXN3KGEuvkpHmunx/tg=" + ], + "X-Amz-Request-Id": [ + "1Q3ZXHP3T742WZNQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "212eab03e5195fd3", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "xhRChKLir+CdAzP+axaoHuy+whuQYIHB841Q52qw814EV+BIyaXtgXI+a/LHr8NULdaIZe6Lbxw=" + ], + "X-Amz-Request-Id": [ + "1Q3GAEVH715BRBEN" + ] + }, + "Body": "" + } + }, + { + "ID": "5898b6da04b264b3", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "czl1YlZfj/PnklXIKckqoVW7MDwRCELhltyH+8u/P7N9VpXEB3wfrif4/Bvh8HrMswRHPXc/oDk=" + ], + "X-Amz-Request-Id": [ + "1Q3Y659HQ6HJ3E84" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "30c33ab764c22fc8", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys__0x10____0x11____0x12____0x13____0x14____0x15____0x16____0x17____0x18____0x19____0x1a____0x1b____0x1c____0x1d____0x1e____0x1f__?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "VwQIzwk5ATne+ABhMassf/fUD9RBsGhAdpOWuls3crZPShh1L+GJjnBcoKBSNt8mRAgQtKvdaQw=" + ], + "X-Amz-Request-Id": [ + "1Q3K7B6HZWYR0WD9" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-3.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-3.replay new file mode 100644 index 000000000..505244bef --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-3.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQJJoGbrwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "710cb782cdf23c21", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "d9qQu51aTm7bYsIw/UT028NHRGFQxEQC/kxyS5ks8GptQs4aOZl2HcR3fck/r+uGAvyywrt5Dl4=" + ], + "X-Amz-Request-Id": [ + "6ZQA09NERWTTB304" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "8b8e9f39f9aa28ab", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "78nuWhuvygcTUiAGX7H4YdWBTcMl7eoqSkHd5eT1DbwIAM6Kyf2KAQC6WLgBx0fiuFaEOuE0sus=" + ], + "X-Amz-Request-Id": [ + "6ZQ7HWVJATEBZPDV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "859a67bf212aa1c9", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "H8ic7Vzmg/cycn4Tj/1VebYpEMEp+rFv2xD0WBdxGosjx7P27fP1JzPHE817ktHJzmwrq+xv3aQ=" + ], + "X-Amz-Request-Id": [ + "6ZQ9SYH8HGX0YMV1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "21496b9dd529201a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "t5V0cBE5Ef/WAMuTYzsr+ZqGtsBUdhY9BV4xgiXPxQXbVmUTbnWLL7j+24iqu648f9sYUEwjJ+M=" + ], + "X-Amz-Request-Id": [ + "6ZQDA1QWEZWR00F9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "265b6f3030f71329", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys+%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "wTMH0BcXUOM3jbhnm7t8NQhUx9SbzBKTRZQvHpN2mYWRCcfeFxTvCulDZlb9ogu1Q5W6KHw7JXY=" + ], + "X-Amz-Request-Id": [ + "6ZQCNYZJRYPBY0CX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjMwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "d375976d5624139d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "sDQEN//mnbstRHVS7S9aqM0MJMPKPhEEIityWXp7/zZJVCfRJtpFrSejQpREDkvhSf023gPwenc=" + ], + "X-Amz-Request-Id": [ + "6ZQCXY6N3B3RRC6E" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "2ddf945f02a66c29", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "HtHQB1wraDuhGN0NJJXs2uSVGiWQ1Nz/CFyKUnCBLqapsI2h5QKHKaMEDiTP9/Ssfyue7gyhc9E=" + ], + "X-Amz-Request-Id": [ + "6ZQ9H32BPSGGYJDD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "df1475c6afa6c83e", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "mss1cSWCjdOCS5ZsPOoNftpGAyNWjcwCTW5x2lEC6+2h+JaHfHxrRv3grorkGB8SXOcmxjam9u8=" + ], + "X-Amz-Request-Id": [ + "6ZQ4K55DFE1BCEYX" + ] + }, + "Body": "" + } + }, + { + "ID": "2673ea3dfd3ae3b6", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "TyR7lJP++E8EI1zYmbJaapkJjEIPA2VvaPYIRu857sMVSUpstoUbdkALtn2v4V+NiYWD5I74Nss=" + ], + "X-Amz-Request-Id": [ + "6ZQ14YK4KEE1Y2C9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "84d496ab37d4973a", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "YJa8hCIuNE1k1tbiBi+mQ6zhjC4sCAY4wjeBBv6bXCj22jmDPXwme8J42CRLN1LhIZyZo8lKt90=" + ], + "X-Amz-Request-Id": [ + "6ZQDMPNH1MA8JQCG" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-4.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-4.replay new file mode 100644 index 000000000..7be9fb88b --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-4.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQHCfeJ5AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "36eef26befb653ac", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Xrog6j11dxWI4lJnoJfHqPpsw7WCy8RudHlu8UkuD8mWXohck2OLJ8DvnWWBJcWaN5b+V3wMihQ=" + ], + "X-Amz-Request-Id": [ + "1Q3SNAQXPNMHMYMA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "06ece0d5f98f1ed3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "hmwVWhIvCijwoEcE5eikQqasmvrGYuBhm5oawFQWBhvhHr0H9gsyv47EvRokMJDpz58KydrpBZc=" + ], + "X-Amz-Request-Id": [ + "1Q3G11AAHJ6BYV4M" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "2a0c99d2fae48fb0", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9IEz6gYDB6WUSKQmeRLhOtlzf7LEdsRaf9xgpUjP6NqivTYzohRTOmSaA5FFC684zxC3fQbbndk=" + ], + "X-Amz-Request-Id": [ + "1Q3M2TXPEYF6W46T" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "074757b9ec22c20d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "BDsC2ceh0Kb4aZEciw58fJE38o7R+TYWB3tcYz+Lpjh08NxXfVNos4/YGtMrlFs5Mk3jXiKtOpM=" + ], + "X-Amz-Request-Id": [ + "1Q3X6ZBPB22M5840" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "59926042dde8a97d", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%3A%3B%3C%3D%3E%3F" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "q12mlOJ0nlt8HrAkrM1yB4J8GXC1WN6TQa1VOES9FIyBILACO+nF/cmzMN3FcHGW/yEmFApXOQg=" + ], + "X-Amz-Request-Id": [ + "1Q3S4YYKXJX2102Q" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjI4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "5ad72092a7f1980d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "+qHIjLq1LnfGR70lcScpdWwjSHJ+QAyEXt9CTQa03BTqzIQmRVhrDK7MDwOYahukBtXveobi88c=" + ], + "X-Amz-Request-Id": [ + "1Q3RV8VYNP4D6PJ1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "0c22642c619d90fc", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "J8UnbjlrZxxD6W5228IzBUFfS5V1rui70pxVbnrs0lEkXfqGlSejLHXIa/LJq8rXEa0AvfMYUdw=" + ], + "X-Amz-Request-Id": [ + "1Q3GJB15Y5RYTR8W" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "55c585ca5baac28c", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "M48lTsP84L1Q+r91uMZ3dvp9ifq2OcrrCFlOrXglX1IcyJWXsYbkNR+fMnxanHXmjXdSXSZ8/yY=" + ], + "X-Amz-Request-Id": [ + "1Q3TJ09JWWR4P8JH" + ] + }, + "Body": "" + } + }, + { + "ID": "816c12aac8de8e2a", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "2WVh4Iqu1t1Bcht64Jg4DjtiGALCRae6ooT7EwAN2bsFtKH4QWXsRGkoQHfILNXUOKIUHIv1eno=" + ], + "X-Amz-Request-Id": [ + "1Q3KC1JZMSY5SCQ5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "13c2ce5dca756239", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%3A%3B%3C%3D%3E%3F?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "xGMha6xnX2Hl/6RS005h4YAJiXD305QO5lfQ9Fbfl4iYBSMCLMlJHnxuYKYdJirJx5ay8w0+bvs=" + ], + "X-Amz-Request-Id": [ + "1Q3QNB9RCRTAN28F" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-5.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-5.replay new file mode 100644 index 000000000..f127c21db --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-5.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQHIHLXPwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "2c1aa77da04aa47c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "4jwO6Cc01LSkXJ9hNu3VAEZfvr5/XRx6EZhbTdGNWrMSuX19t3VyLCwRZJAr8+XAqt5ZphbNnX1Q9hb4uzUBEA==" + ], + "X-Amz-Request-Id": [ + "1Q3J6QA3KC4C2A06" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7818b31266cf626c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "gZgdNglBmdF3aK1u52jT52NJqdlXXNJMszjPWklSoG4J33S4qKqefHCcWGLMbyk0J+Q6daAHvXaiA1ZZGoQddA==" + ], + "X-Amz-Request-Id": [ + "1Q3H7Y76B1WG6WG4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "deaab2034ad1b6fa", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "OwApKHRllBBgVOviILiM3Z2iplYHZlVK45MyCi97o5J9poZiudcVhUpAGRj5xejsq9eb/55RTpNqH9FGc0wqKg==" + ], + "X-Amz-Request-Id": [ + "1Q3REJ1T199CZPBB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "d4b4f1b0289be466", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "AVQGBkAgnRvY939DGUp3qQyQgTvBDG+QzcFjptjv0dDUee1i9WozMj3Se4C+QMZS+NtmShyJwyV3AQTlkAUukQ==" + ], + "X-Amz-Request-Id": [ + "1Q3GPVWEGKMSPTBD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "1fb372a99f07dffc", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%40" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "fLkY2YBV0NPwEw/rLNgxLq6wHd4tjhmfb1erC1H1VmiH59C20qz42GVuMesx1SnBKMUV7Nl33064Uj1u9GDDMA==" + ], + "X-Amz-Request-Id": [ + "1Q3Q1ZS3ZNQPTB06" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjI4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "c25de55d1f2b3738", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "X7FRTjuul9Kkr9BzXZkWH7wMoTYOBphmESwYoQiDif0k8X8hR3R9T6xAuyaTNuLdskSJIOy5TiJDlWJ1q5tuUw==" + ], + "X-Amz-Request-Id": [ + "1Q3SRFQCPW2R5PWN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "1d347b91886eecb2", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Z5utkfNW5FsEzC87aHm3qS0SmY5VmtEHDLL2OH3dCPD6Cd1tBq6auhlY6VJMsLHtqemBA/b/BR9DWv5D4O8Gig==" + ], + "X-Amz-Request-Id": [ + "1Q3MB5WE36YY0RDJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ce20dcb0510edea8", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Oisuh5KJaT0ZJv1Ed2QW+f+ULsKZ69DK3xlpM4n9okf2R4wx0XqnLROVofkPSXJrIEC2cUAF0ddRCICw4mVGgw==" + ], + "X-Amz-Request-Id": [ + "1Q3WY2HV4WEWERG0" + ] + }, + "Body": "" + } + }, + { + "ID": "54eeeccd1175c3d4", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "0/ZdNL2QXVbYkSdkmhf780lTdjstRZySNtJsyyaCuPcrewKwqy9ixSVvHYhqHn3CSwJI2kZIS6w4tiLDWfeZyA==" + ], + "X-Amz-Request-Id": [ + "1Q3HGV2V8FB0K6B2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "f5b2181798b13313", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%40?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Yt+gZzqAarHkN3RJmROgLXUGm+nQEPA72IJsUTH2v/e9rI1OnZWT+F5ni6C4SPlXeSzANWE+Cb6VRLXIt0+g4Q==" + ], + "X-Amz-Request-Id": [ + "1Q3NKD1JF906V62E" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-6.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-6.replay new file mode 100644 index 000000000..344a7eb00 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-6.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQMNVQS6QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "62c4f6f7df624830", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "p9+ZsMVpCdBi8hx52C4Iev7qU8izzEi0c6Fhp4kK2rZimB9onE77SlfvrzTV6LjNmpE9/AbWExs=" + ], + "X-Amz-Request-Id": [ + "RMN1MKJHDAPBCSTB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "75f3231e5fc4c0fb", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "c44yC7GCMszN2KLuC5t4OOxJN2chl6wGlCQeoaRiensTBXLluigSBeRQCeeLxPfT41d7fjPM5vU=" + ], + "X-Amz-Request-Id": [ + "RMN5FM90MZP706PG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "beb40c34bb8d37ee", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "mgy2IAFJRMy1wDgNmwqVH1uqez55BrQRUFMo+tdORpgUW3C5UfuIuvRY95aZbkEXWwowI5/KCVc=" + ], + "X-Amz-Request-Id": [ + "1RC879SM4Q6ZKRX1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "fcb06b7421fdeaba", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ZVEvp0xMjT/xaix/YXPPyGVh+yhJoVlzLY9tTodzWYp798SHCuiKc4y3EilHREbaUSHzMeaxyvo=" + ], + "X-Amz-Request-Id": [ + "1RC30HRVVEPYM4GB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "827c14e7bc79a02a", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%5B%5C%5D%5E_" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9yivkXaHbusDjxDfGIY7z84NWDQGrLnXzWbN8hjPq7e45OYemcr8rqm57lEwPUbLBgJu45zjgf4=" + ], + "X-Amz-Request-Id": [ + "1RCBN4K903Q55CF8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjM0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "632bf05b4afe0d8f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "6OC3WSCjQcCe2LMeMDWUpEHgKhRUmVxHkEn2bQeutxJbr/Fm+Taw9y47I8dfrbxfgoCGeOzh7rY=" + ], + "X-Amz-Request-Id": [ + "1RC4W846MK29WVFS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "a3fa367275e2cab6", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "IOzTNl8t6kP3j3AvA8SyuJt+MuaRoBeJoEAvLFLKF1pyLaP4lY2PJIedzmfBnWoA3YGfTyvQBEA=" + ], + "X-Amz-Request-Id": [ + "1RC03Z1W2DG9KNX9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "fef9a1a4e67d8996", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "lx9ib1GhgCtbqQq66F7YNLU8ZRgaBhEGNWeoX/Ust+c2mIAcTxWkzwwM7ajFYLs6hORN2w+jI/A=" + ], + "X-Amz-Request-Id": [ + "1RCFSXVEBWE1HSZ4" + ] + }, + "Body": "" + } + }, + { + "ID": "b304e958525ab5ed", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "zE/yP3yIkZI3H3EwUBvtbt02oFGiSXVZZ75i8jAxiIpSYZzdypqERQuBMR2WRVp9/hfU1T1z5L4=" + ], + "X-Amz-Request-Id": [ + "1RC54WCJGE9134ZM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7715971cadd958a7", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%5B%5C%5D%5E_?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Wx+3oOGeHz4S1HXoi1+5z+h1WSrdevEhCRKGiHt6bLYtTYUBR9/vl9FET0/fHxRVFwvUTeh2K/M=" + ], + "X-Amz-Request-Id": [ + "1RC6YPN0WQ7N0Z3F" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-7.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-7.replay new file mode 100644 index 000000000..985a8a1ce --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-7.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQHOC52uQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "ea8fe15bc4524272", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "OEK0+N884GAcf/UFrVz4sF2DgRWf62cJKyyeLGs2Q91vrNbLlZB/9TJ0VB1hZv7DLImbM5oMdJk=" + ], + "X-Amz-Request-Id": [ + "1Q3KW0Y1M7PE3K8M" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "fa1d3d3917ba7258", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Xjd0rl74Oe9BoEua/ymfmxrAZ0oWa3FhMQpVuQwYxbtOJbNf+lKGonDSWkRpkEPWSOIgHmaZGOQ=" + ], + "X-Amz-Request-Id": [ + "5CTWW8F2NXN6R002" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "4cc182291f7a36c5", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Cg178bFXxBr4Ie0qn+cuxkm+jmvh2GJKGTll7jrFNobdnZ1EtMjSDUPtpmu/FSWqlOFkusYd05Q=" + ], + "X-Amz-Request-Id": [ + "5CTJJK7ZRHHSGQXA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "259306fbfc8b1088", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9tMxojbULIwFWobeqDQr81xTjiKpfJg69GKbV+FDGGWxD28Uw5ZtfCwtZdU1u7WJzFnRyPq0BLU=" + ], + "X-Amz-Request-Id": [ + "5CTKKFGC32MSE358" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "23f6c091c15850ee", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%60" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "AK+xjNmQSVEddWUqU2c5ZFS+uei4fM9oouN6M+4Tmbt0oZWjxLPdwzHJaV3RzuzdJjDYHvolldw=" + ], + "X-Amz-Request-Id": [ + "5CTW94JF3TBSHTTA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjI5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "0ba4a5c273c667e4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "a4HNph8aMv8G/JR3/2qplTavqcsHPJ+M+Qi35RJP6RyEL+TgCxe7pPCd4TxmCi0gZiMcGeoRPR8=" + ], + "X-Amz-Request-Id": [ + "5CTX1QF1DTHDTYPM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "841562b518d7cbee", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "JBMZTsm7xmoncAvaqP6I8LxWIIDcXT9k2CkpygwU5qBklNjQstj6+KRFV/fI+5AWLHNGK+EIwtU=" + ], + "X-Amz-Request-Id": [ + "5CTXXYWVG477VARB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "58a7132119090204", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "SZTXaLrhFSsQRmzT1m3A/2yhBoIaPR1IjfLrDpk2abT3hCHgfi+CN3Xu4xZKfSRV3HqSp0SE4PY=" + ], + "X-Amz-Request-Id": [ + "5CTJ1PGGGJMEQMDZ" + ] + }, + "Body": "" + } + }, + { + "ID": "635ca271959bd6fc", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:28 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Bb/63R2H502PrW0YzKyvGSfGvEheZko7h1O5WjORo7oaEfy7iuSA3QBiMvwjrlY8as9Ip7KJNvs=" + ], + "X-Amz-Request-Id": [ + "5CTVEQMAWMQQWNX2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c8a5f1d5e51c75e6", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%60?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "7/+fe1eXLh8y6u6T69Uw7aHtMwTaZuv2gHR8DHD11xnLtsByDpuGJZoKly9PEMjJul8IBZDqNJk=" + ], + "X-Amz-Request-Id": [ + "5CTXAVM3RNKBAHM6" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-8.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-8.replay new file mode 100644 index 000000000..399230749 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/ascii-8.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQKAO2DuAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "beab6590d9beb84c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "fzUrxzEuFgKSY3tsHZeeOdn3lYF3vxl0XI+q+4gVPDxwZmUasaj9Z5Sv8wf6geNRoSL9L0gMT/g=" + ], + "X-Amz-Request-Id": [ + "B6FH40WAKMMRN667" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "42cf53774f841925", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "a4xtHMPDCyzq6+eIWX1rRYiy6MxGmeZ9gcBmkOiA7fcF51Rn60tyJ/o5SHqIlII3OO0ugF+Vfr0=" + ], + "X-Amz-Request-Id": [ + "B6FTDEFKXQGYX0W1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "aed4ad3cdbb12f89", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "CldiQhqpAVNSn2D7cV/rrtU+yRsBklGttoHeZXjd3/h92D/Om09AvWjAOkBjVbzUUW0GACPLlfk=" + ], + "X-Amz-Request-Id": [ + "B6FX7Q5B761F2NCN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "73385d78a57bdbe1", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "8LvdPhnIyKmARNEIHgD7+LRxPP3NeDP4pM4RiRPb0YutG2c6lVCi+QPzz9fKmBeqAeIFz73AU/g=" + ], + "X-Amz-Request-Id": [ + "B6FVQNHHM3CVZ6SS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "0307fa8fed446826", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%7B%7C%7D~%7F" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "KVFfVFUCDJC7G5sbvbvu+yANQM8F4HCUI+/U5qHy0yxSxIcdB7Zy4O9ZiNCBNGYaVhhDNreqqXo=" + ], + "X-Amz-Request-Id": [ + "B6FJYVXS9GVMENBF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjMxLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "de031df7bfa68625", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "mwZUpKUlYhtH6bgc1ILkd3j95toJU3U2V/wdwVfW6Z9d+7CO7RJFydq1ROoiLnFwhzwitcbAIEQ=" + ], + "X-Amz-Request-Id": [ + "B6FRJTWVN9DA44Y0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "43ea3452fd3d0374", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "UzFzYYL+qkD/OncyPg5nO3JOJ6noZWva3UXn8o+agjnnlhNDhUcsRPRnHejXsAm1ExFPvO5rmWM=" + ], + "X-Amz-Request-Id": [ + "B6FQ5MW1BTQZQVKY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "4d15d629823dfdf3", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Dr5qHMOWaXKJLaAfoonXe1+BulQBzLXiu+ZM5t28mnh8Qdqd8+pF4xtRoExO5EIyzJuLoHGYiYM=" + ], + "X-Amz-Request-Id": [ + "B6FWZ1QF82AHR6DX" + ] + }, + "Body": "" + } + }, + { + "ID": "5b3529f7fda167ac", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "k8r/anpgeyna22EElRKM6Kykjaldiz+/BZGYqt7JnjDU5OnEMCBnXQ5+wUPC3mgef3kS7Ncl40s=" + ], + "X-Amz-Request-Id": [ + "B6FNM0PRPQKXZK5B" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "5421d747cbbcf3a1", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%7B%7C%7D~%7F?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "j13rf+PhyjQhroKiOjYXuK8UkhmSrhtk1ziknsYeLj4HWneL3tuBbheFmiLl0U6Xzu4qoEyr6Ts=" + ], + "X-Amz-Request-Id": [ + "B6FZGNZE6JJWG31Y" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/backslashes.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/backslashes.replay new file mode 100644 index 000000000..6dfb1dbbd --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/backslashes.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQKLDd7OAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "194039285a2149ed", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "+1V2lbVzkaIzBCFsFZcmxyXL4jUlI6bYQ2Re494HmIqke9km2/aH68nw3tnJofh57W2gwsgVhhc=" + ], + "X-Amz-Request-Id": [ + "B6FXGDYB1CJMKRHP" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "cf7ab08078703b03", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "5eSSz02JHrijV686x/q7aWMw7op99rM0EQTc3tG4L/f0ju5/eHcTe9S8ciMJzBmf9slCOxHr9jg=" + ], + "X-Amz-Request-Id": [ + "B6FJ83FA99AFABEM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "6b8da759e790a436", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "NCTNBVlVRj8HAgzG9UI0MHHPU+mYxk8x/fwZuQ2Y0x382bXTx9KhH3TNe38Q5mRCNGRl1SG8xXc=" + ], + "X-Amz-Request-Id": [ + "B6FNJQ710NAY9YMR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "8093075c57669cdd", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "XgjZk0vwYoXa34DZE0Ed/1ZAA8dNIEOOjP9aoe5UP8DiG0qSGzRn1VV6GLs2HJ+WaRMvksbHj7g=" + ], + "X-Amz-Request-Id": [ + "B6FXBSMXPK2187W1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "25788f804945fede", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keysfoo%5Cbar%5Cbaz" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "WYf909h/+CR70yaTnps2646q3gqbHFb5DUPaNEon78/+zDNdInLbBodtE0BTFNHIl1vcid4sETA=" + ], + "X-Amz-Request-Id": [ + "B6FXQ2PV3PNBV128" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjMxLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "c79c5bf3f68ae037", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "fybe0ml5y0577t5SCOXT7rl8jPoV9rb7hY5iiQ6xsocP27/tD8PebjgInDHS7p7ykKefPOeMFTo=" + ], + "X-Amz-Request-Id": [ + "B6FSZV8DNBN34P1F" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "2efb92e71c1bbfa0", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "jx+ZErypivXdbMuvdg03cN6kKKxSJKyTEm9/+19C8BBNY0/2FsHlACJhQ4qpE93KYg82jYgAIQs=" + ], + "X-Amz-Request-Id": [ + "B6FZJJXDXWZ4CR61" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "446c3092302dc70c", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "xUcmCqCLN49uVaPPvndv18CMPQuss4umf/8S2wl9l634gZ/WlIH37m+3Qu4C3Zg9sEufrxBYndI=" + ], + "X-Amz-Request-Id": [ + "5BM1WTJ11KRXTZXA" + ] + }, + "Body": "" + } + }, + { + "ID": "9efaf62c264bf645", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "1qrxSqgPCCpYqpLVKXwSUeBYiYBgCugEbkd45upEmA4MlrsNzjGNO0Cb5Gx/CzSkQ58ZsozCgpk=" + ], + "X-Amz-Request-Id": [ + "5BM2FK2GWRR596ER" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "93cdea2eee836367", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%5Cbar%5Cbaz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "0vTGaONumumMEnqaXXlTLA/AqYgMDFwTmNIRAHQGr0aXkYR8rqwcPymrrZZ13l2lh+V/YOdu4sE=" + ], + "X-Amz-Request-Id": [ + "5BMDVMSGTGT9FBWY" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/dotdotbackslash.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/dotdotbackslash.replay new file mode 100644 index 000000000..5c511274a --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/dotdotbackslash.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQLBYbaTQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "c87bd440b65b2f67", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "LDYk9NbS3LGcOj8PPazgQJu3rDVn1VHScdKSTtb7C/SKbD8fz0fEQsv9rpwYZ3lnkqdxtEfKF8U=" + ], + "X-Amz-Request-Id": [ + "5BMFZ0TCHFS7RKE2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "62de6f56ce124893", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "B3A18L7nDOq59Hjs0Nhiw2TJHwTQYpigjcB7Zfncmug+m78YsRFcycCKa1KLGrzjl9erLG/VuhQ=" + ], + "X-Amz-Request-Id": [ + "5BM0KQHDDVV6ABAR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "67588371ce517324", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "iIXgmyfbNwLF2mvbO0x15K/Iv75opQ9agHZyHCeatbeHvrqImsj8Jonjf/LiSvMywObz9YPDEBU=" + ], + "X-Amz-Request-Id": [ + "5BMFKCEATK1FQWWS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "4c428197cbf34ba4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "U4DO3aWkna+U1pwWybouF2KHN58IFZ4ioOVsHcgHjSa/LiforH13n5mXPKwNKkyyA3DrBXUWoYg=" + ], + "X-Amz-Request-Id": [ + "5BM5DWS8FJRCQHYK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "b79a34a39afd954e", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "vfNPmRoIHQ+MfIkoGMmXBDbVKLxYZHJWB4gTQ9ojRrODtzzW0A1u+PG4vEEyEbX/mY4Z/jIKR5c=" + ], + "X-Amz-Request-Id": [ + "5BM0J43VP8V0TFVR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjMyLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "260e5da7e2c183bd", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "8KYqppCOMoeSzyJtwqZleh5c+wq3WvuOaJypl/I9z+oHUTYP2qnQAl9sW11aeqpZv15C+2AnD4U=" + ], + "X-Amz-Request-Id": [ + "5BM9GJSJEXQT7JQT" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "ac1b10f4633f6386", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "XKrvTLf2bIAjrK9O9BRBStxJ5hL7wAyE71Vcg6/c3c0cNa4RHvoZ3Fh4jXUxYVUgN86iZkl35Ac=" + ], + "X-Amz-Request-Id": [ + "5BM9XX96CK5TGBXQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "912836ea2bef5e85", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "oinGxjVs1klcbd5l7C8NvrTx7H+Vu4FP0qCNCFwTMNhNzxF+F0PVfwsvqgfiRJDb/lHGdSRBqYk=" + ], + "X-Amz-Request-Id": [ + "5BM5XX44D0N8JVRQ" + ] + }, + "Body": "" + } + }, + { + "ID": "04c5a75a1a10f161", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "pmkZkJIv/Dabvt23v7gIUhBv9VIqu/7Zm7WSq1RtGnXfqoHR6/xfEV0Gcvv3H0f9eqyyR1J7DXw=" + ], + "X-Amz-Request-Id": [ + "5BMEHFX7QRZGGQ3Z" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b303d448be25e3d3", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "xXlQWjttRRGFeYklCPZuELHJRazCwEgWH6GZKGt8pKJU6r/V/03xIzJra99bY2r3iF3X1bsFeg8=" + ], + "X-Amz-Request-Id": [ + "5BM90APE3C2CZG1R" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/dotdotslash.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/dotdotslash.replay new file mode 100644 index 000000000..eebc3832a --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/dotdotslash.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQKFmm7xQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "a9bda85644cf0414", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "HHEHydTzNEBRASQ0Js5nqhfj7xrRksHxCXmLznmhV4XFVxB50ILISK/hZ3k/3/V8Q5O6Z2uv4ehfzHhvl9U6QQ==" + ], + "X-Amz-Request-Id": [ + "B6FVNSXGVAFDHD1D" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "223e4347d0e95698", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "X0o3eocDXJn1HpEazd9W2KjNt4CtShlOTqV9Uok1eVXCHlo9KwO7l9OyRBtK8g5dqzAetB5SfrEdXQeHaVGn2w==" + ], + "X-Amz-Request-Id": [ + "B6FMNSWQWD54WMMJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "ad054d217909df47", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "NxvZqBQWHmuZD/8r+s9j0bLkWwjifBDBYHZuQQyD8t/hiqziq6Yo3hqq2cxUWlX33DhgG2UrJ1NhlqvFzCXWMQ==" + ], + "X-Amz-Request-Id": [ + "B6FR51P15Z5QTE6P" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c1fd31d499fc85d7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "O3iEs40M10c7v5na6i2ktKjdixRVrrZN3VF+ZWxUv873FZwM/3LuAK3p7Zh3oxk0WlDdvlGVxJIUV513bmEN0A==" + ], + "X-Amz-Request-Id": [ + "B6FPCBA33HTT91XX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "7944c8a7d8b59571", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys..__0x2f__foo%2F..__0x2f__bar%2F..__0x2f__..__0x2f__baz..__0x2f__" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "R6e3VZijGGe4F5kFyq2VslRj6PofyyLvNVDwAIePW7PC+LUbG118LZ5QUnIGrjoLrHWFnZXA48jm/knUkK0ygQ==" + ], + "X-Amz-Request-Id": [ + "B6FPVQX8XMP8GBR1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjMxLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "29e2d47f41d58dcd", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "FsyN/FsHGKoLyUW15W8jSB/FxMj+5wxaGZNsKdTdi+Jwfgx2c9te4iBQ0xzcz30qS3zpG0hgkuVDa2chaQPfaw==" + ], + "X-Amz-Request-Id": [ + "B6FS4ZX651CBEYX6" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "5d27b40bcd4d2e92", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "QnzLZQc1xgVxPSS7PCVDdenPpJUuut3hzO9yWcRjbszeZXvDIl84u6L7OuC+igoSjNNQCY1McFaU370Eu+UhRw==" + ], + "X-Amz-Request-Id": [ + "B6FXT105PT0PSX8F" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "20bdcc2c977dc209", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "wis3MNjlBGWpkdAAz/u4Du1vZEftAX4X4BBAJTiIlr0Ry5xC7ee1vt24M+EesVX9+3uN7KJXr+7aPisvNeIYNg==" + ], + "X-Amz-Request-Id": [ + "B6FQFFFK2YHEKWAQ" + ] + }, + "Body": "" + } + }, + { + "ID": "038c09a4f5dac9be", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "RvhR74RbD5rMoKiWXAP3TkMESH1wNtdDHWeI8NRg3zpMFk9Rb6o8dIYEHxepqSKSRd2pJgD3Xq26c6zOSWcpig==" + ], + "X-Amz-Request-Id": [ + "B6FZD78JSA82PNJ4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "bc3e35a94b3e3abf", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..__0x2f__foo/..__0x2f__bar/..__0x2f__..__0x2f__baz..__0x2f__?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:31 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "iaD3TXH25tpbit7i+dX8LyoGzGAos+1DnG38ll61haJ/+giPEMmWfl4yuOdM6JfokqnB3UOyoXd5WilQgz9hlw==" + ], + "X-Amz-Request-Id": [ + "B6FXX202E9JQNHRX" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/fwdslashes.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/fwdslashes.replay new file mode 100644 index 000000000..1de0086d7 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/fwdslashes.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQGGyb28QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "80a0af3800315606", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Ay/Qh6x21xxJ5rdJZBC23FyPIZN4U3w9CrSJ2toFyLTiAEHpPmLD2zb/G7KLizTK2wNPA46/HsQ=" + ], + "X-Amz-Request-Id": [ + "G6DSNQPMPCXRS3ZC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "64b797aa4b8aa002", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ghA1EQzSMjzyZcLzXr9VQl/dy5P8FJoUN2pwKQLbOIgAU6b2qBY+Z4q7UbHGkHttdi+pvqI6CUY=" + ], + "X-Amz-Request-Id": [ + "G6DVWY6DV4Y1P569" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "02a8dbe1f6d061a7", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "oGsb/5inOpkhXLjpdRY1HYdVIJ+0Nu9o/k3SpJv3CqzCLIJ6lQ9E+eIMEW12E4cjooKSb3HopWE=" + ], + "X-Amz-Request-Id": [ + "G6DQ85N31ZRVJV17" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "473c16d8689795b4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "BacY9y3A2Iy4X8LjaN9czW8mdj5T/1TnH0PVO2K2yGVJOSDHf6Iv80cNIcsDz1FfESXY5mm5N3E=" + ], + "X-Amz-Request-Id": [ + "G6DP0R0YRC6DPXM5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "d45ff75ca4125446", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keysfoo%2Fbar%2Fbaz" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "nM5dbj7aH87w4ZtF/WzfEsUzjAFQQJslcAFS8RDEIe66zbB82yIzJubSrtIFLFvozbwQrGeX7HQ=" + ], + "X-Amz-Request-Id": [ + "G6DT72RJNW7HMP1V" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjI3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "31fc981aba62b402", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "snjhk0p0PQetQ6DorwvPb8/vJ+T/Uff8fXrmXrWaz0s5vspzNhY/ZL9S3BfGbqZvVGD8Kwvt9Qo=" + ], + "X-Amz-Request-Id": [ + "G6DZSVQT9J6766SC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "7f71caa109d5bc1d", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "pQqsNCbnoTvASWwRA2a4sKP42be2W150PeTbSMq6lRgdGPbG7Y1ZZhcU6n6rcLTs4Tu8qkxpfmI=" + ], + "X-Amz-Request-Id": [ + "G6DT1EQG2VNRDMZW" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "40756cd5ea9678c6", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rM0yUQ0WW9K+Taq3yRHNUjDf+V/dyFabdlK+lSZCEUIYsl/VHPRGMizP5fBbtbtTZcw4h7au37k=" + ], + "X-Amz-Request-Id": [ + "G6DN830DX8N56Q0X" + ] + }, + "Body": "" + } + }, + { + "ID": "c997ccacf92efb9e", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "LyPoaxEP2B3LNI2ePfr+lrcBGMBEyx3UMv8+AB7wCIdiRu6Hwl6FRgMDhwRf338PmbgCwN/tKBg=" + ], + "X-Amz-Request-Id": [ + "G6DWAKRZZ2ES39PY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "22a22291aec30e39", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo/bar/baz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:27 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "JckZxi1KzgwoTqc8vNi/q7lJbvnirHmbO8rbfyiZUjhZFkVSfiIpxSuETJH7ekNfErK8wsx+CJY=" + ], + "X-Amz-Request-Id": [ + "G6DGP6NMS30YVVX3" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/non-UTF8_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/non-UTF8_fails.replay new file mode 100644 index 000000000..a9daaba6c --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/non-UTF8_fails.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPQGGwabvgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/quote.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/quote.replay new file mode 100644 index 000000000..e6353edda --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/quote.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQIN+NDogAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "566749c4fb545d49", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "9ofoUdnQVuvHaKCJ5GruK/P24HqQ8wg4xd3S2vUWtOuqzRapn0T1DLWnOqcWA9Hy4Tu9f5j++UM=" + ], + "X-Amz-Request-Id": [ + "5CTGGTB6VJ7KJ1PB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b62ae402f7874b3d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "GY8vmOwD8GFzIwU+yXguSbPjKGtEkwZ7wDsXDl5j2OLelj21w2oS3MoXNayiU6mZ+H0Z0xhDPJU=" + ], + "X-Amz-Request-Id": [ + "6ZQ9EWXB35RXNWJG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "a6511966228257b5", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rOJTHhDmWZHJddk4kP8MXv2LRoX866nj30fbpIUwpfmyuQsXUDDGbxBx2vjHAIydzDIQ+CPqHek=" + ], + "X-Amz-Request-Id": [ + "6ZQ6C83Y8P6BDY7C" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ca347503182c410f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "fLTFqcbfNdncdoLjMhLVj/huC/d9SSG60gKe732xNS1KjASJxdakfyVMhsFhRnTGWnWHCVsO3jo=" + ], + "X-Amz-Request-Id": [ + "6ZQEA3GSSGV9GZN9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "a9665a8f42daccc2", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keysfoo%22bar%22baz" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "lz2zt0sym/sO9WGzHCDpRbx4zI8HR4fn4ypWmaeo0h9VqIBoF+ej5jKPK3RjU8hS6hZ0X+gyhEw=" + ], + "X-Amz-Request-Id": [ + "6ZQF0ZX565YRJ07V" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjMwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "68be9351eb44c4d2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "/c1iFLswgJKVz/4LEasKMVYayZjoDk5TGCbrdCcjgJC2f5SOA6xJWbXKtXqmCES3aZW8cHEH5S8=" + ], + "X-Amz-Request-Id": [ + "6ZQ9ANR5B8FYT3AJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "3511f793f5842563", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "T6u70PluaFKTa0mWTmC/M1VxGDIgmp2VQ7//dSHizQpDEeN43r9XZzDzm9eVwnNq7A6kpLbZ4vM=" + ], + "X-Amz-Request-Id": [ + "6ZQE4KQA959JDCRY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6699dec9d70fc717", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "m1K/6bFEONv/t2RdiRudwO/8ofCLb0D/F8v5MCvR5MVV5EFUWW3VK0kKuCnBeHYjrcUFS8TEWTk=" + ], + "X-Amz-Request-Id": [ + "6ZQ7SXBTECD1RHPD" + ] + }, + "Body": "" + } + }, + { + "ID": "1f9b0f1460bd3d00", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "pUk/mTPUpsfWQSUGsXw2CzEWaOucDsEjqW9Gbzo4PHdKUexEnjBWjcsBBB/n4UQW1tzkloGk/1A=" + ], + "X-Amz-Request-Id": [ + "6ZQ6WHS7060Q5W20" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7c18d49217608010", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%22bar%22baz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "v4cYTKU79zBM7HQUjkNMAg+0d0xzcY2BLDiLihsU4SuqRAg04CEXvOkxEdfmOBiHH0GcJDO2cF0=" + ], + "X-Amz-Request-Id": [ + "6ZQ2R5KYTRJQMKW4" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/repeatedbackslashes.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/repeatedbackslashes.replay new file mode 100644 index 000000000..0e48d5369 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/repeatedbackslashes.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQIIao31gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "2364d00700a7fbed", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "fHIS+c+wpLSNPWb6IUsZjBSeUAcbpjfoZPaSynxt4LhyZw97EFXCeJ8xdU0NmGdRUy5OnV21XcHZ4IyVcii9qw==" + ], + "X-Amz-Request-Id": [ + "5CTSD6YHN2F2GX59" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "516208981b164efa", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "BNGPClvJQo555uPnzRU/zJnO2BhmKPVi/G5r1G+MyUdiKC5P47V4AdESrFL9GJDkGeudVt/e+jm+n5RWzf7ykw==" + ], + "X-Amz-Request-Id": [ + "5CTYWMQ0SRMVA557" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "4fa0b6be7cc155e4", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "aDK0+l2qtElIbQXLVCU2obIB0KfTWrlEN0IKRFmWZOEwUAbzJmpX+IQWyv5nIhGHDi4gCNK+P5YZLJ9oS5HATw==" + ], + "X-Amz-Request-Id": [ + "5CTG02Z75HP6G3JD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "312ebf7a27bc9af2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "e+owxyjmkIflupyrqO45XF1VtkK9L/OTx3unqa8xOdPWeuA9Bi/tnyveIahvllWbCkhgsXvsvERoeXJZKHjixg==" + ], + "X-Amz-Request-Id": [ + "5CTYGH7M8TJ7QR2H" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "e2eb81e453b88cc7", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "GEPz7pXbD50XT5wFR/R25zgmEeL0yMhm64g219uclQEOp7dfOA/KlHooFZdByl46ceyUFKmui/RRkJ5kSwUq2Q==" + ], + "X-Amz-Request-Id": [ + "5CTKFXK4SKS5SEST" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjI5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "82041a64a0348c4d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "6rNQlTrQ6t+6X/fzony+0iCwsOBnYVbej5Pdgow1MDXrlQBv0Ewg1fF1pPr7aUexhZEghAeBjFHiqIrJAuBDTA==" + ], + "X-Amz-Request-Id": [ + "5CTKE8GT0AA564KS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "27f473a031110dc4", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "MaAFp0jP59sGo8LMbpmg0Tfm7KhXu/8CV7qSJyrd5j7D3ovWUV4IxmLsAVh1/usclbMqjQxjdM/aOiHsdJ+U5w==" + ], + "X-Amz-Request-Id": [ + "5CTTY96VJ2S6MTTA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6bb52999f0e82486", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "R9YtjKmR+cvwF3YUTDaM5QIkoCxKKUurS3ZS8PMFKXnROuzgxfMaRTyTn3Sor1JMwE6QUOH7CRi35vD9XSKTNQ==" + ], + "X-Amz-Request-Id": [ + "5CTNCFPFV7Z38M59" + ] + }, + "Body": "" + } + }, + { + "ID": "7f2910fddabd39b8", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "hphll9q04T0bZj5MVxKXU3c0Sgwbad6T8Ot+W1Qi105TAprzshdGWUBd2RxI1NtwTy+qrkBTrhN1OSvhnzJn7g==" + ], + "X-Amz-Request-Id": [ + "5CTQ0RP34H0GAFCB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "84ba18ea4cbbd3f8", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "IR93yKCts/SWwysfZe5sXBLXnZt6ssN8gq4tbrGAmFrFuw+u5wKrek5u64TL1COkC7djFTIl9r+HA6ZIs+bdSw==" + ], + "X-Amz-Request-Id": [ + "5CTN9Q1DT1HJ0WGG" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/repeatedfwdslashes.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/repeatedfwdslashes.replay new file mode 100644 index 000000000..4d51fab10 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/repeatedfwdslashes.replay @@ -0,0 +1,458 @@ +{ + "Initial": "AQAAAA7ffPQIExbtggAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "9ba525cd0b975bba", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "AoJRarlV+U9Wm4cqozFlEpSLOI04VsYTrn4LUx/y/Wtch2DB0Zmh/Qh1kmxEVkhK0n8tAtRMPVZw+AJg4yTeMg==" + ], + "X-Amz-Request-Id": [ + "5CTQJC4QEKDSTTN0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "cbc4b9ba51a93960", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "POEtgTx2qTQnqbXuqMQbb9AQ5AK62mkMXHs6MFMrDSKiit5rYGmvQl3pYm3I+i9iKT17rBnTcFhdkSu3OQeTuQ==" + ], + "X-Amz-Request-Id": [ + "5CTW1TWPPTYM4B56" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "64a66156569edc5d", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "dyBkh6kecAOSfLzedDvFOfIPUxpKwBWTaXOsKbLayIMQ9FJU08EqKg25IRzuhw/KX59mpp4+Jzq39PPjl7K2lA==" + ], + "X-Amz-Request-Id": [ + "5CTH28FSX7BKDFS0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "64ea7630fe3dc38e", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "mmJ9TLk6XEmrke6iRuMYyRdrpv9u09b2010MGSGGNM46jR38yWAgVxSEGdAR4G/uFfm5mfBaTMihTYGMeb//Fg==" + ], + "X-Amz-Request-Id": [ + "5CTM747P2Y3KH9CH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "cea9adf8c0e6f27f", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "iq8dKJUUH2ifkhRgJdCw9NMG2vD5mqhobq5HEsNwZWb/vWBeAMhy3kHYp244CmgAH9AkB9VElVDig32U3bHlvQ==" + ], + "X-Amz-Request-Id": [ + "5CTGZHKC9V574PA7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b014ada7266eb99d", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo//bar///baz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:29 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "PS63zxSDyWSB99TuUKaZ9OOyXUTc51picYDCXD9uyrTG/2WydfYMySoVrq6nCGnm4Tu2VPSN0dDdk+vCQe1qpw==" + ], + "X-Amz-Request-Id": [ + "5CTKXFAD44GJMVYY" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/spaces.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/spaces.replay new file mode 100644 index 000000000..426fafe35 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/spaces.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQJEbGD9QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "272b757cd2523e0e", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "IO050I0sM2nHOXQQuX4R8dOEVVGM9wZ06W0b4KS3dzsf3il4jq42BS3shmj2+mWbaweCxSkTYzg=" + ], + "X-Amz-Request-Id": [ + "6ZQF4QQ8HTGWD3BV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "3f5b15f1c0bcd1e5", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "7Dl2A4D3dFkfRaiVQ9ZG5yAW8/t5XZPrBGHiuUs6R9dBy1sJrfyjoYWihfEHcT9dRrKHFno2MpQ=" + ], + "X-Amz-Request-Id": [ + "6ZQEGFBYMCCQJ6Q0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "e5ce31618cb44f22", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "LV+bQrC9uDeFDwj2vJQx7J9b4TiBnWkylimYONZJ7t0nMfC2FpNEErBNF9Fs4hGMaRotSdFLfr4=" + ], + "X-Amz-Request-Id": [ + "6ZQ5NXCT7725QCGX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "18c95bd24f676e0e", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "oV7uMcKM/F3jOE4p7vk5uZ2pwBvd3K07pzNO/zOYl4Y59fHjhRO5Km5vwwSVJ2CHttIN9ms19h4=" + ], + "X-Amz-Request-Id": [ + "6ZQ3WVG3FVCSMBM3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "054ac005fc5df852", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keysfoo+bar+baz" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "ZifOgasW5Rl/dxuOo/w+MLpbNeC7tubPZel9hrSNBmt+MzANzXNspZNcWwxmgsieSP6HYfpubiU=" + ], + "X-Amz-Request-Id": [ + "6ZQ6NBMP6YFDQ3BJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjMwLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "c2b9e1ae28bd059f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "PKoDNsRMFJs6bdG/JnGQddaJAqkkmSUrLkO1dl3FzZjqZMDDDJjUDkQLa/em1nBgyrS0FUL8mpc=" + ], + "X-Amz-Request-Id": [ + "6ZQEX5BFXSDFAAXN" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "a3f0e4d90bc8cd3e", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "btma6kuSxlDzbZ1C31B6/r0HB0eJsHzdhVLnHwib20Ke0O7IWt81Q3T3B2etZQDixuJObrUzVRg=" + ], + "X-Amz-Request-Id": [ + "6ZQ911ZGCXNAMVD2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "27f9cc00c39d11b5", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rE+I2YkWw0X1CE1stR0FdB8olgdjV6/0cHrws2VSaHUtBmeF0Shx+iIpACbHP5KAg9Uzd6tN+48=" + ], + "X-Amz-Request-Id": [ + "6ZQ4NKM216F61N1Y" + ] + }, + "Body": "" + } + }, + { + "ID": "8c4ce78a6c34af6b", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "K9QoCkNhdx3xN8KVC5foYKr0QpM+THkZCPzKB4gOlPEP5gD3qskXBcbX/HSIG93QQvLkRGOasCo=" + ], + "X-Amz-Request-Id": [ + "6ZQ6MWM9E6M157WR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "8d3949eb837a6465", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keysfoo%20bar%20baz?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:30 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+KN+iII9RHrOFFh00nu2Ch2G59b9UDVxg0p52B47ouuem1W4RzB9CC5XC6Cayk8Snj7BzUUzQa0=" + ], + "X-Amz-Request-Id": [ + "6ZQCN2MWTH55YXTK" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/startwithdigit.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/startwithdigit.replay new file mode 100644 index 000000000..ce8d3cf9c --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/startwithdigit.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQLJMj2/wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "30241bcf99bc2e6f", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "RFetGteGP7WalEhFEp0miiv0/N6nlxxpbpJeEN0r5tvHvu99Uy6E+xlWGdUtFfycmiSitpJN+9A=" + ], + "X-Amz-Request-Id": [ + "5BM6FM8JV37NDB72" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "036bea2510f84a4f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "46L/IM0Dy9r6rH7hCQRTswmPWBQ7uxjIOB8hBToIfBWJhCx8dN53GO28yhcDQjhN3KZs8OtIDJI=" + ], + "X-Amz-Request-Id": [ + "5BM3RGF5H1M0R851" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "46bf10afef8498a9", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rMiDb2cROd8iTrmJspPN5U+FCasaLaLVTS0KT5X4ajoIaR65FEnuZu4kDzsPCAkJazKAuSqJTcM=" + ], + "X-Amz-Request-Id": [ + "5BM2X8PS91ZKMHGD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "8c55962429060891", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "DYCw8J/QIcrWkZXN95mIIq0uwU+yySMGfY4vaSGrCCiTMMl92QA/ExoUpC9e1FDwaBjkyrBAYIA=" + ], + "X-Amz-Request-Id": [ + "5BM5J2AAZEHMZ9CA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "3ea709f148ada6e5", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys12345" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "/Joti8pDBc2aRaJ75yRXskZOyqxlopcu6GwvnN3WKtj6+AJLMugG/++vYDNZF61WhNQXjUS+5go=" + ], + "X-Amz-Request-Id": [ + "5BM35QPNSJ54JM6G" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjMyLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "ef0b5347af0e448f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "PtdCGzFV5dWpbt8t4PB+i2LYBApbaQg51ClBOwWnsuJ8sDiNBzmCxdVzUxU88v65hPOefX+NauA=" + ], + "X-Amz-Request-Id": [ + "5BM9VMZ4FAPSDVT2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "50ecb763daf600bd", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "8aYwRSLt97OZZl4dY8k0WNF7awyjhx8uSY5gchmlzLO9IXzHpEoY/BC7xF8mOJDctOF+tQ7vTiA=" + ], + "X-Amz-Request-Id": [ + "5BM0MGGV8KGNNVWH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "4cde12c61979ffd2", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "vmmyPCiIEquTqyo6gHDA1NjjOyeIQ8LzrxrMZPCsr6Bcc4w4htpwAiRSqw/x8R6bwvDagQ8OcdA=" + ], + "X-Amz-Request-Id": [ + "5BM11X2FH74A4680" + ] + }, + "Body": "" + } + }, + { + "ID": "0d1621a7c62629d7", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "0vi+USNLKM2MqFoHKAiPxHTRrdbtO9YWo+04tpWmrxZZx0L8AHhbk7nq1c6NMrex42HXGsBTVA0=" + ], + "X-Amz-Request-Id": [ + "5BM338GBDS815SK2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ec6c6d98558b6084", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys12345?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "lVWkxnUzSQcv+1u5OfH3AVw5luCHE1N4Ei7+5mR9cbwPbiiCLAgLL47a+JAnoOvfEgdVRhdAbcM=" + ], + "X-Amz-Request-Id": [ + "5BMAY7WF82XRMJJ8" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/unicode.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/unicode.replay new file mode 100644 index 000000000..7d6a062b2 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestKeys/unicode.replay @@ -0,0 +1,726 @@ +{ + "Initial": "AQAAAA7ffPQLOzIbwwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "63d327293a64e655", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "UDKJJJxmBT/Eme55uTxdSPuxb4O3TybZlPA1qLyW3A8zJWqLd8nQf9W3Asi+59UXdtvbB/DnZ2c=" + ], + "X-Amz-Request-Id": [ + "RMN73X9ZS2HBKG4X" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "27819fe0839ed152", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "9tr4jGNcOjNTYITKsP7y9idFYcW9Wb4vpRwZKkYHsk5QddS/2dF7Ygw4vVrhJ/a5altZQRvF0gc=" + ], + "X-Amz-Request-Id": [ + "RMN8P1416MACMZJH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "bfbb6d01ae1da59d", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "4B2EW8Zw+m9OtYWDuaLwRnGFsEo8iaVl8423cl8DaNcIwZWGuCla0DxWGoiP+yUeHFhlbpcYiIc=" + ], + "X-Amz-Request-Id": [ + "RMNC37RPRYPQ2BKG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a0407cb427c4d1db", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "aK+BpwmOiK5mazAjyXpXt3UfCfFTr2vCgz37hViNSrk9GTEd/58DDzFiUfT6WIRSNilvO6yhphk=" + ], + "X-Amz-Request-Id": [ + "RMN9KS1KTHDR11G5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "5421e5505f7351eb", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy?x-id=CopyObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Copy-Source": [ + "go-cloud-testing-2%2Fweird-keys%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "263" + ], + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "aA8v3k8MxeOynaKCMiC2/rI1f/CjvIMluyU0vuBBwrVeojuVB/nEE+Q6wlKlE6QkGThopDFnql0=" + ], + "X-Amz-Request-Id": [ + "RMNDT53R03E7F6PT" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPENvcHlPYmplY3RSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM3OjMzLjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4iNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTIiPC9FVGFnPjxDaGVja3N1bUNSQzMyPk5oQ21oZz09PC9DaGVja3N1bUNSQzMyPjwvQ29weU9iamVjdFJlc3VsdD4=" + } + }, + { + "ID": "04001c17436ad9e1", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "O3uC0pZqTf6AGsP0wn4nyRYiZcy8NdUQhtqKkNjqEUOS3UKWuRKuEeVTeCVgbyEHTKrrmGhpy48=" + ], + "X-Amz-Request-Id": [ + "RMNBB85ARXZZA9D0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8=" + } + }, + { + "ID": "d200efcd392398b1", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "3mgfzx7Og/omrsUiu6nHpXh3MtdId5NJSThucWtVWXpPRDF2vf0WZQS6Ujihwc73yi9J2OoF3X4=" + ], + "X-Amz-Request-Id": [ + "RMN36T31Q026K6BT" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "f499aede72c3cca1", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA-copy?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "D68ba850aM9GyAZ3KKnk0EIBsTdShHxajJV4gilsDKuc59Ph6ChiGa1hJXF7i2/cvHE9VCCXYWU=" + ], + "X-Amz-Request-Id": [ + "RMN8PVGY84RM1N02" + ] + }, + "Body": "" + } + }, + { + "ID": "0b199d9528f00182", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "FD605wcwxSk62FWraIC+FBVhq8iaBbji5S4gMjCbXoFwtnVrF3aujtUX4TSU2dQDikRq+gBle7E=" + ], + "X-Amz-Request-Id": [ + "RMNEG65X2T8M8360" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ee3577c5bd757456", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/weird-keys%E2%98%BA%E2%98%BA%E2%98%BA?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "SuG5Fq9THcnxAysiN4xa4qtG/MTlt2q1ylQ582duJLPH6uWixjbRiNkTUGmOVCopML3wonE+04g=" + ], + "X-Amz-Request-Id": [ + "RMNCJWM6RF2N9HH3" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/PaginationConsistencyAfterDelete.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/PaginationConsistencyAfterDelete.replay new file mode 100644 index 000000000..21b222812 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/PaginationConsistencyAfterDelete.replay @@ -0,0 +1,425 @@ +{ + "Initial": "AQAAAA7ffPP6IhcqHAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "4aed8d2f46f7d6af", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "Cs1K8PeLJn9Pw8+X2rhcY4fZI6pEwWehtjJAwUeomoRMt2Um4LhzUE3tXup1u6FgRIxKHygQ6o0=" + ], + "X-Amz-Request-Id": [ + "S6ZMSH1FQBZX657S" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "db6ad4816858c432", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=2\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "ekeD/sJk1GTfdIjC/k8TEPU6wrcyWCxTPxysAz5CsBXAAlEJQmpYFFvbw6611avPd9sNXqMftmk=" + ], + "X-Amz-Request-Id": [ + "S6ZV4QR7MCK9CQ0E" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MjwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTE8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzFUMjA6MzY6NTQuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "71287867275f3827", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-1", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "vb5sWdlYfRndHX0yqxmGxJRwYHmEK30RdcY82C30dZIgEWPz5S6QGgws2/axpVHBDaJ6LwxrFwQ=" + ], + "X-Amz-Request-Id": [ + "S6ZSNCZ0S1MT5HKV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6a5eb192c3562620", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-1?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Q0717eVte1NY7YBsUQa86lbpiyvg4ZtoeAYXMkNIIvJpn4R5v1A1UmldFlVmfIEMtphHyAiEuPo=" + ], + "X-Amz-Request-Id": [ + "S6ZH65RAPW7Z3VYQ" + ] + }, + "Body": "" + } + }, + { + "ID": "fea57b24f515a263", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?marker=blob-for-list-1\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "gXwNGPECikYA4H2i14bTAERMFIYa3WB5A32EcN3I5LMyeX0bEzQscQDCiu8EiEooDtE0S0FgxzQ=" + ], + "X-Amz-Request-Id": [ + "S6ZMYGQEMCY9MVVW" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+YmxvYi1mb3ItbGlzdC0xPC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMjwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "2943d626d673943d", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-1?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "CFd5j9mUC6YRKRtSF9t6kvFM3j14BzU80F4+Cw3wbUANmDAdTdidk2hVdJm7cQlIwQJAGUhU740=" + ], + "X-Amz-Request-Id": [ + "S6ZTAX4W87GY1B4W" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/PaginationConsistencyAfterInsert.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/PaginationConsistencyAfterInsert.replay new file mode 100644 index 000000000..616ec9110 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/PaginationConsistencyAfterInsert.replay @@ -0,0 +1,425 @@ +{ + "Initial": "AQAAAA7ffPP6DwhGVgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "2e128b0e9132114c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "S+8qjUrc3ZUmcsfYt+7OZGU23ZYiGdXpD0cH5HxcEhcim4cCNByG2oup1g/y7Cm6LZf30Gmd96fMPgtQrUI1KA==" + ], + "X-Amz-Request-Id": [ + "S6ZHMVH2K9HY17RY" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "2314648728f5681a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=2\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "dZpc//BSi/Nl2qTsHiZeBx8ICDBP+GbxTmwB/lMVh3b7VcQjVBEmCTZ6b9GKUYhqAqmgXqFPhO/y41GzhVSuzA==" + ], + "X-Amz-Request-Id": [ + "S6ZH0CDG5RTKHA0J" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MjwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTE8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzFUMjA6MzY6NTQuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "67e9d35b2541d31b", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-0a?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "V4DXJ5hPaZtOkNNwJUtueKHbMlmkeRnN1u/c3Agg24lK1QKoINaqCvb3RutU1rFxyKtQaTF5ox5ic9iza9zalw==" + ], + "X-Amz-Request-Id": [ + "S6ZY4DE01NEQWKZA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c89ae41767862e5c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?marker=blob-for-list-1\u0026max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "R4NGLKeWjHahQl+L/IkAa2smBtKwzjAOQWbJp0Lp5FeGfzG5/g1WH6VTpOe8vuqu5pykUWAkAxzoUZALDwAxsA==" + ], + "X-Amz-Request-Id": [ + "S6ZPXSR1A92G85BD" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+YmxvYi1mb3ItbGlzdC0xPC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMjwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "e94dfea3a2807e77", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-0a", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "RdZc5SeQzY5fgXoshk+HQ+MWLxHqfI+KRWcsv6KtaE4LjqAYG3vYrTC0wFkesSb1hY+5Jhlr8H3ayGN6GFaO1g==" + ], + "X-Amz-Request-Id": [ + "S6ZTNYB6FFVHA45R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "57c3b5c199b5b3ba", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-list-0a?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9Zj+lSeAyR6I/2BA41gNCa0sZtb4l2NFeLk9MsejmklkjbU8f3lBy2IMnQXQlpdEV9/sgUyIACullDFBADb6+w==" + ], + "X-Amz-Request-Id": [ + "S6ZQKYKB6SPGRSFN" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/by_1.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/by_1.replay new file mode 100644 index 000000000..0fc92c423 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/by_1.replay @@ -0,0 +1,279 @@ +{ + "Initial": "AQAAAA7ffPP5I7X4LQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "63091337dd46933c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "JMW2e0mp4yLlQmnR2XbGwo0wOe4O/Zci/5YXv1Jb7cGQxCiBgOQYPBiGZ35CClLrDxQCcscw1Fs=" + ], + "X-Amz-Request-Id": [ + "8B8D1AT3MCHJ6Q53" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "7f435e3e0e39f981", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "/8byEb97hf/29bFZgTAYkSEuO8jzLvHrAMCZ2aIW7/YORa4+nmDRjlDsEpJ9cbJQZeh5sIUtLhs=" + ], + "X-Amz-Request-Id": [ + "8B8572RPR9KA5EBT" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "ed1f7e0cf194ad0a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?marker=blob-for-list-0\u0026max-keys=1\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "UpTjM3HOzYhg/fQ8c7oqn3CJRHAtRUVg4TY7zX/WujqfSDJsl0fTVv8Pf0U0W6aZKubfIlfL/Ww=" + ], + "X-Amz-Request-Id": [ + "8B81YVMW9JA5ZZNV" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+YmxvYi1mb3ItbGlzdC0wPC9NYXJrZXI+PE1heEtleXM+MTwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "c62e17a6925c796d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?marker=blob-for-list-1\u0026max-keys=1\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "jh34tJmt7IhG4lCw4Jc6wwgq5SmZlktfOXmgJGK2wH5qgKzjAum1tPRrLGsJcwRGjbGNjpAKbLE=" + ], + "X-Amz-Request-Id": [ + "8B892SRN62YTHA9Z" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+YmxvYi1mb3ItbGlzdC0xPC9NYXJrZXI+PE1heEtleXM+MTwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMjwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/by_2.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/by_2.replay new file mode 100644 index 000000000..8dbb48e1d --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/by_2.replay @@ -0,0 +1,221 @@ +{ + "Initial": "AQAAAA7ffPP5MyKTxAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "15f0dd8e48e419fc", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "CpdVXUztNJwFs3luZwMaCzDFBNbf+cc++qvAhYapTh1UC7iJWR/rdoqKey+jw+aibNubUE9hYN/0zvpBhk6AVA==" + ], + "X-Amz-Request-Id": [ + "8B828EHXV5ASJM7E" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "720139791235cec9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=2\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "NpZ6wnth4UMv+qOUwbEkR0MBw/Ke2o1I6WVxDjVDtnysgsPm8hL/TK6FfSskCfaGHQIoIjys7+rzYTm0JFIOkg==" + ], + "X-Amz-Request-Id": [ + "S6ZM6JHCNFNGWDGP" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MjwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+dHJ1ZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0wPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTE8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzFUMjA6MzY6NTQuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "c6f7aaff7acdf32f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?marker=blob-for-list-1\u0026max-keys=2\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "3s/sQGBnP+hFzIzbAzxxH3tcdyiVyE0T4ol4JMdXM23/PYZfQ5oCGYNfSRQzuV3PtWcmQO8Nh6YD1Yfi9tYDPw==" + ], + "X-Amz-Request-Id": [ + "S6ZVTDKJ9A8GZPNR" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+YmxvYi1mb3ItbGlzdC0xPC9NYXJrZXI+PE1heEtleXM+MjwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMjwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/by_3.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/by_3.replay new file mode 100644 index 000000000..9ed8285c6 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/by_3.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPP6A1oTowAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b18c869f6f150aaf", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "lvySrF4Xc2a10BgRWqU2biJVRtnZdl/5zaCo508Vm97Ah/t5al2abvlCCoz+65PqJ5W2BP+0Y20=" + ], + "X-Amz-Request-Id": [ + "S6ZT0P3KPACVA4GS" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "c4a90b81fdb841ef", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=3\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "TuEhftUIajF6AOmzujUiXml8ea/dRscHx+oLD3lzxZNYgmUoNcH7iSWhf7t0AC3qbxap9JCrTc4=" + ], + "X-Amz-Request-Id": [ + "S6ZVSTMPTMHZCQW2" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MzwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/exactly_1_object_due_to_prefix.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/exactly_1_object_due_to_prefix.replay new file mode 100644 index 000000000..f04653c88 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/exactly_1_object_due_to_prefix.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPP5C9b1iQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "96af3d4a19bcb787", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "M9+r1vyIAwPo4qzOi8WRd2BYkWJULwb55aaYvNPI1I1ZdZkhNYeC2mPhgdcGVcPh9pocyz5oG9Y=" + ], + "X-Amz-Request-Id": [ + "8B8FCGNYKHQPD5NK" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "73d70a03fb0240cb", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-list-1", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "hQZ8HpQopPf5e4s8UOHl1kmFbIfhetp24exCyaj2FBlHgS+PtdQQwtulLClRIB1mLRz56FCyQlk=" + ], + "X-Amz-Request-Id": [ + "8B8F79ANZ7AJG5GA" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdC0xPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/no_objects.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/no_objects.replay new file mode 100644 index 000000000..5c43a2585 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/no_objects.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPP5ABHqhQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "aecc3f99a3fb30d4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "DSsfgyhNE1yGI04a6UoVTZXsZF/F0wiQVkyd3Ou2YbTG7Yq5FNoMcmAiASxv99Kw/sYXW5T8vMY=" + ], + "X-Amz-Request-Id": [ + "8B84XBQ0SX6768V6" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "01661f83dcb0b85f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=no-objects-with-this-prefix", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "sv0res5f2lzFsX6Rajz+WVXcytcRPmuMn88mH/T9736TdNxY4d7wHz8TuCHSp3Ft6whNDfxYB90=" + ], + "X-Amz-Request-Id": [ + "8B85WY78W1BZNDZQ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bm8tb2JqZWN0cy13aXRoLXRoaXMtcHJlZml4PC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/no_pagination.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/no_pagination.replay new file mode 100644 index 000000000..01bd2724a --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestList/no_pagination.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPP5F03mkgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "31f93b0574e94ec5", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "AHGjO0nmdNg3FpJqMkiuaAulpcTMKMpKHRYAHiMNfsr8YwAas8kx/zHsXkSMWtX0vrZsRuiHiR8YldbJm03p5w==" + ], + "X-Amz-Request-Id": [ + "8B898H02XA0TZ88J" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "61573f68f292061f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-list", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:14 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "OjMdBYVhL8to0coqrjrNvvBdDttMiTYiQcaOAzMDdiSOSZD1oYxderl4/0PSdOoR4EdlbtxRpwulU/XYnhF7fw==" + ], + "X-Amz-Request-Id": [ + "8B86ZXJRP655A16D" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbGlzdDwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWxpc3QtMDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItbGlzdC0xPC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1saXN0LTI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListDelimiters/abc.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListDelimiters/abc.replay new file mode 100644 index 000000000..5155d16ca --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListDelimiters/abc.replay @@ -0,0 +1,831 @@ +{ + "Initial": "AQAAAA7ffPP8Bc9anwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "6d7678e1622fd046", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "0isModarKc0tFyHjqcW7E4FQBzfBZF7C0jxJHAuT7raCWJSj+632f72IKEA07xOHRUbhzpW9K6t5sqee0Oov9Q==" + ], + "X-Amz-Request-Id": [ + "6F60QGYS15C7PXFY" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48TWFya2VyPjwvTWFya2VyPjxNYXhLZXlzPjEwMDA8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNhLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjYi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTkuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2MudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNkLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjZS50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzFUMjA6MzY6NTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTkuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "02b12aa1b7601283", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "d32+lIhOzbdSRXoKEml/BJT6emAMd+fqAk1hTLSCTKDsYDU+b8/D985qC5d34F/ESYIggmgYGl9yTH2W3A1Uig==" + ], + "X-Amz-Request-Id": [ + "6F68VXEKN4PTGGDJ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48TWFya2VyPjwvTWFya2VyPjxNYXhLZXlzPjEwMDA8L01heEtleXM+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNhLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjYi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTkuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiY2MudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE5LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNkLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjZS50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzFUMjA6MzY6NTUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTkuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "f6950fa90e888c89", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "+R2W8+an4djtKV+YNDt450ScrAlBSD/ygx1cBEVIoo7oOxLofa6SNVxTPaX6GgZSP/AjueHU4dtpX2POskWa0Q==" + ], + "X-Amz-Request-Id": [ + "6F6B3GTT57WVZQM0" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48TWFya2VyPjwvTWFya2VyPjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj5hYmM8L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTkuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiYzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PENvbW1vblByZWZpeGVzPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "59e0042999177833", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abcdir1abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "6/qzngPOftz0UOQGueRePsR8PQK2cT/pzIYrD6Lvu7iM+gypYjQlrOqfa/PHVyvrqyuGgtDzo79OlbVH9++Jtw==" + ], + "X-Amz-Request-Id": [ + "6F6FB93FH631ZZ3P" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxEZWxpbWl0ZXI+YWJjPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNhLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjYi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTkuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiY3N1YmRpcmFiYzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "005ebf83f977d023", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abcdir1abcsubdirabc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "jNXy276BhQZjJ5DxCpkoab+D2T6syWg+8DZW/fYj99Uq8hDcROd8VBY7dmPzCS0xGTMMyV4MLYJ/u14fDj5qfw==" + ], + "X-Amz-Request-Id": [ + "6F68EF1BCG39T4JR" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxEZWxpbWl0ZXI+YWJjPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjFhYmNzdWJkaXJhYmNjLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIxYWJjc3ViZGlyYWJjZC50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTkuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "6f4c80d92ed272fe", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abcdir2abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "e/kwUmUxD0HwglrcN+vPZvRudwi1T1mK41V9l9kzzobR3wMQchJtAzBp4rJggN6TsDT+b3UEP5Pi31gUHHCo4A==" + ], + "X-Amz-Request-Id": [ + "6F697GVHMADT21XP" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmNkaXIyYWJjPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxEZWxpbWl0ZXI+YWJjPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLWFiY2RpcjJhYmNlLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNS0wMy0zMVQyMDozNjo1NS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PENoZWNrc3VtQWxnb3JpdGhtPkNSQzMyPC9DaGVja3N1bUFsZ29yaXRobT48Q2hlY2tzdW1UeXBlPkZVTExfT0JKRUNUPC9DaGVja3N1bVR5cGU+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "f7b254000cb966b3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026max-keys=1\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "+R5Vv01+srwWc7ooA9pEfNNbYz49m9/9ZpDh3hKgl3cqT4bnPS8Lv/D5d+dmZsm+ML2i6GtZTmBaoXr5TExklg==" + ], + "X-Amz-Request-Id": [ + "6F6204X8NSPZQKW6" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48TWFya2VyPjwvTWFya2VyPjxOZXh0TWFya2VyPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiYzwvTmV4dE1hcmtlcj48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+YWJjPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiYzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "39ac9470d3a7bd92", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026marker=blob-for-delimiters-abcdir1abc\u0026max-keys=1\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "MkX83ayFkN8QK6YIZ46cInaC3MrpcNdlDSGwjy5XMl+YwR0ZDimiy0Ni8baKy+DpEupO7epmiGjDYcAl3HBBVg==" + ], + "X-Amz-Request-Id": [ + "6F60YSMC7E253XHD" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48TWFya2VyPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiYzwvTWFya2VyPjxOZXh0TWFya2VyPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiYzwvTmV4dE1hcmtlcj48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+YWJjPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiYzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "9fbecce973c63f53", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026marker=blob-for-delimiters-abcdir2abc\u0026max-keys=1\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "WUYjYNZPh9Q1ueNqVuBH6u5D7mkK8dRzgtZVWbk9lTU50JK7s/iYZ/g4szBwag0b7k9gNYEq9UZdx3BeF3u2aA==" + ], + "X-Amz-Request-Id": [ + "6F60D5P4Z55GD6CH" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48TWFya2VyPmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMmFiYzwvTWFya2VyPjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj5hYmM8L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTkuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "88a4cbd7bff5db22", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-abcdir2abce.txt", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "nk2xJ+vlUKlHmvNmGH+W8M/BDlXgLGpolEE3ZlHYuJvK2AVLUcOo+5fIXTOZJJHSg/c62EJj9vkuMpE5FbunzA==" + ], + "X-Amz-Request-Id": [ + "6F618TZ3NXSR3AEF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c809c53713bf38e0", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-abcdir2abce.txt?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "saZEemsGQJe3XjDUTQCKRzDtYUqEWkebPI+8s6eF6ZzjpVSe57i56emEScjz7Dw90B4HjYgCyPV1f1ZJ6Hgt6A==" + ], + "X-Amz-Request-Id": [ + "6F65S51A1V4EAMQS" + ] + }, + "Body": "" + } + }, + { + "ID": "6ac6988c07db2b01", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=abc\u0026max-keys=1000\u0026prefix=blob-for-delimiters-abc", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "KAdG9Ep4b+yvmggYoYmOQH+1MFljH+Lkx308eCCofFd5oxa0eLBqkFZbEmzcnAJWx9xP8ZsZSxdw4BWzEvf1LQ==" + ], + "X-Amz-Request-Id": [ + "6F69PPKJR71KC6QY" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1hYmM8L1ByZWZpeD48TWFya2VyPjwvTWFya2VyPjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj5hYmM8L0RlbGltaXRlcj48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTkuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtYWJjZGlyMWFiYzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "8a282bd1f747b993", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-abcdir2abce.txt?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "wRsunl6Rgg4AVJKWmRkDnZ4V+ONUQJzBbSgpf0x3xxiskwrv5JdvH8Y/IeCbYPwcWya+vhjwYI628dLOhYif4A==" + ], + "X-Amz-Request-Id": [ + "6F645AC9XT6K7KHM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListDelimiters/backslash.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListDelimiters/backslash.replay new file mode 100644 index 000000000..dc919d45e --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListDelimiters/backslash.replay @@ -0,0 +1,831 @@ +{ + "Initial": "AQAAAA7ffPP7In+jbwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "31db27e21d68a7af", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "0BiIf6adHNJRub9qgLgb2xe51SpubWzgFi/ecwImxQP2wHPVfnUvVWqq5qDdReZv3Sh6HlYmtTfVC8Lw6TCvqw==" + ], + "X-Amz-Request-Id": [ + "CQCBYJPH8CSTS745" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxhLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxiLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxzdWJkaXJcYy50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjFcc3ViZGlyXGQudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjQxOjI3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIyXGUudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxmLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "9cac15db4798b41e", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "4+gihTgHoqaz83mDukeY0uI/tS29coYQxMWgRyu+MkkOWIMLOp1gp/3Q4ZlgEN8LNilPxQEz7oRSfovEHnE+hw==" + ], + "X-Amz-Request-Id": [ + "CQCES0XHAM0PYVBX" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxhLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxiLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxzdWJkaXJcYy50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjFcc3ViZGlyXGQudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjQxOjI3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIyXGUudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxmLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "ba07857be2b0ef35", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "uHr2+N05aH+FWGdU5d3vTnXYX2gmdO2RMnDOhV5/Uh5kdqlevXBu2CXZMCjMQT40rGrzTs2rgpkYoHSVIYvzxg==" + ], + "X-Amz-Request-Id": [ + "CQC16M18FY3B8MZ4" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxEZWxpbWl0ZXI+XDwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjFcPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIyXDwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "71b9bc40e8936fa8", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5Cdir1%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "90jZ0USdJLCtT3b84TU7D7Y+6nf8uIu1LERUzY/CX5t68TyHBL7nRXQgImOc6Kgk+k9bsYx3n2rthlU0rsTalw==" + ], + "X-Amz-Request-Id": [ + "CQCD5ZD5RW357E45" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVw8L1ByZWZpeD48TWFya2VyPjwvTWFya2VyPjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj5cPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXGEudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjQxOjI3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXGIudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjQxOjI3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXHN1YmRpclw8L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "40e5928869b18bb3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5Cdir1%5Csubdir%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "Kt6rJligcKYekQxYpmJLrjRrv/AdGDsQ0RGbeA/HnJkotneRAy6QL2XFmHRnTza7XGPAf5PraIN/x4JFhh19Hg==" + ], + "X-Amz-Request-Id": [ + "CQCF3M6J9A7SM7HE" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxzdWJkaXJcPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxEZWxpbWl0ZXI+XDwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMVxzdWJkaXJcYy50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjFcc3ViZGlyXGQudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjQxOjI3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "2e3615cf5231ee28", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5Cdir2%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "VUhMwYXiPRgcQkEr4KtMSrCUNqGmD8kU+xCEzl9oWt3V0+tnlWTceiv/2saHBiVd5aD3xNNrMIiqB0KMCe0Ebw==" + ], + "X-Amz-Request-Id": [ + "CQC5EWEEZVS67XEN" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cZGlyMlw8L1ByZWZpeD48TWFya2VyPjwvTWFya2VyPjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj5cPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIyXGUudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU1LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "403b8ebf9afe9574", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026max-keys=1\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "AUhezI0Oq7nPE7FrdSkG8NKzmFKiqGmuSDa7OhS1BHHCXDMfti6VqL/Ef1OxFm1naPW4ZdPSvuUVjqlylAU9+w==" + ], + "X-Amz-Request-Id": [ + "CQCDKHJYXFYVA51W" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TmV4dE1hcmtlcj5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXDwvTmV4dE1hcmtlcj48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+XDwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXDwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "ffd9260cde48eae0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026marker=blob-for-delimiters-%5Cdir1%5C\u0026max-keys=1\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "XI4oAEPBcawmvZLF9egB+MBWah3liaXwkfgwS7xpJlQ8+VDb0MihGa0cMexcR5+BPNEHg6/AQ9RD89xyhXqiBw==" + ], + "X-Amz-Request-Id": [ + "CQCBSQQ6GQ9W7SHW" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIxXDwvTWFya2VyPjxOZXh0TWFya2VyPmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjJcPC9OZXh0TWFya2VyPjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj5cPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjJcPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "69ebddfb4eb725a0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026marker=blob-for-delimiters-%5Cdir2%5C\u0026max-keys=1\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "9kmET4jKp/f8pTEYyEDdK1jcenL7KJATfCprZuTP6voOwnY/kkOF1Ckrz/bovr1CJYLs3nQ4IXF3M85GFOWd1g==" + ], + "X-Amz-Request-Id": [ + "CQC3G06BBTYMPG8K" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kZWxpbWl0ZXJzLVxkaXIyXDwvTWFya2VyPjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj5cPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLVxmLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjo0MToyNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "5a291f64ecf650f9", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-%5Cdir2%5Ce.txt", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:55 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "s7aq42mg9HZyGgDmouLhPzj5GvZPtCyY79+m0prn4ShU14lidcE6oOh8OmG9+rxOw5Y6u1oaLdTv0eyiXiKUaw==" + ], + "X-Amz-Request-Id": [ + "CQC59SDR9NHQNN70" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "ce11fb56f721faa4", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-%5Cdir2%5Ce.txt?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "bKQWwUWNyvr/+TFpoRUaxKp04BvMw2cR8OpE/QpwopYve1AgdEKdsbA6cyZMg7mukahGtf4cSF9bZg17MHu6sw==" + ], + "X-Amz-Request-Id": [ + "CQC9PK5PNWNS78WW" + ] + }, + "Body": "" + } + }, + { + "ID": "7a44930e7fc11419", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%5C\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%5C", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "L++GXw91KznqMeVFlO2tAzESJor+OO2LJP3apC+QPrKKu76A2IrESkqxpyCjWcK090buxmNNgpLEzUI5qi9CeA==" + ], + "X-Amz-Request-Id": [ + "6F6D0WPB1QVWNY2F" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy1cPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxEZWxpbWl0ZXI+XDwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy1cZi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6NDE6MjcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtXGRpcjFcPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "7ceac1eaec2e58e8", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-%5Cdir2%5Ce.txt?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "+9CKh2AP3QowBhbpF/is7Nc+i5dLo4wGCrGiIw2emU6+UZgdAn7vy+cOHUWrLlCfPmk0Qq+wEkY4foThhZi4uQ==" + ], + "X-Amz-Request-Id": [ + "6F63K6HV9YJREEE1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListDelimiters/fwdslash.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListDelimiters/fwdslash.replay new file mode 100644 index 000000000..5f3cf0283 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListDelimiters/fwdslash.replay @@ -0,0 +1,831 @@ +{ + "Initial": "AQAAAA7ffPP7AO6D7gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "0700e5be6294a125", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "bjo6IS7P3U7ey37sLl7Bwd9+Z8Toq0tfYtq5hVIjg3cLr2B2q0+zhqdpkBACJNQkNVxq/2xzweI=" + ], + "X-Amz-Request-Id": [ + "CQC6KBP250VBJFYB" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9hLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9iLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvYy50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvc3ViZGlyL2QudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyL2UudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9mLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "e185723bc94ffbd9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "PEbqZhBG5yYRpXNv9yF0nPujQYWYDmK/WBCbRS6403K90kE2jfstq/8DH3kJVQBiS8DdyE8MtIc=" + ], + "X-Amz-Request-Id": [ + "CQC776ZGYSYNV2S3" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9hLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9iLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvYy50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvc3ViZGlyL2QudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyL2UudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9mLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "99f62f4b84038e17", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "GJeK1KbNTKGIljfo9uv6JpOAAFg3kyRjwCuXbPeuyMJgNTm14jX1DvtHHsNwdAtEYJII5PJslfk=" + ], + "X-Amz-Request-Id": [ + "CQCE7KGRGCGNJA92" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "62727163f14e25e5", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2Fdir1%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "9DLvUMneIsa46g0Pu62fCt5BvSUxaH1I68lenfTq/TC7G82aUgHgY17WdCegn6SM54QtqT0Z2TE=" + ], + "X-Amz-Request-Id": [ + "CQCE60JSCCDH9SRG" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS88L1ByZWZpeD48TWFya2VyPjwvTWFya2VyPjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2EudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL2IudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxL3N1YmRpci88L1ByZWZpeD48L0NvbW1vblByZWZpeGVzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "23d3e8ee8a63d2f3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2Fdir1%2Fsubdir%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "JjLh8wVZQ3MQOcH/P5mcrw2xN8PhRkHN0GtkMUVWczhQrE0CnQPKXwx3T6KQbqkp++jQpoqgpDk=" + ], + "X-Amz-Request-Id": [ + "CQCAXEE9VQMYHRWA" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMS9zdWJkaXIvYy50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvc3ViZGlyL2QudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "78c7c406c4ea0f88", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2Fdir2%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "5b0FjYLwn0yjR2GRkHE+qeBYPJqHTMJpvT4CZVo9fsLcpAr35oD6IwFBZ54NCzQzZzsg+cN6eHI=" + ], + "X-Amz-Request-Id": [ + "CQC7C5ZZTTXSYA86" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vZGlyMi88L1ByZWZpeD48TWFya2VyPjwvTWFya2VyPjxNYXhLZXlzPjEwMDA8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyL2UudHh0PC9LZXk+PExhc3RNb2RpZmllZD4yMDI1LTAzLTMxVDIwOjM2OjU0LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48Q2hlY2tzdW1BbGdvcml0aG0+Q1JDMzI8L0NoZWNrc3VtQWxnb3JpdGhtPjxDaGVja3N1bVR5cGU+RlVMTF9PQkpFQ1Q8L0NoZWNrc3VtVHlwZT48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "9baab1aecba86090", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=1\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "qPh/eooicWvv2zp6R860Qe7HliLVdIk4norlB9DkovRzw4CP4eyxrO/dxFSpFhv9+gqTDU4jeQ8=" + ], + "X-Amz-Request-Id": [ + "CQCAAMNEW2AYSAAP" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TmV4dE1hcmtlcj5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLzwvTmV4dE1hcmtlcj48TWF4S2V5cz4xPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29tbW9uUHJlZml4ZXM+PFByZWZpeD5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLzwvUHJlZml4PjwvQ29tbW9uUHJlZml4ZXM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "f1b7d959033fc553", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-delimiters-%2Fdir1%2F\u0026max-keys=1\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "1XP1qHK8Qj1Xf4Tfktzn0IY9turuyT60YN7fSEBz3G5AhBOz48v70owvaBGd2vIOpVU98zBcyKs=" + ], + "X-Amz-Request-Id": [ + "CQC2WD0KSGZ2G4QX" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIxLzwvTWFya2VyPjxOZXh0TWFya2VyPmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjIvPC9OZXh0TWFya2VyPjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPnRydWU8L0lzVHJ1bmNhdGVkPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjIvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "0e474be362cb4f19", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026marker=blob-for-delimiters-%2Fdir2%2F\u0026max-keys=1\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "9qHy5BDFLo6qucEfN2t1Ng8FKCjcXemekjFkgHDVu/EoMn7uuJj9K5TEKclvUcd5NHYhmuEZWzs=" + ], + "X-Amz-Request-Id": [ + "CQCET4D4H4JG62QK" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PE1hcmtlcj5ibG9iLWZvci1kZWxpbWl0ZXJzLS9kaXIyLzwvTWFya2VyPjxNYXhLZXlzPjE8L01heEtleXM+PERlbGltaXRlcj4vPC9EZWxpbWl0ZXI+PElzVHJ1bmNhdGVkPmZhbHNlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1kZWxpbWl0ZXJzLS9mLnR4dDwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PC9MaXN0QnVja2V0UmVzdWx0Pg==" + } + }, + { + "ID": "aa255ee3a3bb5968", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-/dir2/e.txt", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:36:54 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "VZFTTG0zv/QqyuDKUKNkC1KIDsJL55Ts8osftz7iL/s1fJIHC4wah++H90R1k/mAGjonNS0GFk4=" + ], + "X-Amz-Request-Id": [ + "CQCDGW9QG0XYN63P" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c7634d71be31fe3e", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-/dir2/e.txt?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "HXOHxoYBVRlJHIe/XhMTIpXxwyKb9ysKkSgmE3l/i+T8CBbjpE5eI7Sm6jDBMrnIbXkg2ef2Sjc=" + ], + "X-Amz-Request-Id": [ + "CQC984FF5ZXKG3C5" + ] + }, + "Body": "" + } + }, + { + "ID": "3b12ae537ab0e75a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?delimiter=%2F\u0026max-keys=1000\u0026prefix=blob-for-delimiters-%2F", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "z4eaCn60Mm2jWCSHJseN9kC3o+ZYUONp26MNMxNzGY/MjzHgLTDxtT8L3RHEQUv5+8kfMD7Cea0=" + ], + "X-Amz-Request-Id": [ + "CQC723QPX9F2XH8J" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItZGVsaW1pdGVycy0vPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxEZWxpbWl0ZXI+LzwvRGVsaW1pdGVyPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+YmxvYi1mb3ItZGVsaW1pdGVycy0vZi50eHQ8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTguMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb21tb25QcmVmaXhlcz48UHJlZml4PmJsb2ItZm9yLWRlbGltaXRlcnMtL2RpcjEvPC9QcmVmaXg+PC9Db21tb25QcmVmaXhlcz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + }, + { + "ID": "1c297f03d7d38a72", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-delimiters-/dir2/e.txt?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:16 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "jRaUJ2k5Bz3lRS+WATHP+7Pb4nmu6NssutdTj5RgEdKGVLuhD58T3utdvqrM5ga2A4pQSDXPJCg=" + ], + "X-Amz-Request-Id": [ + "CQC4ZSKQ2Q612TB5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListWeirdKeys.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListWeirdKeys.replay new file mode 100644 index 000000000..5fb33ba12 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestListWeirdKeys.replay @@ -0,0 +1,163 @@ +{ + "Initial": "AQAAAA7ffPP6MOnd8gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "ad687dfc87a6610c", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=list-weirdkeys-", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "Qp2QVNNAa6vDCv0uGrvmzbi7haMIDVmqISNZB6uqwwIMfQamH0rsWkx+1bmkjBpShPN6hrxisVA=" + ], + "X-Amz-Request-Id": [ + "S6ZNB2D0RTBYNXXQ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bGlzdC13ZWlyZGtleXMtPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtICEmcXVvdDsjJCUmYW1wOyZhcG9zOygpKissLS4vPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy0uLl9fMHgyZl9fZm9vLy4uX18weDJmX19iYXIvLi5fXzB4MmZfXy4uX18weDJmX19iYXouLl9fMHgyZl9fPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy0uLl9fMHg1Y19fZm9vX18weDVjX18uLl9fMHg1Y19fYmFyX18weDVjX18uLl9fMHg1Y19fLi5fXzB4NWNfX2Jhei4uX18weDVjX188L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLS4uX18weDVjX19mb29fXzB4NWNfX19fMHg1Y19fYmFyX18weDVjX19fXzB4NWNfX19fMHg1Y19fYmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy0xMjM0NTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtOjsmbHQ7PSZndDs/PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1APC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1bX18weDVjX19dXl88L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLV9fMHgwX19fXzB4MV9fX18weDJfX19fMHgzX19fXzB4NF9fX18weDVfX19fMHg2X19fXzB4N19fX18weDhfX19fMHg5X19fXzB4YV9fX18weGJfX19fMHhjX19fXzB4ZF9fX18weGVfX19fMHhmX188L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLV9fMHgxMF9fX18weDExX19fXzB4MTJfX19fMHgxM19fX18weDE0X19fXzB4MTVfX19fMHgxNl9fX18weDE3X19fXzB4MThfX19fMHgxOV9fX18weDFhX19fXzB4MWJfX19fMHgxY19fX18weDFkX19fXzB4MWVfX19fMHgxZl9fPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1gPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1mb28gYmFyIGJhejwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtZm9vJnF1b3Q7YmFyJnF1b3Q7YmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1mb28vL2Jhci8vL2JhejwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozOTowMS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtZm9vL2Jhci9iYXo8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6NDAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLWZvb19fMHg1Y19fYmFyX18weDVjX19iYXo8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLXt8fX5/PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy3imLrimLrimLo8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "8e14e55d74c38b18", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=list-weirdkeys-", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:15 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "3ZHyp2a/yUYf22/gdNREqeu37J+q82sJRiNaFXZzTlLC+wiioTP1Syoor7kO8M539yAXUMW9nZM=" + ], + "X-Amz-Request-Id": [ + "S6ZG9EMJJ2B1F2YJ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+bGlzdC13ZWlyZGtleXMtPC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xMDAwPC9NYXhLZXlzPjxJc1RydW5jYXRlZD5mYWxzZTwvSXNUcnVuY2F0ZWQ+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtICEmcXVvdDsjJCUmYW1wOyZhcG9zOygpKissLS4vPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy0uLl9fMHgyZl9fZm9vLy4uX18weDJmX19iYXIvLi5fXzB4MmZfXy4uX18weDJmX19iYXouLl9fMHgyZl9fPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy0uLl9fMHg1Y19fZm9vX18weDVjX18uLl9fMHg1Y19fYmFyX18weDVjX18uLl9fMHg1Y19fLi5fXzB4NWNfX2Jhei4uX18weDVjX188L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLS4uX18weDVjX19mb29fXzB4NWNfX19fMHg1Y19fYmFyX18weDVjX19fXzB4NWNfX19fMHg1Y19fYmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy0xMjM0NTwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxOC4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtOjsmbHQ7PSZndDs/PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1APC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1bX18weDVjX19dXl88L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLV9fMHgwX19fXzB4MV9fX18weDJfX19fMHgzX19fXzB4NF9fX18weDVfX19fMHg2X19fXzB4N19fX18weDhfX19fMHg5X19fXzB4YV9fX18weGJfX19fMHhjX19fXzB4ZF9fX18weGVfX19fMHhmX188L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLV9fMHgxMF9fX18weDExX19fXzB4MTJfX19fMHgxM19fX18weDE0X19fXzB4MTVfX19fMHgxNl9fX18weDE3X19fXzB4MThfX19fMHgxOV9fX18weDFhX19fXzB4MWJfX19fMHgxY19fX18weDFkX19fXzB4MWVfX19fMHgxZl9fPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE4LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1gPC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1mb28gYmFyIGJhejwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozODoxNy4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtZm9vJnF1b3Q7YmFyJnF1b3Q7YmF6PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy1mb28vL2Jhci8vL2JhejwvS2V5PjxMYXN0TW9kaWZpZWQ+MjAyNC0wOC0yMFQyMjozOTowMS4wMDBaPC9MYXN0TW9kaWZpZWQ+PEVUYWc+JnF1b3Q7NWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTImcXVvdDs8L0VUYWc+PFNpemU+NTwvU2l6ZT48T3duZXI+PElEPmY0Mzc1YjU5YzBjZmY0OGI4ZWQ5OTAwMjJlOWYyNjY2YTQ1M2Q5NTlmMTNkNzcyYWY0YzE2MWNlOWUwNjRhMmI8L0lEPjxEaXNwbGF5TmFtZT5hbWF6b248L0Rpc3BsYXlOYW1lPjwvT3duZXI+PFN0b3JhZ2VDbGFzcz5TVEFOREFSRDwvU3RvcmFnZUNsYXNzPjwvQ29udGVudHM+PENvbnRlbnRzPjxLZXk+bGlzdC13ZWlyZGtleXMtZm9vL2Jhci9iYXo8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6NDAuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLWZvb19fMHg1Y19fYmFyX18weDVjX19iYXo8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5Pmxpc3Qtd2VpcmRrZXlzLXt8fX5/PC9LZXk+PExhc3RNb2RpZmllZD4yMDI0LTA4LTIwVDIyOjM4OjE3LjAwMFo8L0xhc3RNb2RpZmllZD48RVRhZz4mcXVvdDs1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MiZxdW90OzwvRVRhZz48U2l6ZT41PC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48Q29udGVudHM+PEtleT5saXN0LXdlaXJka2V5cy3imLrimLrimLo8L0tleT48TGFzdE1vZGlmaWVkPjIwMjQtMDgtMjBUMjI6Mzg6MTcuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMD5.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMD5.replay new file mode 100644 index 000000000..9c03fe407 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMD5.replay @@ -0,0 +1,653 @@ +{ + "Initial": "AQAAAA7ffPQFBJ0UFAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "18d30f653854f641", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-aaa?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "hlNiIPEPdOe1NrjXHMdKxEWGM3TUjxmRneL+t4r+usfrsPhOG52I8v3FsmLJqiJgJUIbj8sL0OxzjasK/61Lew==" + ], + "X-Amz-Request-Id": [ + "DTAYKYVSKYBZXTTY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "2b8dbdffd570f12a", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-bbb?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "48" + ], + "Content-Md5": [ + "afqrYmg1ApVVDefVh7wyPQ==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "7" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Nw0KZ29vZGJ5ZQ0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6RFkvWWRBPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"69faab6268350295550de7d587bc323d\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DY/YdA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "3VaRjflu4OTo+XyFUEzZzorohG6SQxyxFdWbofTgeHPa1EiAv0+FBKmpaOeOLln+zQG9L+/+xBeAgZqgTEjIcg==" + ], + "X-Amz-Request-Id": [ + "DTAZ9PDNFWK4KMMW" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "618591fc9707097b", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-aaa", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "woTO03ezRQvNSeT9Sd1gctOl6WOA6p/tf8m3sAkXaasVAS43d+TAw3E3nl1LkG2mOGRIyWADkh5PNU/hcql7iw==" + ], + "X-Amz-Request-Id": [ + "DTAH70ZQ4JXGVDVV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "8e3493d4d2f06299", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-bbb", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "7" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"69faab6268350295550de7d587bc323d\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rSLvnxCFWceNWnekk4un7JFHMP8+NtnP2w7akrIfC+EZLvf6qpS0BF7s/Fim/XEIlJOuNnq1E0HUN1UMz4lIfA==" + ], + "X-Amz-Request-Id": [ + "DTAJ32APHR1YVWRE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "54337509250d0d9d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1000\u0026prefix=blob-for-md5-", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "3sgUYUzux/hyVpouN90XjlxK4Z6CWyYsOs4IY5z3KULJV/YhHocTNYOlmmAFWGCitX0SdLcGiJkLYuqE6fPPkQ==" + ], + "X-Amz-Request-Id": [ + "DTAR1PE1AQFFNAKW" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+YmxvYi1mb3ItbWQ1LTwvUHJlZml4PjxNYXJrZXI+PC9NYXJrZXI+PE1heEtleXM+MTAwMDwvTWF4S2V5cz48SXNUcnVuY2F0ZWQ+ZmFsc2U8L0lzVHJ1bmNhdGVkPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLW1kNS1hYWE8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzFUMjA6Mzc6MjYuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzVkNDE0MDJhYmM0YjJhNzZiOTcxOWQ5MTEwMTdjNTkyJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjU8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjxDb250ZW50cz48S2V5PmJsb2ItZm9yLW1kNS1iYmI8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzFUMjA6Mzc6MjYuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90OzY5ZmFhYjYyNjgzNTAyOTU1NTBkZTdkNTg3YmMzMjNkJnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjc8L1NpemU+PE93bmVyPjxJRD5mNDM3NWI1OWMwY2ZmNDhiOGVkOTkwMDIyZTlmMjY2NmE0NTNkOTU5ZjEzZDc3MmFmNGMxNjFjZTllMDY0YTJiPC9JRD48RGlzcGxheU5hbWU+YW1hem9uPC9EaXNwbGF5TmFtZT48L093bmVyPjxTdG9yYWdlQ2xhc3M+U1RBTkRBUkQ8L1N0b3JhZ2VDbGFzcz48L0NvbnRlbnRzPjwvTGlzdEJ1Y2tldFJlc3VsdD4=" + } + }, + { + "ID": "4cec53d23e4ff61c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-bbb", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "7" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"69faab6268350295550de7d587bc323d\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "95j1d7iasfh3NCZQKJWn+5wDPFeOl77it+yF2CpS78pDiceBDN9O2EkAr0XdDYCw5EmuzhxTFPYBbFpmjiop0g==" + ], + "X-Amz-Request-Id": [ + "DTAZXE3NGGBMAC6D" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7cb40e6dcfc0cefc", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-bbb?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "qOwkOZ5s0clQwlzS6NG87AJ1/ZCS9W5XWEkz2spPbJg/9QSyDcm0fi+8E/m8IXFXYouPYIm01PmD1Croi5nODw==" + ], + "X-Amz-Request-Id": [ + "DTANY5MWNJ11742D" + ] + }, + "Body": "" + } + }, + { + "ID": "1f39a5beb3c2e075", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-aaa", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "sF3yETd66SqCITfjZveDq+jtKEq7C0jWVxlQ2J6lCWp4KatYzwt4FhMAN+jVysQ+sDaOMNn6/hkQ/ecrW88kUQ==" + ], + "X-Amz-Request-Id": [ + "DTATWFETWFYRRKSE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "d07ff09d89330d63", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-md5-aaa?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "yd0z399pckqtmZ6Bn8MvZIdSGNAlcE6SVoY25/SreizvHUMb1VSZSJxCIUvrstSpCsJdA3RRsnHsv+8vEYL6Ag==" + ], + "X-Amz-Request-Id": [ + "DTASXHVH6QNG1TQM" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/duplicate_case-insensitive_key_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/duplicate_case-insensitive_key_fails.replay new file mode 100644 index 000000000..5e96564a2 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/duplicate_case-insensitive_key_fails.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPQEFDDuCwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/empty.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/empty.replay new file mode 100644 index 000000000..1aa34daa2 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/empty.replay @@ -0,0 +1,321 @@ +{ + "Initial": "AQAAAA7ffPQECXnXowAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "eeeafcc2f885a02e", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "TqppMFmqO8MjNz8OvaP1+dwa5pfRhJhnoShszFtbxQFQsMWgRLqx4Ven1uer/yBSn/YUtFAGqjU=" + ], + "X-Amz-Request-Id": [ + "6PMCZKWSWN26RDRQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "20e929ab504036b9", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "dd1UE0uayD0NwMfg5T/BUf75bQm+8ypZi9sETThBKBdiVbnl/9RkLiGgwqse0JkRG9cHvbZkGBw=" + ], + "X-Amz-Request-Id": [ + "6PM8AFYXZ70ZN9T2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "97e304362d161043", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "KrEx1HiLZa/EQWHIJpl5G4hyhPb3+Kd357/pNd7dgUZppUsE6GKK8IGhG/WIHDaj5GbZ+DznkRY=" + ], + "X-Amz-Request-Id": [ + "6PM3H53WKVB0EA10" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "639bfb5a12eed27e", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rF1CmoNKvm2iegtyl7cZs2lA3PBBslTfH9IRP8Z/fV9xhdmod/7fRsSTCZyBG1WC+6ulTcTKyME=" + ], + "X-Amz-Request-Id": [ + "6PM3Q998JZFHVWVC" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/empty_key_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/empty_key_fails.replay new file mode 100644 index 000000000..5b332a114 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/empty_key_fails.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPQEFCVVVQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/non-utf8_metadata_key.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/non-utf8_metadata_key.replay new file mode 100644 index 000000000..430560ba1 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/non-utf8_metadata_key.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPQFBIWBoQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/non-utf8_metadata_value.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/non-utf8_metadata_value.replay new file mode 100644 index 000000000..575ec1ccf --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/non-utf8_metadata_value.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPQFBJRL4AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/valid_metadata.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/valid_metadata.replay new file mode 100644 index 000000000..beb4f6946 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/valid_metadata.replay @@ -0,0 +1,348 @@ +{ + "Initial": "AQAAAA7ffPQEFDmS+AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "6dafac6b1ec94a06", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Meta-Key_a": [ + "value-a" + ], + "X-Amz-Meta-Key_b": [ + "value-b" + ], + "X-Amz-Meta-Key_c": [ + "vAlUe-c" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "/801EOf2l0OWw/QsybcHUnNXwz8U4cdsAMjEW0NHH+RpZ0BnClUMd2EYm262iri4qJLNtOgxFMk=" + ], + "X-Amz-Request-Id": [ + "6PM8J2YGRK2QP3QB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "d7040e121e3b47bf", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "SRhsE0vZe4V9THI2gLRzkD/SbPePq8UXOaKbH0ii8sbxbn4LU1TaJteqYRxFSKSHlcaQi2Jybk0=" + ], + "X-Amz-Meta-Key_a": [ + "value-a" + ], + "X-Amz-Meta-Key_b": [ + "value-b" + ], + "X-Amz-Meta-Key_c": [ + "vAlUe-c" + ], + "X-Amz-Request-Id": [ + "6PMAXQJ4NPBTH2WS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c4dbec7143145cce", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "7ewcSm+Kl+9qZ/vbAKdlvfg9cAHiloh9+bJK5b8UZPtkyrqLewDQfxqF/oAz3keSaudunSFgMdQ=" + ], + "X-Amz-Meta-Key_a": [ + "value-a" + ], + "X-Amz-Meta-Key_b": [ + "value-b" + ], + "X-Amz-Meta-Key_c": [ + "vAlUe-c" + ], + "X-Amz-Request-Id": [ + "6PM70CVT5P0XVWM3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1119e52de5c3d905", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "mJgaqBV8UbY77NUvmhdQlVU95riP5AgDA1Q0Ey4X1PE9jxqTW+WHBkqfhckQH2Vv6IuI/QxeP+8=" + ], + "X-Amz-Request-Id": [ + "6PM8QS4WHNNAPPBF" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/valid_metadata_with_content_type.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/valid_metadata_with_content_type.replay new file mode 100644 index 000000000..846f8560c --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/valid_metadata_with_content_type.replay @@ -0,0 +1,330 @@ +{ + "Initial": "AQAAAA7ffPQEKeIkIgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "4777645632ee21a8", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Iz8Pdcln8X7taEGDegv6xBHJeNXXXIxVoB4n+A0WSyWO5ZQgp2vpOYZ22+zhPVrgdJt0iWzZmEw=" + ], + "X-Amz-Request-Id": [ + "6PM4946JT9RS3JJR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "e9ecce9d69d8a752", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9VG9j6cHjm4Tt3lm0ADKeJk09N7jaNGMV2uKs9m+Uabe91J9FUyK4U4fWz9Rx0qa9/hUtTbLu+0=" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "6PM3A6DDZHQS9M6T" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "75399a4f73ee4d54", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "albpCKqwMBDC41DR3NqnwswjspQE3KJKyYR+upSXRTJuUqjsrXAPSuNS9pSHxWXIwr9QobrQJ3A=" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "6PMF8MW063TEMWM8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "cb3c21b3ea35b13d", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "bM3IuIn9csxkPqnVft6JDycWYOr4mivfaXST9HQWTl8tAu3EWjomL3CW9s0JutQJrujWUVIJ064=" + ], + "X-Amz-Request-Id": [ + "6PM9PJ03EBHBTVRQ" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/valid_metadata_with_empty_body.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/valid_metadata_with_empty_body.replay new file mode 100644 index 000000000..97216b8e5 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/valid_metadata_with_empty_body.replay @@ -0,0 +1,330 @@ +{ + "Initial": "AQAAAA7ffPQEHz3hTQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "3e09d0388e576941", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "zSFFfDgphWyzOXNwoHnsrGEaN1LfIXomy2zFJTr3tCEKQSP5Fg9d/GasaTEJ83qwnuNpei9Y765pa3N3bGuep43Qj50o7iTzXpGJejMqu4Y=" + ], + "X-Amz-Request-Id": [ + "6PM9V2KDYT8E4XNP" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "760a044dddf430d3", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "moBthgcLwCLBS5Y0EkpC4VCumoWr+lZMbANacYOIQSRPwBqJ1kW8zXh0QMsZOEG4oMPTqr52x177E8Hl1X8lPidJxbevDw57cXgo6AxmGOE=" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "6PM42CDNQTEG77B5" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "5993bd02143eac3e", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "zj3adnTHg40Fy83rBnYnPeyqirxzPHQfcPY0E0RMcpWau5Uk5SW2Qt9S89jN/DJiOHoxTBlqcjYvbvo29rboLnmP/nez00rOvySz4jf2bbw=" + ], + "X-Amz-Meta-Foo": [ + "bar" + ], + "X-Amz-Request-Id": [ + "6PM98DR8D571F0GE" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7666ec53a07c6a0b", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "8OItkvNpa96weYlAUnpschriwmBd1qOMfeDanGBWbJhxpt6czVbwX4NNFxdpi357fY4mT0eYOntNUTei9JHTLDIhw+BiYb4o0nXOYZ5Xe2g=" + ], + "X-Amz-Request-Id": [ + "6PM90PJC2V8HKW9H" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/weird_metadata_keys.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/weird_metadata_keys.replay new file mode 100644 index 000000000..9832fd8b1 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestMetadata/weird_metadata_keys.replay @@ -0,0 +1,483 @@ +{ + "Initial": "AQAAAA7ffPQENObc8wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "dd439968915a1d0a", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "46" + ], + "Content-Md5": [ + "XUFAKrxLKna5cZ2REBfFkg==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "5" + ], + "X-Amz-Meta-%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f": [ + "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F" + ], + "X-Amz-Meta-%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f": [ + "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F" + ], + "X-Amz-Meta-%20%21%22%23$%25\u0026%27%28%29%2a+%2c-.%2f": [ + "%20%21%22%23$%25\u0026%27%28%29%2A+%2C-.%2F" + ], + "X-Amz-Meta-%5b%5c%5d%5e_": [ + "%5B%5C%5D%5E_" + ], + "X-Amz-Meta-%60": [ + "%60" + ], + "X-Amz-Meta-%7b%7c%7d~%7f": [ + "%7B%7C%7D~%7F" + ], + "X-Amz-Meta-%e2%98%ba%e2%98%ba%e2%98%ba": [ + "%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Amz-Meta-..%2ffoo%2f..%2fbar%2f..%2f..%2fbaz..%2f": [ + "..%2Ffoo%2F..%2Fbar%2F..%2F..%2Fbaz..%2F" + ], + "X-Amz-Meta-..%5cfoo%5c%5cbar%5c%5c%5cbaz": [ + "..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz" + ], + "X-Amz-Meta-..%5cfoo%5c..%5cbar%5c..%5c..%5cbaz..%5c": [ + "..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C" + ], + "X-Amz-Meta-12345": [ + "12345" + ], + "X-Amz-Meta-Foo%20bar%20baz": [ + "foo%20bar%20baz" + ], + "X-Amz-Meta-Foo%22bar%22baz": [ + "foo%22bar%22baz" + ], + "X-Amz-Meta-Foo%2f%2fbar%2f%2f%2fbaz": [ + "foo%2F%2Fbar%2F%2F%2Fbaz" + ], + "X-Amz-Meta-Foo%2fbar%2fbaz": [ + "foo%2Fbar%2Fbaz" + ], + "X-Amz-Meta-Foo%5cbar%5cbaz": [ + "foo%5Cbar%5Cbaz" + ], + "X-Amz-Meta-__0x3a__%3b%3c__0x3d__%3e%3f": [ + ":%3B%3C=%3E%3F" + ], + "X-Amz-Meta-__0x40__": [ + "@" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "NQ0KaGVsbG8NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk5oQ21oZz09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "NhCmhg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "GtZG0CGweQ4HO0T0LpvfQjGlCj4F5tMO7KfDVO+0nmNM3GyjTwlcA2iXYuHdjHKc1P4zxRHgmBNjKzPKYZMUWTjgqEtl0sBvIdIzFQJRy84=" + ], + "X-Amz-Request-Id": [ + "6PMF1BJ35BNA90NR" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7baf32f5e39f5da1", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "EtIq9SoaQZuS+eCwkLwwlnaPW1FoO8Wtdqs1APHk/4hBnrgHN/kBkSWSFLpE9txYPZI/ak25BVJrI/QcOSJTv053OGxszjww8l7QKgos0wE=" + ], + "X-Amz-Meta-%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f": [ + "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F" + ], + "X-Amz-Meta-%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f": [ + "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F" + ], + "X-Amz-Meta-%20%21%22%23$%25\u0026%27%28%29%2a+%2c-.%2f": [ + "%20%21%22%23$%25\u0026%27%28%29%2A+%2C-.%2F" + ], + "X-Amz-Meta-%5b%5c%5d%5e_": [ + "%5B%5C%5D%5E_" + ], + "X-Amz-Meta-%60": [ + "%60" + ], + "X-Amz-Meta-%7b%7c%7d~%7f": [ + "%7B%7C%7D~%7F" + ], + "X-Amz-Meta-%e2%98%ba%e2%98%ba%e2%98%ba": [ + "%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Amz-Meta-..%2ffoo%2f..%2fbar%2f..%2f..%2fbaz..%2f": [ + "..%2Ffoo%2F..%2Fbar%2F..%2F..%2Fbaz..%2F" + ], + "X-Amz-Meta-..%5cfoo%5c%5cbar%5c%5c%5cbaz": [ + "..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz" + ], + "X-Amz-Meta-..%5cfoo%5c..%5cbar%5c..%5c..%5cbaz..%5c": [ + "..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C" + ], + "X-Amz-Meta-12345": [ + "12345" + ], + "X-Amz-Meta-Foo%20bar%20baz": [ + "foo%20bar%20baz" + ], + "X-Amz-Meta-Foo%22bar%22baz": [ + "foo%22bar%22baz" + ], + "X-Amz-Meta-Foo%2f%2fbar%2f%2f%2fbaz": [ + "foo%2F%2Fbar%2F%2F%2Fbaz" + ], + "X-Amz-Meta-Foo%2fbar%2fbaz": [ + "foo%2Fbar%2Fbaz" + ], + "X-Amz-Meta-Foo%5cbar%5cbaz": [ + "foo%5Cbar%5Cbaz" + ], + "X-Amz-Meta-__0x3a__%3b%3c__0x3d__%3e%3f": [ + ":%3B%3C=%3E%3F" + ], + "X-Amz-Meta-__0x40__": [ + "@" + ], + "X-Amz-Request-Id": [ + "6PM2QPT9EF2TSQCC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "9f75eb2ab71434b9", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Etag": [ + "\"5d41402abc4b2a76b9719d911017c592\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Rd42uwuXggQ+r6dx+1biME2B5Gul6IMRoJCjjCKYIez3CC5Ood9f+6MRS69nQphvh2w6DhD5Vahd2azEJT2AeAWOnJ+Cew43QfqW61IwW+4=" + ], + "X-Amz-Meta-%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f": [ + "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F" + ], + "X-Amz-Meta-%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f": [ + "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F" + ], + "X-Amz-Meta-%20%21%22%23$%25\u0026%27%28%29%2a+%2c-.%2f": [ + "%20%21%22%23$%25\u0026%27%28%29%2A+%2C-.%2F" + ], + "X-Amz-Meta-%5b%5c%5d%5e_": [ + "%5B%5C%5D%5E_" + ], + "X-Amz-Meta-%60": [ + "%60" + ], + "X-Amz-Meta-%7b%7c%7d~%7f": [ + "%7B%7C%7D~%7F" + ], + "X-Amz-Meta-%e2%98%ba%e2%98%ba%e2%98%ba": [ + "%E2%98%BA%E2%98%BA%E2%98%BA" + ], + "X-Amz-Meta-..%2ffoo%2f..%2fbar%2f..%2f..%2fbaz..%2f": [ + "..%2Ffoo%2F..%2Fbar%2F..%2F..%2Fbaz..%2F" + ], + "X-Amz-Meta-..%5cfoo%5c%5cbar%5c%5c%5cbaz": [ + "..%5Cfoo%5C%5Cbar%5C%5C%5Cbaz" + ], + "X-Amz-Meta-..%5cfoo%5c..%5cbar%5c..%5c..%5cbaz..%5c": [ + "..%5Cfoo%5C..%5Cbar%5C..%5C..%5Cbaz..%5C" + ], + "X-Amz-Meta-12345": [ + "12345" + ], + "X-Amz-Meta-Foo%20bar%20baz": [ + "foo%20bar%20baz" + ], + "X-Amz-Meta-Foo%22bar%22baz": [ + "foo%22bar%22baz" + ], + "X-Amz-Meta-Foo%2f%2fbar%2f%2f%2fbaz": [ + "foo%2F%2Fbar%2F%2F%2Fbaz" + ], + "X-Amz-Meta-Foo%2fbar%2fbaz": [ + "foo%2Fbar%2Fbaz" + ], + "X-Amz-Meta-Foo%5cbar%5cbaz": [ + "foo%5Cbar%5Cbaz" + ], + "X-Amz-Meta-__0x3a__%3b%3c__0x3d__%3e%3f": [ + ":%3B%3C=%3E%3F" + ], + "X-Amz-Meta-__0x40__": [ + "@" + ], + "X-Amz-Request-Id": [ + "DTAWBN2Q3VGTKGS0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "99d2d73e2dfcf31b", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-metadata?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:26 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "bR1X01flxcZrMQcEHoL8dkNaISVFtcsVu2BHLwmAY9E/yZm/JHShZj6E3qGIp4AfRBTuBaamOjq6Uilh2XzaaDICJl53eaX/0oRdGWHsXIY=" + ], + "X-Amz-Request-Id": [ + "DTAWQNQT8FBVYBCM" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestNonexistentBucket.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestNonexistentBucket.replay new file mode 100644 index 000000000..c87012cd4 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestNonexistentBucket.replay @@ -0,0 +1,160 @@ +{ + "Initial": "AQAAAA7ffPP4H8oeRQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "7defd7c6356ffb8c", + "Request": { + "Method": "GET", + "URL": "https://go-cdk-bucket-does-not-exist.s3.us-west-1.amazonaws.com/?max-keys=1", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:12 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "wZmX64JRCytdRBd2TqDTMnp/GSEnoX2FbvoEOthZRvG53CF0I9e3MOQmGH04bmllkBtjKlBHCHk=" + ], + "X-Amz-Request-Id": [ + "PQJGEWFJ1ERACF9A" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEJ1Y2tldDwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGJ1Y2tldCBkb2VzIG5vdCBleGlzdDwvTWVzc2FnZT48QnVja2V0TmFtZT5nby1jZGstYnVja2V0LWRvZXMtbm90LWV4aXN0PC9CdWNrZXROYW1lPjxSZXF1ZXN0SWQ+UFFKR0VXRkoxRVJBQ0Y5QTwvUmVxdWVzdElkPjxIb3N0SWQ+d1ptWDY0SlJDeXRkUkJkMlRxRFRNbnAvR1NFbm9YMkZidm9FT3RoWlJ2RzUzQ0YwSTllM01PUW1HSDA0Ym1sbGtCdGpLbEJIQ0hrPTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "9674f0cc31161c1a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/?max-keys=1", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:13 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Bucket-Region": [ + "us-west-1" + ], + "X-Amz-Id-2": [ + "7ufzxKxF23XhiYuVwAoMsxl0lcUP9yZ2+aNsxY/0/ZPiYmV6wVWzqqzJXGxVdrahGSdoCp+w43M=" + ], + "X-Amz-Request-Id": [ + "PQJTXNNRZMDNGVXP" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPExpc3RCdWNrZXRSZXN1bHQgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PE5hbWU+Z28tY2xvdWQtdGVzdGluZy0yPC9OYW1lPjxQcmVmaXg+PC9QcmVmaXg+PE1hcmtlcj48L01hcmtlcj48TWF4S2V5cz4xPC9NYXhLZXlzPjxJc1RydW5jYXRlZD50cnVlPC9Jc1RydW5jYXRlZD48Q29udGVudHM+PEtleT5ibG9iLWZvci1jb3B5aW5nLWRlc3Q8L0tleT48TGFzdE1vZGlmaWVkPjIwMjUtMDMtMzFUMjA6Mzc6MDUuMDAwWjwvTGFzdE1vZGlmaWVkPjxFVGFnPiZxdW90O2IxMGE4ZGIxNjRlMDc1NDEwNWI3YTk5YmU3MmUzZmU1JnF1b3Q7PC9FVGFnPjxDaGVja3N1bUFsZ29yaXRobT5DUkMzMjwvQ2hlY2tzdW1BbGdvcml0aG0+PENoZWNrc3VtVHlwZT5GVUxMX09CSkVDVDwvQ2hlY2tzdW1UeXBlPjxTaXplPjExPC9TaXplPjxPd25lcj48SUQ+ZjQzNzViNTljMGNmZjQ4YjhlZDk5MDAyMmU5ZjI2NjZhNDUzZDk1OWYxM2Q3NzJhZjRjMTYxY2U5ZTA2NGEyYjwvSUQ+PERpc3BsYXlOYW1lPmFtYXpvbjwvRGlzcGxheU5hbWU+PC9Pd25lcj48U3RvcmFnZUNsYXNzPlNUQU5EQVJEPC9TdG9yYWdlQ2xhc3M+PC9Db250ZW50cz48L0xpc3RCdWNrZXRSZXN1bHQ+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/length_0_read.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/length_0_read.replay new file mode 100644 index 000000000..6f6028cf3 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/length_0_read.replay @@ -0,0 +1,409 @@ +{ + "Initial": "AQAAAA7ffPP9KYbOZQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "060296e9704b6256", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ZUSBBI39ytBInAOkHawHQrFJ4BbueMCV1/f+Qtmj0aOcmIJEa3Zx+PirYhdR6xfKSVXl0eSB6O0=" + ], + "X-Amz-Request-Id": [ + "ZVV3FPB4W0TYTDS6" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "85dcd37e2a85996a", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=0-0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 0-0/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "KR9LQZXYiblYSKR0CQnvg4LvXFafddy0RqBNM8uhN5pfHEp11EL3ZaWvaAHsc3vzhKnvv0UBG4c=" + ], + "X-Amz-Request-Id": [ + "ZVV4VTB3XTW65S9V" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YQ==" + } + }, + { + "ID": "03947a16394c1bb6", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=0-0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 0-0/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "nS4Aoh/VVjB48n/7078e6IM3JuBhLu8YrrbpXF3ZFLgRQm75zHoLuuIhSAdrtNTkpMqFtMoI1vE=" + ], + "X-Amz-Request-Id": [ + "ZVV3CHQV89RZ5D6K" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YQ==" + } + }, + { + "ID": "733601af607fe2b7", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+ldO0RPf5Q0yrQh1yBMLHoC9ykKYKivbv4lSj6g6FfOSYpkLhjeMZyxESX1sW57yxFb68J0sS60=" + ], + "X-Amz-Request-Id": [ + "ZVV82K2YBP1EKQ5R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7c0c4eb8e2a9bfbe", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "SKcD5SDwz3pIeD92uDF9AURHncqVWJnHdKSlzNe9xSsfIa4q2dBXa72j/rHRpJ+2QgGeE/nXuJ8=" + ], + "X-Amz-Request-Id": [ + "ZVVC6XSR8GZWM3TZ" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/negative_offset_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/negative_offset_fails.replay new file mode 100644 index 000000000..f706e136d --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/negative_offset_fails.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPP9KXrxuAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_a_part_in_middle.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_a_part_in_middle.replay new file mode 100644 index 000000000..c74a4bd78 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_a_part_in_middle.replay @@ -0,0 +1,646 @@ +{ + "Initial": "AQAAAA7ffPP+DYAsCgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "8fc4028c6481d3a3", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "11rvf5/3Ambqybka7tiy/6/iJr9hfiPdlBP0t04XBmKmmAT1WLd2aWAE7j85ZR7hcVGhUxou/Gg=" + ], + "X-Amz-Request-Id": [ + "RDDKV0W93PBEA8ZT" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "43f2dc21df841865", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=10-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 10-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "8RmZEcwL2+r7uGdYrGD94BHV4CoN5mgf7iCqwTaSKQw4n1ewL0avMrK8pllMbs2tp3bcv1qR7LA=" + ], + "X-Amz-Request-Id": [ + "RDDS7ZWYHE480GQP" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "a2xtbm8=" + } + }, + { + "ID": "ef414353f2c81314", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=10-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 10-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "MA0C+VPhYZZHxsKWt2BmeZMIKPeLxSrx56B2LChBKWWyxJaPM4LF6mC51lzu0UHX4nxA950BI9E=" + ], + "X-Amz-Request-Id": [ + "RDDZ3BN77D0ZNFCK" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "a2xtbm8=" + } + }, + { + "ID": "dd190c1a1e5f0fb3", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=14-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 14-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "sGH2Kn+7QFFompTmXyAPvdlUVvbKL7bQueNGmN58zdMKZf75IJQuhIxlQ6XYlk3IrSqeRJkMIFM=" + ], + "X-Amz-Request-Id": [ + "RDDXRDT5BK85JPPF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "bw==" + } + }, + { + "ID": "e1a4e46450197d7f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=14-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "1" + ], + "Content-Range": [ + "bytes 14-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "mwgQafkxQnLRH+Wh/j//FAnfj2kYPXUr6TPItuzlZZaMziTv8vA78NjO1i+vIMg4o+ueYUQGIcc=" + ], + "X-Amz-Request-Id": [ + "RDDXT35NW9TKJNNX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "bw==" + } + }, + { + "ID": "a6b283a017ab08d7", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=12-14" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "3" + ], + "Content-Range": [ + "bytes 12-14/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "f0dMw6v1jayoVVbv9DnVLz56DqgW5TmfnX+bipThqENhcv0t4eZZUOHjKTwpyAC57MKW1/9UH0A=" + ], + "X-Amz-Request-Id": [ + "RDDKWQ8AZ2GZFS15" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "bW5v" + } + }, + { + "ID": "1581936534101b8e", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "EN/7C38EzDEzb/vGs7gWV80z2VTRjOi8JnpVPd0F4l+FWnzioKSIsZbYx/Bkg+z8FW7Te9NGxKY=" + ], + "X-Amz-Request-Id": [ + "RDDN88XZT2FPPCVX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "6d2af3e11c61908e", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "wZH1Hy+KQAnvKEI2uJgfcaiHld1zYFUhSWUIuq6ayLV6kLaK41YH9RETZBmfaPh//6fBHHdShGE=" + ], + "X-Amz-Request-Id": [ + "RDDT9ZR8P8WSD80S" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_from_positive_offset_to_end.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_from_positive_offset_to_end.replay new file mode 100644 index 000000000..4e5b46620 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_from_positive_offset_to_end.replay @@ -0,0 +1,646 @@ +{ + "Initial": "AQAAAA7ffPP9NxsaCAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b89e439618ee661d", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ZbPvSC8v2p3hb7F91YUED02GkjlkMH1ZwOyAWa6qbGFKUSnuLWQ5HorvaIqY7zjo0mPPupQd4ks=" + ], + "X-Amz-Request-Id": [ + "ZVV7ZQHABJASFCSD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "452b3b0ba857d789", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=10-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "17" + ], + "Content-Range": [ + "bytes 10-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "upStnAMRnqYE/aQiO/L+7Z/RkPk5YfZKJY4gsSHCUsK6l1zZ3MiAUYTL+fQXL1heNwbW0GqiYVc=" + ], + "X-Amz-Request-Id": [ + "RDDJMMTGY1Y1AHHG" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "a2xtbm9wcXVyc3R1dnd4eXo=" + } + }, + { + "ID": "8803cfc768a5c692", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=10-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "17" + ], + "Content-Range": [ + "bytes 10-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "jHirMY6dIqypq4ZKKl+/AlKHc0HyCYfVmqx4JRpN5BJubbujrRXh6G0jvcH+nQRmgaLSY7D94e0=" + ], + "X-Amz-Request-Id": [ + "RDDYM9PAMCETYV0Q" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "a2xtbm9wcXVyc3R1dnd4eXo=" + } + }, + { + "ID": "5d8161c9ec19146f", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=22-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 22-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "twuZ3NwliME+gZFMwJis62QRs38ErooFG/q8ihmMBQTteegkmwJZR0n8ky20NJ9InY2iJ5hXIoE=" + ], + "X-Amz-Request-Id": [ + "RDDSTQXESS1MQ4D3" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "dnd4eXo=" + } + }, + { + "ID": "8159e3b7d72bb45d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=22-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "5" + ], + "Content-Range": [ + "bytes 22-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "oitBkSz3sjTmbFO6EoN4/izaQWz0Xf/YP7uSxvFRS4U2GXRDimo6tPtRZHyQQkAX6MKdgfSuAzw=" + ], + "X-Amz-Request-Id": [ + "RDDPRFEETC66BPDS" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "dnd4eXo=" + } + }, + { + "ID": "6c686280905d04d0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=16-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Range": [ + "bytes 16-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "woif/yrXFs4gpErRW4yj6rDEOtAfL/AaErDcmnbXzwtOMGnAE6XYTKr0ZJR1yjDhvgHDie6vr7Y=" + ], + "X-Amz-Request-Id": [ + "RDDN7RSKYBWE4WKB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "cXVyc3R1dnd4eXo=" + } + }, + { + "ID": "eeb3cb0ebab3f0ca", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Pv7dEKDjMAnP5Qiz+5LgAtM7QW0+4SWFBluAqX/RJa5X1G5dwGAFvsEvLK3juDBBECZ+6LixKuM=" + ], + "X-Amz-Request-Id": [ + "RDDKTDKYMA5K38CW" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c4ab11fa8bffe52a", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "xiqfoxnFh/dQsQov3R/T7xLHCG4ss+s0Vj7KzMAsCAGqZiyJMPzT84Gw8YuVqqGUGi0WquQjeIw=" + ], + "X-Amz-Request-Id": [ + "RDDNTX6SX9EK2RRF" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_in_full.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_in_full.replay new file mode 100644 index 000000000..b00204548 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_in_full.replay @@ -0,0 +1,646 @@ +{ + "Initial": "AQAAAA7ffPP+HovIugAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "bf11e2f53615540e", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "tsERo1pRVH4VWXNSrDmsT2u2mAL8gsunJSBskI6oyKgS0dRGtckCshmWW17ymJlVXhQ8m0E70vFw2ZQnGPnwCw==" + ], + "X-Amz-Request-Id": [ + "RDDJ3ZR1FND2P28K" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "af8299dfd77af957", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ySbskEcM12sP8OzmybWNKV7kGMIcWerMx0MyyCUAGNTC398+LnngTNbdG1xQCKnn3Ot/Buss+uO1I7GeT+thbg==" + ], + "X-Amz-Request-Id": [ + "RDDYWJHFEF0MMG7S" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "4db4cca7d5032d86", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Nith7U7/AkwbN7Gn4GgCG+hACT+JWbv/REllpdoaLkVFzrOaAxH4BBCoEooewNemXE+glY6s91Pamd+IMhZvfw==" + ], + "X-Amz-Request-Id": [ + "RDDPM9XS73DW994J" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "d8dec239787036d2", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "lxZih4rFtGstGxg0ryA0wG4UtLZpwISv9MfLkLS1QNIUEkbUCTy2iykvZxQJqYhRHg4vxOcOTGNUx46V7qqD4Q==" + ], + "X-Amz-Request-Id": [ + "RDDQBSWQ8BWG1DJZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "f44d057ecc54aee9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "UconQovph1UQakUQBz9Jrg8+oms0TiqMYU3TLkRdLJ/A6rn0H7l3bMPD2w1v9fCoIm/dMF0KwUiKREaaL+lEkA==" + ], + "X-Amz-Request-Id": [ + "RDDGETDFTNGB704M" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "4c57882d4dd34a80", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=9-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "18" + ], + "Content-Range": [ + "bytes 9-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "l6EWN0BBRm7eUKv4il/SJkoqPEKamenjexnGu0h1pilHxT2lblqMwNMggFDS60t73vh38Vq6GixtIJqtT3ZNCQ==" + ], + "X-Amz-Request-Id": [ + "RDDZ7788H77AQFQX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "amtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "0094096e0b1ae7be", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "4ReHq29k+r5lFaiEymtj7NYtFsMtBWyURSPSL3PBLBYPdV/ij3RUvCNgZ02FpshsB57LlC/MSHDTHwxfrgct/Q==" + ], + "X-Amz-Request-Id": [ + "RDDK52WBV3EMMZVD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "67dcaf6cc679134f", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "RnzpNynkfU/qMpUy9Zh7CtmjF/TDwnAUgxEnAW6i33B/Jk/QzjOHvwNbh33GjNGl1ZXCmrchJBJYjsCAmkOe3Q==" + ], + "X-Amz-Request-Id": [ + "RDDZK7E3T8PT4TES" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_in_full_with_negative_length_not_-1.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_in_full_with_negative_length_not_-1.replay new file mode 100644 index 000000000..ddcc19d39 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_in_full_with_negative_length_not_-1.replay @@ -0,0 +1,646 @@ +{ + "Initial": "AQAAAA7ffPP+L9cGUQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "d8ac803e28994685", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "qkEJ4QmBPaHm20KRiIMI4bWiGNd4t/0UNFJLUk6xIlhPwXD4nmuw41fPZ+TQnC6RNw6Ay80hmFQ=" + ], + "X-Amz-Request-Id": [ + "RDDQST8G4SHVMHSQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "979da310b4e744ba", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "dz3QHcH+cYoC05Sc4lC+faYIlWro7UtpRjt0fI4MvBar8LO5qGancbOja9Vszomn3cDcpiHGRug=" + ], + "X-Amz-Request-Id": [ + "RDDVQ781DWBQMSB9" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "ca60e53956975107", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "Xits3Xv7aUaf/9LK4XTYS6pkuFPX57BVawHxcT+f1WQxPCb8tpMwJVNXn487aRBfy1wCKXtL2so=" + ], + "X-Amz-Request-Id": [ + "RDDS4ZM8JT7A0BGD" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "YWJjZGVmZ2hpamtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "eb19d3ed61d458cc", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "wDKEElUbhTjPoX8E6Rvkvf04ym+fEeBvy/lDJOxlYll6lSFtVXIvRO76NuZIx0TGCe6PSrryGiQ=" + ], + "X-Amz-Request-Id": [ + "RDDT8BAFMBHD4WZM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "e5ec28c0b3240402", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=18-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "9" + ], + "Content-Range": [ + "bytes 18-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "AWFAyR9kXc7UbhXLiTce07Wjeq3h9jS6lvk0oj53l/sQSEEykDsPniZPOuQzeu9fc8W12Is+qOM=" + ], + "X-Amz-Request-Id": [ + "RDDK93TB6HQREJ9V" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "cnN0dXZ3eHl6" + } + }, + { + "ID": "89b6e3658b3d4ec4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Range": [ + "bytes=9-" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 206, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "18" + ], + "Content-Range": [ + "bytes 9-26/27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "1PSuFB1QLOeD+NCQAlXF7PWOiMiL6/EUYNt2Gw7/zIVSeSk8Fcjhqgqh4DYSl5PL+NAs+tIlF8E=" + ], + "X-Amz-Request-Id": [ + "3XSDVGYAN6ETHEPZ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "amtsbW5vcHF1cnN0dXZ3eHl6" + } + }, + { + "ID": "8a9b29d094ed52a9", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:19 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "c4DjlXCBY2WL/XwUH41MUBkSp70mednfmqhh/fezbAdwwisxsKljn3kcUBM+F8ybAluGrg3G70Y=" + ], + "X-Amz-Request-Id": [ + "3XSBY9ZXYHSXARSF" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "fbbb94d96833f2c4", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "hv9aJfVsZsYCYhxlkqy0LECVbPAfd6YX8FgylmX8sxKQXemh4EoCFTbotFFjYSzxfoznk2xxfS0=" + ], + "X-Amz-Request-Id": [ + "3XS5E76MW7NYSYXQ" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_of_nonexistent_key_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_of_nonexistent_key_fails.replay new file mode 100644 index 000000000..4d5cf5a96 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestRead/read_of_nonexistent_key_fails.replay @@ -0,0 +1,309 @@ +{ + "Initial": "AQAAAA7ffPP9Hq9bWQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "2ea05e40fa2e4475", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "69" + ], + "Content-Md5": [ + "PflsWr6X8pZ9OAEIcAMKXw==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "27" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MWINCmFiY2RlZmdoaWprbG1ub3BxdXJzdHV2d3h5eg0KMA0KeC1hbXotY2hlY2tzdW0tY3JjMzI6UnlQZzVRPT0NCg0K" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "RyPg5Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "9GK2IFdqSfY0INMF0PYxOBBrhwYkLUheIkgbBk+NUWRs7wiSl1BVG+j6v4RXAmRZLlTJ2p+pGiA=" + ], + "X-Amz-Request-Id": [ + "ZVVCD6D33VVHTF1Y" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a7771926ef0d5ed0", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/key-does-not-exist?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:17 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "E7rJ6GLidPggqDhdnSpF1uyFtOsTGQMPHqPtCQuX6JnGZCwZLYZY9hYKUo8v6djTxkmkdu+25yc=" + ], + "X-Amz-Request-Id": [ + "ZVV22JFMP1NZQMF2" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5rZXktZG9lcy1ub3QtZXhpc3Q8L0tleT48UmVxdWVzdElkPlpWVjIySkZNUDFOWlFNRjI8L1JlcXVlc3RJZD48SG9zdElkPkU3cko2R0xpZFBnZ3FEaGRuU3BGMXV5RnRPc1RHUU1QSHFQdENRdVg2Sm5HWkN3WkxZWlk5aFlLVW84djZkalR4a21rZHUrMjV5Yz08L0hvc3RJZD48L0Vycm9yPg==" + } + }, + { + "ID": "783531520b610102", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "27" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Etag": [ + "\"3df96c5abe97f2967d38010870030a5f\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "DvqoPZaslpuFKHYKo/fh1iwKKrHYh58MKFtmLezjXCnpU3GKuDUyL/KaZm4mFidnFLUS1aIEI0E=" + ], + "X-Amz-Request-Id": [ + "ZVV8004HFMZ9XXC0" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "4497412e27afabe7", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "jrqwq0jf9LGI/KL46lC78jOA4ui8ZishjM5CJJ9FDWH9OWfvQIFmQvGNSHo78/wzFcPrnS6MFxw=" + ], + "X-Amz-Request-Id": [ + "ZVVF365N85KWYAEV" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestSignedURL.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestSignedURL.replay new file mode 100644 index 000000000..4cb48063c --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestSignedURL.replay @@ -0,0 +1,381 @@ +{ + "Initial": "AQAAAA7ffPQNEMg6swAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "f25648861dba057e", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:32 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rt2nSXR0RRQXcRwazR3gCZPOumywd5XQXDy3Qr3gRGjUklQJt6en2PHUrOrbkvSNM8y/jSI1N1Y=" + ], + "X-Amz-Request-Id": [ + "1RC68T800QX9673T" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPlNpZ25hdHVyZURvZXNOb3RNYXRjaDwvQ29kZT48TWVzc2FnZT5UaGUgcmVxdWVzdCBzaWduYXR1cmUgd2UgY2FsY3VsYXRlZCBkb2VzIG5vdCBtYXRjaCB0aGUgc2lnbmF0dXJlIHlvdSBwcm92aWRlZC4gQ2hlY2sgeW91ciBrZXkgYW5kIHNpZ25pbmcgbWV0aG9kLjwvTWVzc2FnZT48QVdTQWNjZXNzS2V5SWQ+QUtJQVdVV0VVU1BVTFlYM0JMM008L0FXU0FjY2Vzc0tleUlkPjxTdHJpbmdUb1NpZ24+QVdTNC1ITUFDLVNIQTI1NgoyMDI1MDMzMVQyMDM3MzNaCjIwMjUwMzMxL3VzLXdlc3QtMS9zMy9hd3M0X3JlcXVlc3QKMjdjNDUzYTUzZGM2M2M3ODk2ZmJhOWI0YzJlMjE4MWYxYWMzY2M5MWJmOGFjMDU4NmQ4YTZiZjE2ZGM4MzBkZDwvU3RyaW5nVG9TaWduPjxTaWduYXR1cmVQcm92aWRlZD41MjAyYjhkZjQ3YzMzOGNjZGY2ZDVjZTk4ZTBiYTE2NTQ3MGNmNzY4OGI3N2Q5NTAzOTFmZDM2ZjUyNjdiOWQ2PC9TaWduYXR1cmVQcm92aWRlZD48U3RyaW5nVG9TaWduQnl0ZXM+NDEgNTcgNTMgMzQgMmQgNDggNGQgNDEgNDMgMmQgNTMgNDggNDEgMzIgMzUgMzYgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgNTQgMzIgMzAgMzMgMzcgMzMgMzMgNWEgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgMmYgNzUgNzMgMmQgNzcgNjUgNzMgNzQgMmQgMzEgMmYgNzMgMzMgMmYgNjEgNzcgNzMgMzQgNWYgNzIgNjUgNzEgNzUgNjUgNzMgNzQgMGEgMzIgMzcgNjMgMzQgMzUgMzMgNjEgMzUgMzMgNjQgNjMgMzYgMzMgNjMgMzcgMzggMzkgMzYgNjYgNjIgNjEgMzkgNjIgMzQgNjMgMzIgNjUgMzIgMzEgMzggMzEgNjYgMzEgNjEgNjMgMzMgNjMgNjMgMzkgMzEgNjIgNjYgMzggNjEgNjMgMzAgMzUgMzggMzYgNjQgMzggNjEgMzYgNjIgNjYgMzEgMzYgNjQgNjMgMzggMzMgMzAgNjQgNjQ8L1N0cmluZ1RvU2lnbkJ5dGVzPjxDYW5vbmljYWxSZXF1ZXN0PlBVVAovYmxvYi1mb3Itc2lnbmluZwpYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZhbXA7WC1BbXotQ2hlY2tzdW0tTW9kZT1FTkFCTEVEJmFtcDtYLUFtei1DcmVkZW50aWFsPUFLSUFXVVdFVVNQVUxZWDNCTDNNJTJGMjAyNTAzMzElMkZ1cy13ZXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZhbXA7WC1BbXotRGF0ZT0yMDI1MDMzMVQyMDM3MzNaJmFtcDtYLUFtei1FeHBpcmVzPTM2MDAmYW1wO1gtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhbXA7eC1pZD1HZXRPYmplY3QKaG9zdDpnby1jbG91ZC10ZXN0aW5nLTIuczMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20KCmhvc3QKVU5TSUdORUQtUEFZTE9BRDwvQ2Fub25pY2FsUmVxdWVzdD48Q2Fub25pY2FsUmVxdWVzdEJ5dGVzPjUwIDU1IDU0IDBhIDJmIDYyIDZjIDZmIDYyIDJkIDY2IDZmIDcyIDJkIDczIDY5IDY3IDZlIDY5IDZlIDY3IDBhIDU4IDJkIDQxIDZkIDdhIDJkIDQxIDZjIDY3IDZmIDcyIDY5IDc0IDY4IDZkIDNkIDQxIDU3IDUzIDM0IDJkIDQ4IDRkIDQxIDQzIDJkIDUzIDQ4IDQxIDMyIDM1IDM2IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQzIDY4IDY1IDYzIDZiIDczIDc1IDZkIDJkIDRkIDZmIDY0IDY1IDNkIDQ1IDRlIDQxIDQyIDRjIDQ1IDQ0IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQzIDcyIDY1IDY0IDY1IDZlIDc0IDY5IDYxIDZjIDNkIDQxIDRiIDQ5IDQxIDU3IDU1IDU3IDQ1IDU1IDUzIDUwIDU1IDRjIDU5IDU4IDMzIDQyIDRjIDMzIDRkIDI1IDMyIDQ2IDMyIDMwIDMyIDM1IDMwIDMzIDMzIDMxIDI1IDMyIDQ2IDc1IDczIDJkIDc3IDY1IDczIDc0IDJkIDMxIDI1IDMyIDQ2IDczIDMzIDI1IDMyIDQ2IDYxIDc3IDczIDM0IDVmIDcyIDY1IDcxIDc1IDY1IDczIDc0IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQ0IDYxIDc0IDY1IDNkIDMyIDMwIDMyIDM1IDMwIDMzIDMzIDMxIDU0IDMyIDMwIDMzIDM3IDMzIDMzIDVhIDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQ1IDc4IDcwIDY5IDcyIDY1IDczIDNkIDMzIDM2IDMwIDMwIDI2IDU4IDJkIDQxIDZkIDdhIDJkIDUzIDY5IDY3IDZlIDY1IDY0IDQ4IDY1IDYxIDY0IDY1IDcyIDczIDNkIDY4IDZmIDczIDc0IDI2IDc4IDJkIDY5IDY0IDNkIDQ3IDY1IDc0IDRmIDYyIDZhIDY1IDYzIDc0IDBhIDY4IDZmIDczIDc0IDNhIDY3IDZmIDJkIDYzIDZjIDZmIDc1IDY0IDJkIDc0IDY1IDczIDc0IDY5IDZlIDY3IDJkIDMyIDJlIDczIDMzIDJlIDc1IDczIDJkIDc3IDY1IDczIDc0IDJkIDMxIDJlIDYxIDZkIDYxIDdhIDZmIDZlIDYxIDc3IDczIDJlIDYzIDZmIDZkIDBhIDBhIDY4IDZmIDczIDc0IDBhIDU1IDRlIDUzIDQ5IDQ3IDRlIDQ1IDQ0IDJkIDUwIDQxIDU5IDRjIDRmIDQxIDQ0PC9DYW5vbmljYWxSZXF1ZXN0Qnl0ZXM+PFJlcXVlc3RJZD4xUkM2OFQ4MDBRWDk2NzNUPC9SZXF1ZXN0SWQ+PEhvc3RJZD5ydDJuU1hSMFJSUVhjUndhelIzZ0NaUE91bXl3ZDVYUVhEeTNRcjNnUkdqVWtsUUp0NmVuMlBIVXJPcmJrdlNOTTh5L2pTSTFOMVk9PC9Ib3N0SWQ+PC9FcnJvcj4=" + } + }, + { + "ID": "9d05466552b3858c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "11" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "aGVsbG8gd29ybGQ=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc64nvme": [ + "jSnVw/bqjr4=" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "9j9buRQocPfDtmzo2mj+DEyLF7N/SBaHSpfsgFeufz+TmgzWyAnUcqesiBF+2Oo4HqmVpahdGZoLE5cAgOOPzg==" + ], + "X-Amz-Request-Id": [ + "1RCAP59CSJP50RAA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "abc0391f84061f22", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Kqc5rfOFksAzlWCMq051EBjsN3w8QgQYJMzDOF2Qn9HwflZ0ogV4fIbFLhDVlBAzIdWnYjIOCY+y8UTUgKMoUQ==" + ], + "X-Amz-Request-Id": [ + "1RCF3QANN8Z2V14G" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPlNpZ25hdHVyZURvZXNOb3RNYXRjaDwvQ29kZT48TWVzc2FnZT5UaGUgcmVxdWVzdCBzaWduYXR1cmUgd2UgY2FsY3VsYXRlZCBkb2VzIG5vdCBtYXRjaCB0aGUgc2lnbmF0dXJlIHlvdSBwcm92aWRlZC4gQ2hlY2sgeW91ciBrZXkgYW5kIHNpZ25pbmcgbWV0aG9kLjwvTWVzc2FnZT48QVdTQWNjZXNzS2V5SWQ+QUtJQVdVV0VVU1BVTFlYM0JMM008L0FXU0FjY2Vzc0tleUlkPjxTdHJpbmdUb1NpZ24+QVdTNC1ITUFDLVNIQTI1NgoyMDI1MDMzMVQyMDM3MzNaCjIwMjUwMzMxL3VzLXdlc3QtMS9zMy9hd3M0X3JlcXVlc3QKZTQ4YzRmODQzNjJmZmFhZDc5NWZmYzg3YzRiMDcxOWRjM2ZmY2I5ODgwYzVmYzFhNGUyODA2M2RmOWY0MDNlMjwvU3RyaW5nVG9TaWduPjxTaWduYXR1cmVQcm92aWRlZD5hYjJiNTZmMTU2MDVkN2JmODUyMDZhYjUyNGNmMTFjOWZlYmQ4MTZhNjlmYWEyM2U0NjY1NDNiM2UzMjBkOWVhPC9TaWduYXR1cmVQcm92aWRlZD48U3RyaW5nVG9TaWduQnl0ZXM+NDEgNTcgNTMgMzQgMmQgNDggNGQgNDEgNDMgMmQgNTMgNDggNDEgMzIgMzUgMzYgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgNTQgMzIgMzAgMzMgMzcgMzMgMzMgNWEgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgMmYgNzUgNzMgMmQgNzcgNjUgNzMgNzQgMmQgMzEgMmYgNzMgMzMgMmYgNjEgNzcgNzMgMzQgNWYgNzIgNjUgNzEgNzUgNjUgNzMgNzQgMGEgNjUgMzQgMzggNjMgMzQgNjYgMzggMzQgMzMgMzYgMzIgNjYgNjYgNjEgNjEgNjQgMzcgMzkgMzUgNjYgNjYgNjMgMzggMzcgNjMgMzQgNjIgMzAgMzcgMzEgMzkgNjQgNjMgMzMgNjYgNjYgNjMgNjIgMzkgMzggMzggMzAgNjMgMzUgNjYgNjMgMzEgNjEgMzQgNjUgMzIgMzggMzAgMzYgMzMgNjQgNjYgMzkgNjYgMzQgMzAgMzMgNjUgMzI8L1N0cmluZ1RvU2lnbkJ5dGVzPjxDYW5vbmljYWxSZXF1ZXN0PkdFVAovYmxvYi1mb3Itc2lnbmluZwpYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZhbXA7WC1BbXotQ3JlZGVudGlhbD1BS0lBV1VXRVVTUFVMWVgzQkwzTSUyRjIwMjUwMzMxJTJGdXMtd2VzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmYW1wO1gtQW16LURhdGU9MjAyNTAzMzFUMjAzNzMzWiZhbXA7WC1BbXotRXhwaXJlcz0zNjAwJmFtcDtYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYW1wO3gtaWQ9UHV0T2JqZWN0Cmhvc3Q6Z28tY2xvdWQtdGVzdGluZy0yLnMzLnVzLXdlc3QtMS5hbWF6b25hd3MuY29tCgpob3N0ClVOU0lHTkVELVBBWUxPQUQ8L0Nhbm9uaWNhbFJlcXVlc3Q+PENhbm9uaWNhbFJlcXVlc3RCeXRlcz40NyA0NSA1NCAwYSAyZiA2MiA2YyA2ZiA2MiAyZCA2NiA2ZiA3MiAyZCA3MyA2OSA2NyA2ZSA2OSA2ZSA2NyAwYSA1OCAyZCA0MSA2ZCA3YSAyZCA0MSA2YyA2NyA2ZiA3MiA2OSA3NCA2OCA2ZCAzZCA0MSA1NyA1MyAzNCAyZCA0OCA0ZCA0MSA0MyAyZCA1MyA0OCA0MSAzMiAzNSAzNiAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0MyA3MiA2NSA2NCA2NSA2ZSA3NCA2OSA2MSA2YyAzZCA0MSA0YiA0OSA0MSA1NyA1NSA1NyA0NSA1NSA1MyA1MCA1NSA0YyA1OSA1OCAzMyA0MiA0YyAzMyA0ZCAyNSAzMiA0NiAzMiAzMCAzMiAzNSAzMCAzMyAzMyAzMSAyNSAzMiA0NiA3NSA3MyAyZCA3NyA2NSA3MyA3NCAyZCAzMSAyNSAzMiA0NiA3MyAzMyAyNSAzMiA0NiA2MSA3NyA3MyAzNCA1ZiA3MiA2NSA3MSA3NSA2NSA3MyA3NCAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0NCA2MSA3NCA2NSAzZCAzMiAzMCAzMiAzNSAzMCAzMyAzMyAzMSA1NCAzMiAzMCAzMyAzNyAzMyAzMyA1YSAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0NSA3OCA3MCA2OSA3MiA2NSA3MyAzZCAzMyAzNiAzMCAzMCAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA1MyA2OSA2NyA2ZSA2NSA2NCA0OCA2NSA2MSA2NCA2NSA3MiA3MyAzZCA2OCA2ZiA3MyA3NCAyNiA3OCAyZCA2OSA2NCAzZCA1MCA3NSA3NCA0ZiA2MiA2YSA2NSA2MyA3NCAwYSA2OCA2ZiA3MyA3NCAzYSA2NyA2ZiAyZCA2MyA2YyA2ZiA3NSA2NCAyZCA3NCA2NSA3MyA3NCA2OSA2ZSA2NyAyZCAzMiAyZSA3MyAzMyAyZSA3NSA3MyAyZCA3NyA2NSA3MyA3NCAyZCAzMSAyZSA2MSA2ZCA2MSA3YSA2ZiA2ZSA2MSA3NyA3MyAyZSA2MyA2ZiA2ZCAwYSAwYSA2OCA2ZiA3MyA3NCAwYSA1NSA0ZSA1MyA0OSA0NyA0ZSA0NSA0NCAyZCA1MCA0MSA1OSA0YyA0ZiA0MSA0NDwvQ2Fub25pY2FsUmVxdWVzdEJ5dGVzPjxSZXF1ZXN0SWQ+MVJDRjNRQU5OOFoyVjE0RzwvUmVxdWVzdElkPjxIb3N0SWQ+S3FjNXJmT0Zrc0F6bFdDTXEwNTFFQmpzTjN3OFFnUVlKTXpET0YyUW45SHdmbFowb2dWNGZJYkZMaERWbEJBeklkV25ZaklPQ1kreThVVFVnS01vVVE9PTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "238673cb6750e012", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "0DQd7uFbfPZOLSZ6RFDTFEDLszASux1RmdXt0aEN/EGtaOfiosqOiB9PQkr0tirlfeVlKHLQ1dz/3DaoQGozVw==" + ], + "X-Amz-Request-Id": [ + "1RC2H35C55GHQ0S4" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPkFjY2Vzc0RlbmllZDwvQ29kZT48TWVzc2FnZT5BY2Nlc3MgRGVuaWVkPC9NZXNzYWdlPjxSZXF1ZXN0SWQ+MVJDMkgzNUM1NUdIUTBTNDwvUmVxdWVzdElkPjxIb3N0SWQ+MERRZDd1RmJmUFpPTFNaNlJGRFRGRURMc3pBU3V4MVJtZFh0MGFFTi9FR3RhT2Zpb3NxT2lCOVBRa3IwdGlybGZlVmxLSExRMWR6LzNEYW9RR296Vnc9PTwvSG9zdElkPjwvRXJyb3I+" + } + }, + { + "ID": "ade1110323e9259d", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "binary/octet-stream" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:34 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "s7WYDGcFob5ro1O0Jjx4TVi2cWf/p/LXN1GN6Tkq+/baknCrhmf3sA1ShAJX8rZabhYPGom3raaR3SclvvTNRg==" + ], + "X-Amz-Request-Id": [ + "1RCE7D3JPD50P2BA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "11b4b9e9e2af31c6", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Checksum-Mode=ENABLED\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "JM+mX+JMVRjFqVeQXGRr3SXUJH30HqEURe55JkkuTRcHpGJs1iyFGU67CdeMF8BK6DE2OPSlb/pI08RtYOzXNg==" + ], + "X-Amz-Request-Id": [ + "1RC87RDVH8GF4SFR" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPlNpZ25hdHVyZURvZXNOb3RNYXRjaDwvQ29kZT48TWVzc2FnZT5UaGUgcmVxdWVzdCBzaWduYXR1cmUgd2UgY2FsY3VsYXRlZCBkb2VzIG5vdCBtYXRjaCB0aGUgc2lnbmF0dXJlIHlvdSBwcm92aWRlZC4gQ2hlY2sgeW91ciBrZXkgYW5kIHNpZ25pbmcgbWV0aG9kLjwvTWVzc2FnZT48QVdTQWNjZXNzS2V5SWQ+QUtJQVdVV0VVU1BVTFlYM0JMM008L0FXU0FjY2Vzc0tleUlkPjxTdHJpbmdUb1NpZ24+QVdTNC1ITUFDLVNIQTI1NgoyMDI1MDMzMVQyMDM3MzNaCjIwMjUwMzMxL3VzLXdlc3QtMS9zMy9hd3M0X3JlcXVlc3QKZDlhN2UwNWNmNTY5ODdlNzEwYjI4NGU1YWU2ZDkxMDcxYWIyYzUyMTFkNGEyM2U1YWFlN2Y3Yzg3ZWY3ODFmMTwvU3RyaW5nVG9TaWduPjxTaWduYXR1cmVQcm92aWRlZD41MjAyYjhkZjQ3YzMzOGNjZGY2ZDVjZTk4ZTBiYTE2NTQ3MGNmNzY4OGI3N2Q5NTAzOTFmZDM2ZjUyNjdiOWQ2PC9TaWduYXR1cmVQcm92aWRlZD48U3RyaW5nVG9TaWduQnl0ZXM+NDEgNTcgNTMgMzQgMmQgNDggNGQgNDEgNDMgMmQgNTMgNDggNDEgMzIgMzUgMzYgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgNTQgMzIgMzAgMzMgMzcgMzMgMzMgNWEgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgMmYgNzUgNzMgMmQgNzcgNjUgNzMgNzQgMmQgMzEgMmYgNzMgMzMgMmYgNjEgNzcgNzMgMzQgNWYgNzIgNjUgNzEgNzUgNjUgNzMgNzQgMGEgNjQgMzkgNjEgMzcgNjUgMzAgMzUgNjMgNjYgMzUgMzYgMzkgMzggMzcgNjUgMzcgMzEgMzAgNjIgMzIgMzggMzQgNjUgMzUgNjEgNjUgMzYgNjQgMzkgMzEgMzAgMzcgMzEgNjEgNjIgMzIgNjMgMzUgMzIgMzEgMzEgNjQgMzQgNjEgMzIgMzMgNjUgMzUgNjEgNjEgNjUgMzcgNjYgMzcgNjMgMzggMzcgNjUgNjYgMzcgMzggMzEgNjYgMzE8L1N0cmluZ1RvU2lnbkJ5dGVzPjxDYW5vbmljYWxSZXF1ZXN0PkRFTEVURQovYmxvYi1mb3Itc2lnbmluZwpYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZhbXA7WC1BbXotQ2hlY2tzdW0tTW9kZT1FTkFCTEVEJmFtcDtYLUFtei1DcmVkZW50aWFsPUFLSUFXVVdFVVNQVUxZWDNCTDNNJTJGMjAyNTAzMzElMkZ1cy13ZXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZhbXA7WC1BbXotRGF0ZT0yMDI1MDMzMVQyMDM3MzNaJmFtcDtYLUFtei1FeHBpcmVzPTM2MDAmYW1wO1gtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhbXA7eC1pZD1HZXRPYmplY3QKaG9zdDpnby1jbG91ZC10ZXN0aW5nLTIuczMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20KCmhvc3QKVU5TSUdORUQtUEFZTE9BRDwvQ2Fub25pY2FsUmVxdWVzdD48Q2Fub25pY2FsUmVxdWVzdEJ5dGVzPjQ0IDQ1IDRjIDQ1IDU0IDQ1IDBhIDJmIDYyIDZjIDZmIDYyIDJkIDY2IDZmIDcyIDJkIDczIDY5IDY3IDZlIDY5IDZlIDY3IDBhIDU4IDJkIDQxIDZkIDdhIDJkIDQxIDZjIDY3IDZmIDcyIDY5IDc0IDY4IDZkIDNkIDQxIDU3IDUzIDM0IDJkIDQ4IDRkIDQxIDQzIDJkIDUzIDQ4IDQxIDMyIDM1IDM2IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQzIDY4IDY1IDYzIDZiIDczIDc1IDZkIDJkIDRkIDZmIDY0IDY1IDNkIDQ1IDRlIDQxIDQyIDRjIDQ1IDQ0IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQzIDcyIDY1IDY0IDY1IDZlIDc0IDY5IDYxIDZjIDNkIDQxIDRiIDQ5IDQxIDU3IDU1IDU3IDQ1IDU1IDUzIDUwIDU1IDRjIDU5IDU4IDMzIDQyIDRjIDMzIDRkIDI1IDMyIDQ2IDMyIDMwIDMyIDM1IDMwIDMzIDMzIDMxIDI1IDMyIDQ2IDc1IDczIDJkIDc3IDY1IDczIDc0IDJkIDMxIDI1IDMyIDQ2IDczIDMzIDI1IDMyIDQ2IDYxIDc3IDczIDM0IDVmIDcyIDY1IDcxIDc1IDY1IDczIDc0IDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQ0IDYxIDc0IDY1IDNkIDMyIDMwIDMyIDM1IDMwIDMzIDMzIDMxIDU0IDMyIDMwIDMzIDM3IDMzIDMzIDVhIDI2IDU4IDJkIDQxIDZkIDdhIDJkIDQ1IDc4IDcwIDY5IDcyIDY1IDczIDNkIDMzIDM2IDMwIDMwIDI2IDU4IDJkIDQxIDZkIDdhIDJkIDUzIDY5IDY3IDZlIDY1IDY0IDQ4IDY1IDYxIDY0IDY1IDcyIDczIDNkIDY4IDZmIDczIDc0IDI2IDc4IDJkIDY5IDY0IDNkIDQ3IDY1IDc0IDRmIDYyIDZhIDY1IDYzIDc0IDBhIDY4IDZmIDczIDc0IDNhIDY3IDZmIDJkIDYzIDZjIDZmIDc1IDY0IDJkIDc0IDY1IDczIDc0IDY5IDZlIDY3IDJkIDMyIDJlIDczIDMzIDJlIDc1IDczIDJkIDc3IDY1IDczIDc0IDJkIDMxIDJlIDYxIDZkIDYxIDdhIDZmIDZlIDYxIDc3IDczIDJlIDYzIDZmIDZkIDBhIDBhIDY4IDZmIDczIDc0IDBhIDU1IDRlIDUzIDQ5IDQ3IDRlIDQ1IDQ0IDJkIDUwIDQxIDU5IDRjIDRmIDQxIDQ0PC9DYW5vbmljYWxSZXF1ZXN0Qnl0ZXM+PFJlcXVlc3RJZD4xUkM4N1JEVkg4R0Y0U0ZSPC9SZXF1ZXN0SWQ+PEhvc3RJZD5KTSttWCtKTVZSakZxVmVRWEdScjNTWFVKSDMwSHFFVVJlNTVKa2t1VFJjSHBHSnMxaXlGR1U2N0NkZU1GOEJLNkRFMk9QU2xiL3BJMDhSdFlPelhOZz09PC9Ib3N0SWQ+PC9FcnJvcj4=" + } + }, + { + "ID": "187b10750823e2d2", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-signing?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Date=CLEARED\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 403, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:33 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "RCmNkpHzadHmHpZEMqgfZCNYi5KRD9IPktg5bqyxMWX9LjkQduztdN/uSLwTGD8m+sftR77L4bF7Wc93QqzFVw==" + ], + "X-Amz-Request-Id": [ + "1RC9898EX6H7XFAK" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPlNpZ25hdHVyZURvZXNOb3RNYXRjaDwvQ29kZT48TWVzc2FnZT5UaGUgcmVxdWVzdCBzaWduYXR1cmUgd2UgY2FsY3VsYXRlZCBkb2VzIG5vdCBtYXRjaCB0aGUgc2lnbmF0dXJlIHlvdSBwcm92aWRlZC4gQ2hlY2sgeW91ciBrZXkgYW5kIHNpZ25pbmcgbWV0aG9kLjwvTWVzc2FnZT48QVdTQWNjZXNzS2V5SWQ+QUtJQVdVV0VVU1BVTFlYM0JMM008L0FXU0FjY2Vzc0tleUlkPjxTdHJpbmdUb1NpZ24+QVdTNC1ITUFDLVNIQTI1NgoyMDI1MDMzMVQyMDM3MzNaCjIwMjUwMzMxL3VzLXdlc3QtMS9zMy9hd3M0X3JlcXVlc3QKZWU3ZDBjZWUyYmI1OTdkYjczOTQxZDNhZGYzZWNlYWZlZTdhNzAwYWYyMDQwZWZlOTc0NTE1NDc0YjY1MDc0ZjwvU3RyaW5nVG9TaWduPjxTaWduYXR1cmVQcm92aWRlZD5hYjJiNTZmMTU2MDVkN2JmODUyMDZhYjUyNGNmMTFjOWZlYmQ4MTZhNjlmYWEyM2U0NjY1NDNiM2UzMjBkOWVhPC9TaWduYXR1cmVQcm92aWRlZD48U3RyaW5nVG9TaWduQnl0ZXM+NDEgNTcgNTMgMzQgMmQgNDggNGQgNDEgNDMgMmQgNTMgNDggNDEgMzIgMzUgMzYgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgNTQgMzIgMzAgMzMgMzcgMzMgMzMgNWEgMGEgMzIgMzAgMzIgMzUgMzAgMzMgMzMgMzEgMmYgNzUgNzMgMmQgNzcgNjUgNzMgNzQgMmQgMzEgMmYgNzMgMzMgMmYgNjEgNzcgNzMgMzQgNWYgNzIgNjUgNzEgNzUgNjUgNzMgNzQgMGEgNjUgNjUgMzcgNjQgMzAgNjMgNjUgNjUgMzIgNjIgNjIgMzUgMzkgMzcgNjQgNjIgMzcgMzMgMzkgMzQgMzEgNjQgMzMgNjEgNjQgNjYgMzMgNjUgNjMgNjUgNjEgNjYgNjUgNjUgMzcgNjEgMzcgMzAgMzAgNjEgNjYgMzIgMzAgMzQgMzAgNjUgNjYgNjUgMzkgMzcgMzQgMzUgMzEgMzUgMzQgMzcgMzQgNjIgMzYgMzUgMzAgMzcgMzQgNjY8L1N0cmluZ1RvU2lnbkJ5dGVzPjxDYW5vbmljYWxSZXF1ZXN0PkRFTEVURQovYmxvYi1mb3Itc2lnbmluZwpYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZhbXA7WC1BbXotQ3JlZGVudGlhbD1BS0lBV1VXRVVTUFVMWVgzQkwzTSUyRjIwMjUwMzMxJTJGdXMtd2VzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmYW1wO1gtQW16LURhdGU9MjAyNTAzMzFUMjAzNzMzWiZhbXA7WC1BbXotRXhwaXJlcz0zNjAwJmFtcDtYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYW1wO3gtaWQ9UHV0T2JqZWN0Cmhvc3Q6Z28tY2xvdWQtdGVzdGluZy0yLnMzLnVzLXdlc3QtMS5hbWF6b25hd3MuY29tCgpob3N0ClVOU0lHTkVELVBBWUxPQUQ8L0Nhbm9uaWNhbFJlcXVlc3Q+PENhbm9uaWNhbFJlcXVlc3RCeXRlcz40NCA0NSA0YyA0NSA1NCA0NSAwYSAyZiA2MiA2YyA2ZiA2MiAyZCA2NiA2ZiA3MiAyZCA3MyA2OSA2NyA2ZSA2OSA2ZSA2NyAwYSA1OCAyZCA0MSA2ZCA3YSAyZCA0MSA2YyA2NyA2ZiA3MiA2OSA3NCA2OCA2ZCAzZCA0MSA1NyA1MyAzNCAyZCA0OCA0ZCA0MSA0MyAyZCA1MyA0OCA0MSAzMiAzNSAzNiAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0MyA3MiA2NSA2NCA2NSA2ZSA3NCA2OSA2MSA2YyAzZCA0MSA0YiA0OSA0MSA1NyA1NSA1NyA0NSA1NSA1MyA1MCA1NSA0YyA1OSA1OCAzMyA0MiA0YyAzMyA0ZCAyNSAzMiA0NiAzMiAzMCAzMiAzNSAzMCAzMyAzMyAzMSAyNSAzMiA0NiA3NSA3MyAyZCA3NyA2NSA3MyA3NCAyZCAzMSAyNSAzMiA0NiA3MyAzMyAyNSAzMiA0NiA2MSA3NyA3MyAzNCA1ZiA3MiA2NSA3MSA3NSA2NSA3MyA3NCAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0NCA2MSA3NCA2NSAzZCAzMiAzMCAzMiAzNSAzMCAzMyAzMyAzMSA1NCAzMiAzMCAzMyAzNyAzMyAzMyA1YSAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA0NSA3OCA3MCA2OSA3MiA2NSA3MyAzZCAzMyAzNiAzMCAzMCAyNiA1OCAyZCA0MSA2ZCA3YSAyZCA1MyA2OSA2NyA2ZSA2NSA2NCA0OCA2NSA2MSA2NCA2NSA3MiA3MyAzZCA2OCA2ZiA3MyA3NCAyNiA3OCAyZCA2OSA2NCAzZCA1MCA3NSA3NCA0ZiA2MiA2YSA2NSA2MyA3NCAwYSA2OCA2ZiA3MyA3NCAzYSA2NyA2ZiAyZCA2MyA2YyA2ZiA3NSA2NCAyZCA3NCA2NSA3MyA3NCA2OSA2ZSA2NyAyZCAzMiAyZSA3MyAzMyAyZSA3NSA3MyAyZCA3NyA2NSA3MyA3NCAyZCAzMSAyZSA2MSA2ZCA2MSA3YSA2ZiA2ZSA2MSA3NyA3MyAyZSA2MyA2ZiA2ZCAwYSAwYSA2OCA2ZiA3MyA3NCAwYSA1NSA0ZSA1MyA0OSA0NyA0ZSA0NSA0NCAyZCA1MCA0MSA1OSA0YyA0ZiA0MSA0NDwvQ2Fub25pY2FsUmVxdWVzdEJ5dGVzPjxSZXF1ZXN0SWQ+MVJDOTg5OEVYNkg3WEZBSzwvUmVxdWVzdElkPjxIb3N0SWQ+UkNtTmtwSHphZEhtSHBaRU1xZ2ZaQ05ZaTVLUkQ5SVBrdGc1YnF5eE1XWDlMamtRZHV6dGROL3VTTHdUR0Q4bStzZnRSNzdMNGJGN1djOTNRcXpGVnc9PTwvSG9zdElkPjwvRXJyb3I+" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestUploadDownload.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestUploadDownload.replay new file mode 100644 index 000000000..6681c9f1f --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestUploadDownload.replay @@ -0,0 +1,464 @@ +{ + "Initial": "AQAAAA7ffPQDNieq/QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "169feb2625c14e7f", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text", + "BodyParts": [ + "Yg0KdXAgYW5kIGRvd24NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk9KM3lsQT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OJ3ylA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "uVI93+PszCcaaGZoIUNsR0hoPw/7q2eoLk8rQQwrLF42w1QHWfB5F0zVHC+tv0jw5u94/r8WzpPdxDmb8auJ2w==" + ], + "X-Amz-Request-Id": [ + "YTBG9AV9556P4FB7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "9b72b96341aac5b5", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:24 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OJ3ylA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ABZazT70SFBdMUjj1R1CZE2Y/hmb3rcAGNE/LKeuqHaSI7H4DCjLXypO3BQ78gn5+BjxnbghTq0jY+l7j+ZoSQ==" + ], + "X-Amz-Request-Id": [ + "6PM8FE50Q6CCSE9G" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "dXAgYW5kIGRvd24=" + } + }, + { + "ID": "06f644859b75e3d4", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "G3VTPtWoaf9vOuAzbQwzIA==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text", + "BodyParts": [ + "Yg0KdXAgYW5kIGRvd24NCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOk9KM3lsQT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "OJ3ylA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "4YGYOETO+B3rtedUOZVlyxdq7NtZgZefy0PpWCFxZvlX+sEdV53JuRm+VFCfxzYd0FXNYGUq/8EZAPi2wJukFQ==" + ], + "X-Amz-Request-Id": [ + "6PMB9XN0NZM7ZFS8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "aff759a59010eaab", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Etag": [ + "\"1b75533ed5a869ff6f3ae0336d0c3320\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Pi/rgejcOEja05550XCjqX06ibEHgojK8PP1J+4QY7ILAAxLtCv9oS1bw6efKXoHGfWSpGBnyGKBcI8oE76cKA==" + ], + "X-Amz-Request-Id": [ + "6PMEM47SBZX1418R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a7a60c5bf9644cba", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:25 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "2SiAfaRAQ4D+tJe0nxRq2El7mPq3qb9h1ueDajINibFS/VZVnwp9iB4qYlLW1aUWOfa/dRz6Dg+p5scwi4rnig==" + ], + "X-Amz-Request-Id": [ + "6PM38E0HHGFV5M2D" + ] + }, + "Body": "" + } + }, + { + "ID": "8b546feb8a971ad9", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-upload-download", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:23 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "o6LilkTqiHxyzi9L4p/jAmUNY03aQ/HmD1BAE71EQ9I3AnPv+XIkPa9i8BLo70cDNgkPjxsRcEElYldTR/QWPA==" + ], + "X-Amz-Request-Id": [ + "6PM5SGKKP5F5HBQX" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/ContentType_is_discovered_if_not_provided.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/ContentType_is_discovered_if_not_provided.replay new file mode 100644 index 000000000..c849e4241 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/ContentType_is_discovered_if_not_provided.replay @@ -0,0 +1,397 @@ +{ + "Initial": "AQAAAA7ffPP/NN0DmQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "c29a8ffb4587a556", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "6398" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "6354" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/html", + "BodyParts": [ + "MThkMg0KPCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+DQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjplQ01DcWc9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "EwR266R3rFhtnNpmscgx0geVj3jlTTnAbrKPjDvaj3TcuKc91tuU915Bv+Iu++/tyGWAlpSxqGs=" + ], + "X-Amz-Request-Id": [ + "3XSB1NTHTMAC52GJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "b2a57c0588672b68", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "text/html; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "DhI5RL7hOK/VzzicyOw4X7L6QaSreWD8Cuv4sN3Sa9os2ctnsNfxRKBqPFFQfbORFhgFPKnqGJE=" + ], + "X-Amz-Request-Id": [ + "3XSA3SA8VC28HKF2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "10444e49e1de57dd", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "text/html; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "yHqBi91BmmX5FYZGQPPPJeVO2mAAKMD4dSuRXYWCaQclgqPKTILNMtlpAC7Dxt8kQAycD/iGbOw=" + ], + "X-Amz-Request-Id": [ + "5852YTB604HEDBRV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "2b3d8882a3413560", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "text/html; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rqSn1NkeOyyf23SXt76K6LlV+qu3/xay8MsaPHOUcZxvMFXAqpi4gn0GNZS9fPwBIISTQ31e4gc=" + ], + "X-Amz-Request-Id": [ + "585CX2T60TY2ZGJV" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "d98246b7c9deb96e", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "jkf14HACkjQDjtNxqPXcyXYABB8jIq7qatnia7/y2hhUVlvGPEIiW4GmQlzhQEr0wGzH+dbwES4=" + ], + "X-Amz-Request-Id": [ + "585E682YJ8MQX182" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay new file mode 100644 index 000000000..39109440b --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/ContentType_is_left_empty_if_not_provided_and_DisableContentTypeDetection_is_true.replay @@ -0,0 +1,327 @@ +{ + "Initial": "AQAAAA7ffPQABm32mQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "e8fe117c52570b23", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "6398" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "6354" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "", + "BodyParts": [ + "MThkMg0KPCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+DQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjplQ01DcWc9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "wpUkPzuR/qrpkkvlfu+qoT+zYiHK+6ScklsdBcynMOiGtr55unNei2+akAB5hiWqP341IKjV7I0=" + ], + "X-Amz-Request-Id": [ + "58500E4F2Q0DPNTM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "1ffda327e9b8b2ed", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "rH1oVrCbbeja6wT38Xcequ1OYJzQXE+nXMqK9ZiSZa7M7/JUPWtRt+EtktlBk/L7EK49h8+C70k=" + ], + "X-Amz-Request-Id": [ + "5856A2WFAS90ZJY2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "36f6b07b7f8c1292", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "JIkWaXN5jC8NTAj7uDyQN9n/dHGUz1RAfIBcY/y7ToZq71RriXw4yNEmg0dola4Qk9tuxkmfMrM=" + ], + "X-Amz-Request-Id": [ + "5854FTJDEMCPCR4N" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "8c95d361c11a8507", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "wDuQk8SLkhVg3MT1QWShHJVP4BNNZS8NJLlOWc14WcjB/DpgMJxevpJgFQY6sue5+lhCjwpvumE=" + ], + "X-Amz-Request-Id": [ + "5851DXHWN4AD435P" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/Content_md5_did_not_match,_blob_existed.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/Content_md5_did_not_match,_blob_existed.replay new file mode 100644 index 000000000..8381e4e47 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/Content_md5_did_not_match,_blob_existed.replay @@ -0,0 +1,330 @@ +{ + "Initial": "AQAAAA7ffPQAMFpyJQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "762ee6296adac29c", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "58" + ], + "Content-Md5": [ + "dH9B/ScP7BuCvgMMwc1IAQ==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "16" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTANCmV4aXN0aW5nIGNvbnRlbnQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOkl1VXExUT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"747f41fd270fec1b82be030cc1cd4801\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "IuUq1Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "6licAfAinMuYNaE3+ll0TEQOvcKkSQMs1dk2+wUQ6PanU/gYH8OzL4UXmbmYaqBRsh0KIbGY7ub6aLBOz/EWHQ==" + ], + "X-Amz-Request-Id": [ + "5851FS42MNG8DG21" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "072f5b58c45cc6d1", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "16" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"747f41fd270fec1b82be030cc1cd4801\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "IuUq1Q==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "62IJhy2WmqiZCNy03rLqsZP8zTfoByGJHfHkj/tt83RDXMZzDk3PPLj9VndXX+OW5YHQDoEMcpEpKrg8zEpTQA==" + ], + "X-Amz-Request-Id": [ + "585A3523GDSXTSFW" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "ZXhpc3RpbmcgY29udGVudA==" + } + }, + { + "ID": "fb8c498f83c66151", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "16" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"747f41fd270fec1b82be030cc1cd4801\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "07DDAj/oPKr4PjCJy5kPWk0TOEIM0ryrNzzWYtyPPR0XKaWv8UBRqlFrvEtAoOK97BLuWfvn1oZcFlIdWZMw6A==" + ], + "X-Amz-Request-Id": [ + "585F1D58D0YSBFM2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "fa286e9a7bae95ca", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "J32lntICliFpXER+lK6Dbp52jkjG+LT3mRUcUsn2ylYZmjlNPNIqDn8BMBIKQppNfs6+HRYJgwY4XGuPTvDQMA==" + ], + "X-Amz-Request-Id": [ + "5857X7B0BCKK29YY" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/Content_md5_did_not_match.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/Content_md5_did_not_match.replay new file mode 100644 index 000000000..61f803448 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/Content_md5_did_not_match.replay @@ -0,0 +1,105 @@ +{ + "Initial": "AQAAAA7ffPQAK4bgqAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "1107ac199ed0eec9", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "trP71v4KVFBsCkeE1d+4mwPIJZmEDk0JOUnHElsJQLPRkxFoUNeeqpZbO/9PuYfS19xHA48qId3rhKdHoyHVGA==" + ], + "X-Amz-Request-Id": [ + "585CXDV4JNP3SQH8" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1yZWFkaW5nPC9LZXk+PFJlcXVlc3RJZD41ODVDWERWNEpOUDNTUUg4PC9SZXF1ZXN0SWQ+PEhvc3RJZD50clA3MXY0S1ZGQnNDa2VFMWQrNG13UElKWm1FRGswSk9VbkhFbHNKUUxQUmt4Rm9VTmVlcXBaYk8vOVB1WWZTMTl4SEE0OHFJZDNyaEtkSG95SFZHQT09PC9Ib3N0SWQ+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/Content_md5_match.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/Content_md5_match.replay new file mode 100644 index 000000000..fc6b24caa --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/Content_md5_match.replay @@ -0,0 +1,330 @@ +{ + "Initial": "AQAAAA7ffPQAIIyGsAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "28c96e56da81f17d", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "52" + ], + "Content-Md5": [ + "XrY7u+Ae7tCTyyK7j1rNww==" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "11" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "Yg0KaGVsbG8gd29ybGQNCjANCngtYW16LWNoZWNrc3VtLWNyYzMyOkRVb1JoUT09DQoNCg==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "gq4SQQ6u632Zba33DsSGtpo78Cj29f7s8kwz1yClfWKQ3j/f/H1eOUSn6YKl3yrsfxI3AWp5kdY=" + ], + "X-Amz-Request-Id": [ + "58574P85KCNSKYX4" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "942abb59f4b10475", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "DUoRhQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "InNz6CC997NrKl62hCgmhc0VVJRqE+OqwzCrRricxIX91SPoRMmjXB7w3bjLb+/ag3RVE5C+tUc=" + ], + "X-Amz-Request-Id": [ + "58547MPWYQ9CGFMY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "aGVsbG8gd29ybGQ=" + } + }, + { + "ID": "d19ce44cc7a7929f", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "11" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"5eb63bbbe01eeed093cb22bb8f5acdc3\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "FaWI/o+8MgtACdKJAZZmMCUEeKaW9VLMZ7xZTNAOkmQL6keDUJzQhXWUPC5wsr/2dMvyq9AaQQE=" + ], + "X-Amz-Request-Id": [ + "58550V4KGDSPZCG8" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "8295ca9ffe5e1939", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "qsiJOnT5tcQE+yBDCUPAO4eNSiOWYS1JTgr6orm30LXHfgcobkDJv41J7L19dmFMxFZr864T4xs=" + ], + "X-Amz-Request-Id": [ + "585AE2TDXMTGDHYD" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/a_large_jpg_file_gets_a_ContentType.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/a_large_jpg_file_gets_a_ContentType.replay new file mode 100644 index 000000000..81279ef6f --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/a_large_jpg_file_gets_a_ContentType.replay @@ -0,0 +1,397 @@ +{ + "Initial": "AQAAAA7ffPQBDRCdGQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "bd3ddae82450dbab", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "38474" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "38430" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "image/jpeg", + "BodyParts": [ + "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9HsyyadINQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//ZDQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjo4RGhML0E9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "8DhL/A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "tKuqXZjRrqntA7HdOO/07zWm+SlEhpjbBhs0X7rcyN78P1x8HRbxRxMZjRc0Y18CNg0ELNJBBsPv9mjQRYlmjuAU1GLYDH0OxipHT9C9lJo=" + ], + "X-Amz-Request-Id": [ + "TGVHQNA3YGEQ866T" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "cb6d12fe2cc7d19b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "8DhL/A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "OYxHOAkgPUMefUQSBY8A/ETjXWlnsXvIkMDk/LRPxmCwWI2P+08y54+EH7z/dygtl1JoHujvE+ry+eIBOdErMSDYwvj3V+cBmYiTadzn9W8=" + ], + "X-Amz-Request-Id": [ + "TGVX5JC23GCT9FQT" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + } + }, + { + "ID": "1c6b034e54cda7e9", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "Hp0QD8RjaM2nRaTUCrqiZVUNJY89C7cEhwjGrMl60Ve42LEFFV4qFYxDLOBY8pXfK2+3rbsWyi3dskCM6SOHVasjh7UdjLgdGPjW/arjJaM=" + ], + "X-Amz-Request-Id": [ + "TGVNRZ3XB6KYFTVQ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "d979fef7e45de60c", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "yasAktzGxzpCL/zeC9+5DubqhpRjPRsALuh64NV66Kwc2d//H8p34AbJe5gQcCoq5GYYUbLSv9FnUiBIZNE+kUy1+nApo7mPAAodz+vcObs=" + ], + "X-Amz-Request-Id": [ + "TGVGMQXCHV1MM427" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "c6d31e1b114c0261", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "oKRVTHl0OWx8RS2OhEPy1iCzMdTiJCBuUfjCFwTiZakOz+SKS7uuKJ4wcddQLw7JGPWtjr49VyOGGCMJIVPGyt+AYz/RYc28hj30ZSiniT4=" + ], + "X-Amz-Request-Id": [ + "TGVSR5SB31MWCXWT" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay new file mode 100644 index 000000000..36b82bf4d --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/a_large_jpg_file_written_in_two_chunks_gets_a_ContentType.replay @@ -0,0 +1,397 @@ +{ + "Initial": "AQAAAA7ffPQBKQb4kAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "e1848c0344b49145", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "38474" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "38430" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "image/jpeg", + "BodyParts": [ + "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9HsyyadINQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//ZDQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjo4RGhML0E9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "8DhL/A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "9rQv0+5K8kD3OQhvyjTLsX4SnHy+UObAFkFx7olpmai9+UrluWsWAqMiUkuzJvpXMfZ8mgPCo9sEBkk+DOTIVd3z2lsKFvkHTYLLRIpBdL0=" + ], + "X-Amz-Request-Id": [ + "TGVMGJ7FC6EN262X" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "81285063ddcd77df", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "8DhL/A==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "DrnNI9LizbhCeRB3DQyAI8eC11RGHXMAZpvwXJsT0KPxWt+t5ksUHTGq62w7yESbaYD0EIMrVoU1a0TcKo1ESo+KetwmIp0a9fR4BAVoV7g=" + ], + "X-Amz-Request-Id": [ + "TGVT72DTB67X3QZX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "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NQu4GCulv823Pv06iufTwprfjG5W58Q3MogJ3LaoNqICOAMEg/jXTaP8OdL0rGyEO3AJZF6D6D9a7K3sY4YgqggAYHtQBmaJ4fs9MiAgt40AGMquDW6IxwMUJGFGOcVJQA3aDTsUUUAFFFFABRRRQAUhGaWigBoQA5Ap1FFABRRRQAUCiigAooooAKKKKAAdKKKKACiiigAooooAKKKKACiiigAooooAKKKKACqOsI0mlXMaruLRsuMZ6j0q9TZF3IRQB5N8MtV8m1n06RGSWGZsfJtDDPXpivSJNSMcO5oyD7mvHPElmngbxu+pmCeSyuvmHlE4Ru4wBirt/wCNZvEMS6X4dtrl5Z12POQcRDHp60Ac5I7+Lvi7LeQITHbuqAhdwwvGa+h7ddsCA9QK4b4f+B/+Ecs/MnObmU7nAOQDXfAYFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAIRmloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBpUHtVdrRCc4HtVqigCi+nwsclAe4JFQvpFs64aFDnrkVpkUY6UAYf/COaeIti2cIUnLARjBP/wCupl0S0QkLbxjPXCjmtbAoxzQBSWxiRQAg4wOlWBbopGB0qUCloAjVMAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRSY96AFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCpf6baanavbXcKSwv95WHWqml+HNM0hStlaxxAnJ2jqa1qKAAADoKKKKACiiigAooooAKKKKACiiigAooooAKKTNLQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRQKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKO9FGOaACiiigAopAR0zzS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFGc0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFIeKKKAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKQnkCiigBaKKKACiiigAooooAKKKKACiiigAooooA//Z" + } + }, + { + "ID": "08bae2f61a72364e", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "WoUGjn/9C5FK0h5lBRKM4es1wh0zViJiMCUMqtw71AeyKEud1sTBqLk7afcbVJM128E5HYTh9wImaEDYBb5BnzyQJ3QiRNbvOtveG6qrsMo=" + ], + "X-Amz-Request-Id": [ + "TGVMCNWQZT1FQ5ZC" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "21156c7f1ff18d46", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "38430" + ], + "Content-Type": [ + "image/jpeg" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"62d43fa20e70bfa1fdb22510d1c060d2\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "GaLej+cbAHcNr57G0a6ahDQ3Szl4pl5KjSlJWHox2xaElur9Nhd8uAUCsdfu10bpTfy75zzT4nALaIDlaKDcCNFiphBvVXcqmFjU289PB5w=" + ], + "X-Amz-Request-Id": [ + "TGVV8X0FJ9Y2FN7M" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "967d8a3fd50899aa", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "+EsHLDHc+sx/ZFWYOTjYqH/1cCZPfKbWvs7xMaELsfRWFXw5ZKitUqTAbcF0Ehy0KnBD456Ab/QkG6ou7uwaybWWh/+VLlH+NtI50DYZEUc=" + ], + "X-Amz-Request-Id": [ + "TGVYSCDQC7DSW4PW" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/a_small_text_file_gets_a_ContentType.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/a_small_text_file_gets_a_ContentType.replay new file mode 100644 index 000000000..81d1eea7c --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/a_small_text_file_gets_a_ContentType.replay @@ -0,0 +1,397 @@ +{ + "Initial": "AQAAAA7ffPQAO3HqhwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "538ffa0c220adc87", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "62" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "20" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + "MTQNClRoaXMgaXMgYSB0ZXh0IGZpbGUuDQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjpzUURpRVE9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"3f3309312cc3264a1389b2d263dece8d\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "sQDiEQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "RM0mmAdd8kR+UjiNgOJL7VF2pSBgcBeoibwzl3sj6+ovg7SfpxnlvjKYree0sbO03bG56OPbfu4=" + ], + "X-Amz-Request-Id": [ + "TGVYC74TKGH42C8V" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "57d43ad1742bb7e4", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "20" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"3f3309312cc3264a1389b2d263dece8d\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "sQDiEQ==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "ISfI54gN6ft1nDT3DvRlHOds2siCqCBFtRbd/Md99+cgueuoQB/3Jfsa6wa+y5hupAcE2xV9MfQ=" + ], + "X-Amz-Request-Id": [ + "TGVY89CC2B367YSA" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "VGhpcyBpcyBhIHRleHQgZmlsZS4=" + } + }, + { + "ID": "cb039cf7cda10d36", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "20" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"3f3309312cc3264a1389b2d263dece8d\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "0RW6Q/qBBG4sXwgbbB6jw2GShO+82JSFvM0Umir2S6xPoJXm4oqeu0xfDvLpxuslXmtHZ3RvlCQ=" + ], + "X-Amz-Request-Id": [ + "TGVQ84QZT32P742R" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "bd9c6e97d6348fa0", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "20" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Etag": [ + "\"3f3309312cc3264a1389b2d263dece8d\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "reXRZKhqXNWL9vc49UnVwtsjmg27+N6ABYxElojqcI5qsg/f0vGHsNtttHLiSo9E73dcGIqRxS8=" + ], + "X-Amz-Request-Id": [ + "TGVWJEPBD4EN4FZ7" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0aa4876d74d5f114", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:22 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "5z/HFLVWUwZh1kYJLYjp6xXUldTmC25dn14OJIEQguCwxX6tc1PU/SSngfixC1pC0Ce/7FB6h5I=" + ], + "X-Amz-Request-Id": [ + "TGVGXPV8YB61FHRK" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/invalid_ContentType_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/invalid_ContentType_fails.replay new file mode 100644 index 000000000..5861bb001 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/invalid_ContentType_fails.replay @@ -0,0 +1,105 @@ +{ + "Initial": "AQAAAA7ffPP/MDhSQwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "bdfbadb68660c088", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Type": [ + "application/xml" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:18 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "b29fuksta7HpI++RLyAR2pJr8c5Ww/lhZ7MuKbuRvotXNYnjQOJ3JriNTwg60Ceafl5Uw7VZqUI=" + ], + "X-Amz-Request-Id": [ + "3XSFH0MATFJAZNDJ" + ] + }, + "Body": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEVycm9yPjxDb2RlPk5vU3VjaEtleTwvQ29kZT48TWVzc2FnZT5UaGUgc3BlY2lmaWVkIGtleSBkb2VzIG5vdCBleGlzdC48L01lc3NhZ2U+PEtleT5ibG9iLWZvci1yZWFkaW5nPC9LZXk+PFJlcXVlc3RJZD4zWFNGSDBNQVRGSkFaTkRKPC9SZXF1ZXN0SWQ+PEhvc3RJZD5iMjlmdWtzdGE3SHBJKytSTHlBUjJwSnI4YzVXdy9saFo3TXVLYnVSdm90WE5ZbmpRT0ozSnJpTlR3ZzYwQ2VhZmw1VXc3VlpxVUk9PC9Ib3N0SWQ+PC9FcnJvcj4=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay new file mode 100644 index 000000000..c39806a6a --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/no_write_then_close_results_in_empty_blob,_blob_existed.replay @@ -0,0 +1,321 @@ +{ + "Initial": "AQAAAA7ffPP/JPxXPgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "0eccf3b25395cce6", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Content-Sha256": [ + "UNSIGNED-PAYLOAD" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "PKxRjFhTaxCyE322Cywk5Dc5NnWRYmcQ9hJr7tw1v7AubD0JSBD0fhGITDYuydxJ9h5pRkDcF3Y=" + ], + "X-Amz-Request-Id": [ + "3XS86WED6XSG28HB" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "af4617c5f0569fba", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "6ip5/Y0OmJCRQvf7XffBMD911wKbL++ayDzxB9dllkaVHLmkVRSWAwQ3AKR8xEuD87hpqBJBmrM=" + ], + "X-Amz-Request-Id": [ + "3XSBD9BDDJHZMHN2" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "7765d778c1096ed8", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "HAOkljmJ9RDoWXW4Bao3RDsEfsm8cGlYrfMbPelgoVGhbajn6NamcrCHcC9gQoJZPlxpisnXlVA=" + ], + "X-Amz-Request-Id": [ + "3XS3QW1DKAJW94BH" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "53dcd258cf6d1dc7", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "rxobJxVmcFOa6zkXXAFduQjo8WAXxAKrJ8KQeZXbd0DLo75KY/8yg1AWVLYYV+PdCH70MozsgL4=" + ], + "X-Amz-Request-Id": [ + "3XS223TV4648CPEH" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/no_write_then_close_results_in_empty_blob.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/no_write_then_close_results_in_empty_blob.replay new file mode 100644 index 000000000..d46c7b206 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/no_write_then_close_results_in_empty_blob.replay @@ -0,0 +1,321 @@ +{ + "Initial": "AQAAAA7ffPP/GlToGgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "4ecdbae895c3bfc5", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Content-Sha256": [ + "UNSIGNED-PAYLOAD" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "text/plain", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "f+Wf65a4aQrgBUJngpUNRwx+Ox8MD3UL7xSDPvMaEdxMi+jezFsNj2b8zcFIqcU4yModCqjo8rrkZIvhGonzkQ==" + ], + "X-Amz-Request-Id": [ + "3XSAZDZ9MSYZ7XF1" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "a6e7f771279bae6b", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "AAAAAA==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "IBLSMnhwMkIi65pTRY96jkil0eBTR+PZXv74Q4tcsYyBxICV7LeUdIQ5u/DqZMhZBaY331kbM1uT/mnLTe6IsA==" + ], + "X-Amz-Request-Id": [ + "3XS3V9WN6RCJM0WJ" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "02b66dde5e918f10", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "0" + ], + "Content-Type": [ + "text/plain; charset=utf-8" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Etag": [ + "\"d41d8cd98f00b204e9800998ecf8427e\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "HgHbyOBpYmcO4XGtjPQGkZsnyd6AhvVjarluaKIeivWPsVr95miniQa5aMEP0YlsGWkOxFY7oWd0wVPrLJtELA==" + ], + "X-Amz-Request-Id": [ + "3XSBMGJN8D7NYKXT" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "169bc4f3dba23ceb", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:20 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "lodwrr0d5pQM4PhNZkcP77ygyJ0nWwGaNsMn2lZqhvjYp/YhBKXJUn3QomHLf0MpU+Iex4H5m4oPJDca5S9oNA==" + ], + "X-Amz-Request-Id": [ + "3XS8NVNK8R0N8DMS" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/write_to_empty_key_fails.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/write_to_empty_key_fails.replay new file mode 100644 index 000000000..8b9fe9643 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/write_to_empty_key_fails.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPP/Gj5bmwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay new file mode 100644 index 000000000..c987212ca --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestConformanceUsingLegacyList/TestWrite/write_with_explicit_ContentType_overrides_discovery.replay @@ -0,0 +1,397 @@ +{ + "Initial": "AQAAAA7ffPQAEZCIRQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "3b130910c62fc28a", + "Request": { + "Method": "PUT", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=PutObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Encoding": [ + "aws-chunked" + ], + "Content-Length": [ + "6398" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "STREAMING-UNSIGNED-PAYLOAD-TRAILER" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Decoded-Content-Length": [ + "6354" + ], + "X-Amz-Trailer": [ + "x-amz-checksum-crc32" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "MThkMg0KPCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+DQowDQp4LWFtei1jaGVja3N1bS1jcmMzMjplQ01DcWc9PQ0KDQo=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "W4nwMPt4/Nh9mx4b4gmCuEs1B8quqMxqbpRBTntTTyMd7pEfKfV2pE9yuq8sx5h1gEQTT80aNl3QTcfiKG4MtA==" + ], + "X-Amz-Request-Id": [ + "585FA6ZYB2BW3BPY" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "64ab95edec1da829", + "Request": { + "Method": "GET", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=GetObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Checksum-Mode": [ + "ENABLED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Checksum-Crc32": [ + "eCMCqg==" + ], + "X-Amz-Checksum-Type": [ + "FULL_OBJECT" + ], + "X-Amz-Id-2": [ + "hA4tU8Vnw2dyUOnpTEzgmdkz7G0JE1jSBmGvOke/opaSqxjts6WtNHHC9y4q6ig+bQ+Flxr5638NTiMUNA868w==" + ], + "X-Amz-Request-Id": [ + "5858AFPDEWZX2KAM" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "PCFET0NUWVBFIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgo8aGVhZCBwcm9maWxlPSJodHRwOi8vYTkuY29tLy0vc3BlYy9vcGVuc2VhcmNoLzEuMS8iPgogIDxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CiAgPGxpbmsgaHJlZj0iLy0vYm9vdHN0cmFwLm1pbi5jc3M/dj04YmVjMWJiYTNlMjNlY2JhMjJjZmZiMTk3YTJkNDQwYWY0MTBiMTVkIiByZWw9InN0eWxlc2hlZXQiPgogIDxsaW5rIGhyZWY9Ii8tL3NpdGUuY3NzP3Y9N2Q4MWY0MTA0Yzg5ZGJlMzc2MzQ1ZjZiZmUzZTYyYjRlNDBkM2QwNiIgcmVsPSJzdHlsZXNoZWV0Ij4KICA8dGl0bGU+R29Eb2M8L3RpdGxlPgo8L2hlYWQ+Cjxib2R5Pgo8bmF2IGNsYXNzPSJuYXZiYXIgbmF2YmFyLWRlZmF1bHQiIHJvbGU9Im5hdmlnYXRpb24iPgogIDxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgPGRpdiBjbGFzcz0ibmF2YmFyLWhlYWRlciI+CiAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9Im5hdmJhci10b2dnbGUiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9Ii5uYXZiYXItY29sbGFwc2UiPgogICAgICA8c3BhbiBjbGFzcz0ic3Itb25seSI+VG9nZ2xlIG5hdmlnYXRpb248L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJpY29uLWJhciI+PC9zcGFuPgogICAgICA8c3BhbiBjbGFzcz0iaWNvbi1iYXIiPjwvc3Bhbj4KICAgICAgPHNwYW4gY2xhc3M9Imljb24tYmFyIj48L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxhIGNsYXNzPSJuYXZiYXItYnJhbmQiIGhyZWY9Ii8iPjxzdHJvbmc+R29Eb2M8L3N0cm9uZz48L2E+CiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sbGFwc2UgbmF2YmFyLWNvbGxhcHNlIj4KICAgIDx1bCBjbGFzcz0ibmF2IG5hdmJhci1uYXYiPgogICAgICAgIDxsaSBjbGFzcz0iYWN0aXZlIj48YSBocmVmPSIvIj5Ib21lPC9hPjwvbGk+CiAgICAgICAgPGxpPjxhIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dDwvYT48L2xpPgogICAgPC91bD4KICAgIDxmb3JtIGNsYXNzPSJuYXZiYXItbmF2IG5hdmJhci1mb3JtIG5hdmJhci1yaWdodCIgaWQ9Ingtc2VhcmNoIiBhY3Rpb249Ii8iIHJvbGU9InNlYXJjaCI+PGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIGlkPSJ4LXNlYXJjaC1xdWVyeSIgdHlwZT0idGV4dCIgbmFtZT0icSIgcGxhY2Vob2xkZXI9IlNlYXJjaCI+PC9mb3JtPgogIDwvZGl2Pgo8L2Rpdj4KPC9uYXY+CjxkaXYgY2xhc3M9ImNvbnRhaW5lciI+CiAgCjxkaXYgY2xhc3M9Imp1bWJvdHJvbiI+CiAgICA8aDI+U2VhcmNoIGZvciBHbyBQYWNrYWdlczwvaDI+CiAgICAKICA8Zm9ybT4KICAgIDxkaXYgY2xhc3M9ImlucHV0LWdyb3VwIj4KICAgICAgPGlucHV0IGNsYXNzPSJmb3JtLWNvbnRyb2wiIG5hbWU9InEiIGF1dG9mb2N1cz0iYXV0b2ZvY3VzIiB2YWx1ZT0iIiBwbGFjZWhvbGRlcj0iU2VhcmNoIGZvciBwYWNrYWdlIGJ5IGltcG9ydCBwYXRoIG9yIGtleXdvcmQuIiB0eXBlPSJ0ZXh0Ij4KICAgICAgPHNwYW4gY2xhc3M9ImlucHV0LWdyb3VwLWJ0biI+CiAgICAgICAgPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1kZWZhdWx0IiB0eXBlPSJzdWJtaXQiPkdvITwvYnV0dG9uPgogICAgICA8L3NwYW4+CiAgICA8L2Rpdj4KICA8L2Zvcm0+Cgo8L2Rpdj4KCjxwPkdvRG9jIGhvc3RzIGRvY3VtZW50YXRpb24gZm9yIDxhIGhyZWY9Imh0dHA6Ly9nb2xhbmcub3JnLyI+R288L2E+IHBhY2thZ2VzCm9uIEJpdGJ1Y2tldCwgR2l0SHViLCBHb29nbGUgUHJvamVjdCBIb3N0aW5nIGFuZCBMYXVuY2hwYWQuICBSZWFkIHRoZSA8YQogIGhyZWY9Ii8tL2Fib3V0Ij5BYm91dCBQYWdlPC9hPiBmb3IgaW5mb3JtYXRpb24gYWJvdXQgYWRkaW5nIHBhY2thZ2VzIHRvIEdvRG9jCmFuZCBtb3JlLgoKPGRpdiBjbGFzcz0icm93Ij4KICA8ZGl2IGNsYXNzPSJjb2wtc20tNiI+CiAgICAKICAgICAgPGg0PlBvcHVsYXIgUGFja2FnZXM8L2g0PgogICAgICA8dWwgY2xhc3M9Imxpc3QtdW5zdHlsZWQiPgogICAgICAgIDxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9hd3MvYXdzLXNkay1nby9hd3MiPmdpdGh1Yi5jb20vYXdzL2F3cy1zZGstZ28vYXdzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9kZ3JpamFsdmEvand0LWdvIj5naXRodWIuY29tL2RncmlqYWx2YS9qd3QtZ288L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dpbi1nb25pYy9naW4iPmdpdGh1Yi5jb20vZ2luLWdvbmljL2dpbjwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXMiPmdpdGh1Yi5jb20vZ28tcmVkaXMvcmVkaXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2dvLXNxbC1kcml2ZXIvbXlzcWwiPmdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbDwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvIj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90bzwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29tb2R1bGUvcmVkaWdvL3JlZGlzIj5naXRodWIuY29tL2dvbW9kdWxlL3JlZGlnby9yZWRpczwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiPmdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQ8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltIj5naXRodWIuY29tL2h5cGVybGVkZ2VyL2ZhYnJpYy9jb3JlL2NoYWluY29kZS9zaGltPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9qaW56aHUvZ29ybSI+Z2l0aHViLmNvbS9qaW56aHUvZ29ybTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vbGliL3BxIj5naXRodWIuY29tL2xpYi9wcTwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcGtnL2Vycm9ycyI+Z2l0aHViLmNvbS9wa2cvZXJyb3JzPC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1cyI+Z2l0aHViLmNvbS9wcm9tZXRoZXVzL2NsaWVudF9nb2xhbmcvcHJvbWV0aGV1czwvYT48bGk+PGEgaHJlZj0iL2dpdGh1Yi5jb20vcm9iZmlnL2Nyb24iPmdpdGh1Yi5jb20vcm9iZmlnL2Nyb248L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3NpcnVwc2VuL2xvZ3J1cyI+Z2l0aHViLmNvbS9zaXJ1cHNlbi9sb2dydXM8L2E+PGxpPjxhIGhyZWY9Ii9naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0Ij5naXRodWIuY29tL3N0cmV0Y2hyL3Rlc3RpZnkvYXNzZXJ0PC9hPjxsaT48YSBocmVmPSIvZ2l0aHViLmNvbS91bml4cGlja2xlL2thaG9vdC1oYWNrIj5naXRodWIuY29tL3VuaXhwaWNrbGUva2Fob290LWhhY2s8L2E+PGxpPjxhIGhyZWY9Ii9nby51YmVyLm9yZy96YXAiPmdvLnViZXIub3JnL3phcDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9jcnlwdG8vc3NoIj5nb2xhbmcub3JnL3gvY3J5cHRvL3NzaDwvYT48bGk+PGEgaHJlZj0iL2dvbGFuZy5vcmcveC9uZXQvY29udGV4dCI+Z29sYW5nLm9yZy94L25ldC9jb250ZXh0PC9hPjxsaT48YSBocmVmPSIvZ29sYW5nLm9yZy94L29hdXRoMiI+Z29sYW5nLm9yZy94L29hdXRoMjwvYT48bGk+PGEgaHJlZj0iL2dvb2dsZS5nb2xhbmcub3JnL2dycGMiPmdvb2dsZS5nb2xhbmcub3JnL2dycGM8L2E+PGxpPjxhIGhyZWY9Ii9nb3BrZy5pbi9tZ28udjIiPmdvcGtnLmluL21nby52MjwvYT48bGk+PGEgaHJlZj0iL2dvcGtnLmluL3lhbWwudjIiPmdvcGtnLmluL3lhbWwudjI8L2E+PGxpPjxhIGhyZWY9Ii9sYWJpeC5vcmcvdjIvbWdvIj5sYWJpeC5vcmcvdjIvbWdvPC9hPgogICAgICA8L3VsPgogICAgCiAgPC9kaXY+CiAgPGRpdiBjbGFzcz0iY29sLXNtLTYiPgogICAgPGg0Pk1vcmUgUGFja2FnZXM8L2g0PgogICAgPHVsIGNsYXNzPSJsaXN0LXVuc3R5bGVkIj4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL2dvIj5HbyBTdGFuZGFyZCBQYWNrYWdlczwvYT4KICAgICAgPGxpPjxhIGhyZWY9Ii8tL3N1YnJlcG8iPkdvIFN1Yi1yZXBvc2l0b3J5IFBhY2thZ2VzPC9hPgogICAgICA8bGk+PGEgaHJlZj0iaHR0cHM6Ly9nb2xhbmcub3JnL3dpa2kvUHJvamVjdHMiPlByb2plY3RzIEAgZ28td2lraTwvYT4KICAgICAgPGxpPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9zZWFyY2g/bz1kZXNjJmFtcDtxPWxhbmd1YWdlJTNBZ28mYW1wO3M9c3RhcnMmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5Nb3N0IHN0YXJzPC9hPiwgCiAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9vPWRlc2MmYW1wO3E9bGFuZ3VhZ2UlM0FnbyZhbXA7cz1mb3JrcyZhbXA7dHlwZT1SZXBvc2l0b3JpZXMiPm1vc3QgZm9ya3M8L2E+LCAKICAgICAgICA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vc2VhcmNoP289ZGVzYyZhbXA7cT1sYW5ndWFnZSUzQWdvJmFtcDtzPXVwZGF0ZWQmYW1wO3R5cGU9UmVwb3NpdG9yaWVzIj5yZWNlbnRseSB1cGRhdGVkPC9hPiBvbiBHaXRIdWIKICAgIDwvdWw+CiAgPC9kaXY+CjwvZGl2PgoKCjwvZGl2Pgo8ZGl2IGlkPSJ4LWZvb3RlciIgY2xhc3M9ImNsZWFyZml4Ij4KICA8ZGl2IGNsYXNzPSJjb250YWluZXIiPgogICAgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2dvbGFuZy9nZGRvL2lzc3VlcyI+V2Vic2l0ZSBJc3N1ZXM8L2E+CiAgICA8c3BhbiBjbGFzcz0idGV4dC1tdXRlZCI+fDwvc3Bhbj4gPGEgaHJlZj0iaHR0cDovL2dvbGFuZy5vcmcvIj5HbyBMYW5ndWFnZTwvYT4KICAgIDxzcGFuIGNsYXNzPSJwdWxsLXJpZ2h0Ij48YSBocmVmPSIjIj5CYWNrIHRvIHRvcDwvYT48L3NwYW4+CiAgPC9kaXY+CjwvZGl2PgoKPGRpdiBpZD0ieC1zaG9ydGN1dHMiIHRhYmluZGV4PSItMSIgY2xhc3M9Im1vZGFsIj4KICAgIDxkaXYgY2xhc3M9Im1vZGFsLWRpYWxvZyI+CiAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWNvbnRlbnQiPgogICAgICAgIDxkaXYgY2xhc3M9Im1vZGFsLWhlYWRlciI+CiAgICAgICAgICA8YnV0dG9uIHR5cGU9ImJ1dHRvbiIgY2xhc3M9ImNsb3NlIiBkYXRhLWRpc21pc3M9Im1vZGFsIiBhcmlhLWhpZGRlbj0idHJ1ZSI+JnRpbWVzOzwvYnV0dG9uPgogICAgICAgICAgPGg0IGNsYXNzPSJtb2RhbC10aXRsZSI+S2V5Ym9hcmQgc2hvcnRjdXRzPC9oND4KICAgICAgICA8L2Rpdj4KICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgIDx0YWJsZT4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4/PC9iPjwvdGQ+PHRkPiA6IFRoaXMgbWVudTwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj4vPC9iPjwvdGQ+PHRkPiA6IFNlYXJjaCBzaXRlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5mPC9iPjwvdGQ+PHRkPiA6IEp1bXAgdG8gaWRlbnRpZmllcjwvdGQ+PC90cj4KICAgICAgICAgIDx0cj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmc8L2I+PC90ZD48dGQ+IDogR28gdG8gdG9wIG9mIHBhZ2U8L3RkPjwvdHI+CiAgICAgICAgICA8dHI+PHRkIGFsaWduPSJyaWdodCI+PGI+ZzwvYj4gdGhlbiA8Yj5iPC9iPjwvdGQ+PHRkPiA6IEdvIHRvIGVuZCBvZiBwYWdlPC90ZD48L3RyPgogICAgICAgICAgPHRyIGNsYXNzPSJ0ZXh0LW11dGVkIj48dGQgYWxpZ249InJpZ2h0Ij48Yj5nPC9iPiB0aGVuIDxiPmk8L2I+PC90ZD48dGQ+IDogR28gdG8gaW5kZXg8L3RkPjwvdHI+CiAgICAgICAgICA8dHIgY2xhc3M9InRleHQtbXV0ZWQiPjx0ZCBhbGlnbj0icmlnaHQiPjxiPmc8L2I+IHRoZW4gPGI+ZTwvYj48L3RkPjx0ZD4gOiBHbyB0byBleGFtcGxlczwvdGQ+PC90cj4KICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibW9kYWwtZm9vdGVyIj4KICAgICAgICAgIDxidXR0b24gdHlwZT0iYnV0dG9uIiBjbGFzcz0iYnRuIiBkYXRhLWRpc21pc3M9Im1vZGFsIj5DbG9zZTwvYnV0dG9uPgogICAgICA8L2Rpdj4KICAgIDwvZGl2PgogIDwvZGl2Pgo8L2Rpdj4KPHNjcmlwdCBzcmM9Ii8tL2pxdWVyeS0yLjAuMy5taW4uanM/dj1mYmY5Yzc3ZDBjNGUzYzM0YTQ4NTk4MGMxZTUzMTZiNjIxMjE2MGM4Ij48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL2Jvb3RzdHJhcC5taW4uanM/dj01YWRhN2MxMDNmYzFkZWFiYzkyNWNjMWZkYmJiNmU0NTFjMjFmYzcwIj48L3NjcmlwdD4KPHNjcmlwdCBzcmM9Ii8tL3NpdGUuanM/dj0zNzFkZTczMWMxOGQ5MWM0OTlkOTBiMWFiMGJmMzllY2Y2NmQ2Y2Y3Ij48L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+" + } + }, + { + "ID": "92613e947a62f33e", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "3zx40ZjMEUiuW2dmVHIPPNX8bKpke1BaJDOcGjGHQPdhX/UBbnMcgrYC86VAlH5vvk/otzJ/Ucld3UQO7VxJHQ==" + ], + "X-Amz-Request-Id": [ + "585D7A217SSRV3JX" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "cb7f9ff5ff804601", + "Request": { + "Method": "HEAD", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Accept-Ranges": [ + "bytes" + ], + "Content-Length": [ + "6354" + ], + "Content-Type": [ + "application/json" + ], + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Etag": [ + "\"0f6a7c9ff3d3d770b8f7fa19c2ae19d0\"" + ], + "Last-Modified": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "9T0OSku40sEm3HCv1UbnztHrNJbUJQx9yZSf8+usj7lN4u73fAEJdteCkRnIdaEwQimIU8FT+OfQqGWD38Sl5w==" + ], + "X-Amz-Request-Id": [ + "5854M2A09GHYCY3X" + ], + "X-Amz-Server-Side-Encryption": [ + "AES256" + ] + }, + "Body": "" + } + }, + { + "ID": "0d5ec7aa42ac8e37", + "Request": { + "Method": "DELETE", + "URL": "https://go-cloud-testing-2.s3.us-west-1.amazonaws.com/blob-for-reading?x-id=DeleteObject", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Content-Sha256": [ + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + null + ] + }, + "Response": { + "StatusCode": 204, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Date": [ + "Mon, 31 Mar 2025 20:37:21 GMT" + ], + "Server": [ + "AmazonS3" + ], + "X-Amz-Id-2": [ + "xQIJdRIfCpm9vwLQAGHTGuAquZp7UnPXaFSCOnQUOhR3sQmbhVV/EqdwiSVdJ13XRAWnIk5/n1h/dz+tLnwMmw==" + ], + "X-Amz-Request-Id": [ + "585DFR8F5MTV0YHX" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestOpenBucket/empty_bucket_name_results_in_error.replay b/go-cloud/blob/s3blob/testdata/TestOpenBucket/empty_bucket_name_results_in_error.replay new file mode 100644 index 000000000..db343ab97 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestOpenBucket/empty_bucket_name_results_in_error.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPQOHMOqwwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestOpenBucket/empty_bucket_name_results_in_error_V2.replay b/go-cloud/blob/s3blob/testdata/TestOpenBucket/empty_bucket_name_results_in_error_V2.replay new file mode 100644 index 000000000..db32227b1 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestOpenBucket/empty_bucket_name_results_in_error_V2.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7fe2/sO5bkMQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestOpenBucket/success.replay b/go-cloud/blob/s3blob/testdata/TestOpenBucket/success.replay new file mode 100644 index 000000000..a5edae3a7 --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestOpenBucket/success.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7ffPQOHM67QwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/s3blob/testdata/TestOpenBucket/success_V2.replay b/go-cloud/blob/s3blob/testdata/TestOpenBucket/success_V2.replay new file mode 100644 index 000000000..a7d49b82e --- /dev/null +++ b/go-cloud/blob/s3blob/testdata/TestOpenBucket/success_V2.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7fe2/tABc27wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/blob/wrapped_bucket_test.go b/go-cloud/blob/wrapped_bucket_test.go new file mode 100644 index 000000000..9853208a5 --- /dev/null +++ b/go-cloud/blob/wrapped_bucket_test.go @@ -0,0 +1,71 @@ +package blob_test + +import ( + "context" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/fileblob" +) + +func TestPrefixedBucket(t *testing.T) { + dir := t.TempDir() + + bucket, err := fileblob.OpenBucket(dir, nil) + if err != nil { + t.Fatal(err) + } + + const contents = "contents" + ctx := context.Background() + if err := bucket.WriteAll(ctx, "foo/bar/baz.txt", []byte(contents), nil); err != nil { + t.Fatal(err) + } + + wrapped := blob.PrefixedBucket(bucket, "foo/bar/") + defer wrapped.Close() + + got, err := wrapped.ReadAll(ctx, "baz.txt") + if err != nil { + t.Fatal(err) + } + if string(got) != contents { + t.Errorf("got %q want %q", string(got), contents) + } +} + +func TestSingleKeyBucket(t *testing.T) { + dir := t.TempDir() + + bucket, err := fileblob.OpenBucket(dir, nil) + if err != nil { + t.Fatal(err) + } + + const contents = "contents" + ctx := context.Background() + if err := bucket.WriteAll(ctx, "foo/bar.txt", []byte(contents), nil); err != nil { + t.Fatal(err) + } + + dirpath := filepath.ToSlash(dir) + if os.PathSeparator != '/' && !strings.HasPrefix(dirpath, "/") { + dirpath = "/" + dirpath + } + + wrapped, err := blob.OpenBucket(ctx, "file://"+dirpath+"?key=foo/bar.txt") + if err != nil { + t.Fatal(err) + } + defer wrapped.Close() + got, err := wrapped.ReadAll(ctx, "") + if err != nil { + t.Fatal(err) + } + if string(got) != contents { + t.Errorf("got %q want %q", string(got), contents) + } +} diff --git a/go-cloud/doc.go b/go-cloud/doc.go new file mode 100644 index 000000000..b4a370fe7 --- /dev/null +++ b/go-cloud/doc.go @@ -0,0 +1,48 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 cloud contains a library and tools for open cloud development in Go. + +The Go Cloud Development Kit (Go CDK) allows application developers to +seamlessly deploy cloud applications on any combination of cloud providers. +It does this by providing stable, idiomatic interfaces for common uses like +storage and databases. Think `database/sql` for cloud products. + +At the core of the Go CDK are common "portable types", implemented on top of +service-specific drivers for supported cloud services. For example, +objects of the blob.Bucket portable type can be created using +gcsblob.OpenBucket, s3blob.OpenBucket, or any other Go CDK driver. Then, the +blob.Bucket can be used throughout your application without worrying about the +underlying implementation. + +The Go CDK works well with a code generator called Wire +(https://github.com/google/wire/blob/master/README.md). It creates +human-readable code that only imports the cloud SDKs for drivers you use. This +allows the Go CDK to grow to support any number of cloud services, without +increasing compile times or binary sizes, and avoiding any side effects from +`init()` functions. + +For non-reference documentation, see https://gocloud.dev/ + +# URLs + +See https://gocloud.dev/concepts/urls/ for a discussion of URLs in the Go CDK. + +# As + +See https://gocloud.dev/concepts/as/ for a discussion of how to write +service-specific code with the Go CDK. +*/ +package cloud // import "gocloud.dev" diff --git a/go-cloud/docstore/awsdynamodb/benchmark_test.go b/go-cloud/docstore/awsdynamodb/benchmark_test.go new file mode 100644 index 000000000..7f739ca8c --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/benchmark_test.go @@ -0,0 +1,149 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "fmt" + "net/http" + "strconv" + "testing" + + "github.com/aws/aws-sdk-go/aws" + awscreds "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/aws/aws-sdk-go/service/dynamodb/expression" +) + +var benchmarkTableName = collectionName3 + +func BenchmarkPutVSTransact(b *testing.B) { + // This benchmark compares two ways to replace N items and retrieve their previous values. + // The first way makes N calls to PutItem with ReturnValues set to ALL_OLD. + // The second way calls BatchGetItem followed by TransactWriteItem. + // + // The results show that separate PutItems are faster for up to two items. + sess, err := awsSession(region, http.DefaultClient) + if err != nil { + b.Fatal(err) + } + db := dynamodb.New(sess) + + for nItems := 1; nItems <= 5; nItems++ { + b.Run(fmt.Sprintf("%d-Items", nItems), func(b *testing.B) { + var items []map[string]*dynamodb.AttributeValue + for i := 0; i < nItems; i++ { + items = append(items, map[string]*dynamodb.AttributeValue{ + "name": new(dynamodb.AttributeValue).SetS(fmt.Sprintf("pt-vs-transact-%d", i)), + "x": new(dynamodb.AttributeValue).SetN(strconv.Itoa(i)), + "rev": new(dynamodb.AttributeValue).SetN("1"), + }) + } + for _, item := range items { + _, err := db.PutItem(&dynamodb.PutItemInput{ + TableName: &benchmarkTableName, + Item: item, + }) + if err != nil { + b.Fatal(err) + } + } + b.Run("PutItem", func(b *testing.B) { + for n := 0; n < b.N; n++ { + putItems(b, db, items) + } + }) + b.Run("TransactWrite", func(b *testing.B) { + for n := 0; n < b.N; n++ { + batchGetTransactWrite(b, db, items) + } + }) + }) + } +} + +func putItems(b *testing.B, db *dynamodb.DynamoDB, items []map[string]*dynamodb.AttributeValue) { + b.Helper() + + for i, item := range items { + item["x"].SetN(strconv.Itoa(i + 1)) + in := &dynamodb.PutItemInput{ + TableName: &benchmarkTableName, + Item: item, + ReturnValues: aws.String("ALL_OLD"), + } + ce, err := expression.NewBuilder(). + WithCondition(expression.Name("rev").Equal(expression.Value(1))). + Build() + if err != nil { + b.Fatal(err) + } + in.ExpressionAttributeNames = ce.Names() + in.ExpressionAttributeValues = ce.Values() + in.ConditionExpression = ce.Condition() + out, err := db.PutItem(in) + if err != nil { + b.Fatal(err) + } + if got, want := len(out.Attributes), 3; got != want { + b.Fatalf("got %d attributes, want %d", got, want) + } + } +} + +func batchGetTransactWrite(b *testing.B, db *dynamodb.DynamoDB, items []map[string]*dynamodb.AttributeValue) { + b.Helper() + + keys := make([]map[string]*dynamodb.AttributeValue, len(items)) + tws := make([]*dynamodb.TransactWriteItem, len(items)) + for i, item := range items { + keys[i] = map[string]*dynamodb.AttributeValue{"name": items[i]["name"]} + item["x"].SetN(strconv.Itoa(i + 2)) + put := &dynamodb.Put{TableName: &benchmarkTableName, Item: items[i]} + ce, err := expression.NewBuilder(). + WithCondition(expression.Name("rev").Equal(expression.Value(1))). + Build() + if err != nil { + b.Fatal(err) + } + put.ExpressionAttributeNames = ce.Names() + put.ExpressionAttributeValues = ce.Values() + put.ConditionExpression = ce.Condition() + tws[i] = &dynamodb.TransactWriteItem{Put: put} + } + _, err := db.BatchGetItem(&dynamodb.BatchGetItemInput{ + RequestItems: map[string]*dynamodb.KeysAndAttributes{ + benchmarkTableName: {Keys: keys}, + }, + }) + if err != nil { + b.Fatal(err) + } + _, err = db.TransactWriteItems(&dynamodb.TransactWriteItemsInput{TransactItems: tws}) + if err != nil { + b.Fatal(err) + } +} + +func awsSession(region string, client *http.Client) (*session.Session, error) { + // Provide fake creds if running in replay mode. + var creds *awscreds.Credentials + return session.NewSession(&aws.Config{ + HTTPClient: client, + Region: aws.String(region), + Credentials: creds, + MaxRetries: aws.Int(0), + }) +} diff --git a/go-cloud/docstore/awsdynamodb/codec.go b/go-cloud/docstore/awsdynamodb/codec.go new file mode 100644 index 000000000..c06a1c40d --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/codec.go @@ -0,0 +1,344 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "errors" + "fmt" + "reflect" + "strconv" + "time" + + dyn "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" +) + +var nullValue = new(dyn.AttributeValue).SetNULL(true) + +type encoder struct { + av *dyn.AttributeValue +} + +func (e *encoder) EncodeNil() { e.av = nullValue } +func (e *encoder) EncodeBool(x bool) { e.av = new(dyn.AttributeValue).SetBOOL(x) } +func (e *encoder) EncodeInt(x int64) { e.av = new(dyn.AttributeValue).SetN(strconv.FormatInt(x, 10)) } +func (e *encoder) EncodeUint(x uint64) { + e.av = new(dyn.AttributeValue).SetN(strconv.FormatUint(x, 10)) +} +func (e *encoder) EncodeBytes(x []byte) { e.av = new(dyn.AttributeValue).SetB(x) } +func (e *encoder) EncodeFloat(x float64) { e.av = encodeFloat(x) } + +func (e *encoder) ListIndex(int) { panic("impossible") } +func (e *encoder) MapKey(string) { panic("impossible") } + +func (e *encoder) EncodeString(x string) { + if len(x) == 0 { + e.av = nullValue + } else { + e.av = new(dyn.AttributeValue).SetS(x) + } +} + +func (e *encoder) EncodeComplex(x complex128) { + e.av = new(dyn.AttributeValue).SetL([]*dyn.AttributeValue{encodeFloat(real(x)), encodeFloat(imag(x))}) +} + +func (e *encoder) EncodeList(n int) driver.Encoder { + s := make([]*dyn.AttributeValue, n) + e.av = new(dyn.AttributeValue).SetL(s) + return &listEncoder{s: s} +} + +func (e *encoder) EncodeMap(n int) driver.Encoder { + m := make(map[string]*dyn.AttributeValue, n) + e.av = new(dyn.AttributeValue).SetM(m) + return &mapEncoder{m: m} +} + +var typeOfGoTime = reflect.TypeOf(time.Time{}) + +// EncodeSpecial encodes time.Time specially. +func (e *encoder) EncodeSpecial(v reflect.Value) (bool, error) { + switch v.Type() { + case typeOfGoTime: + ts := v.Interface().(time.Time).Format(time.RFC3339Nano) + e.EncodeString(ts) + default: + return false, nil + } + return true, nil +} + +type listEncoder struct { + s []*dyn.AttributeValue + encoder +} + +func (e *listEncoder) ListIndex(i int) { e.s[i] = e.av } + +type mapEncoder struct { + m map[string]*dyn.AttributeValue + encoder +} + +func (e *mapEncoder) MapKey(k string) { e.m[k] = e.av } + +func encodeDoc(doc driver.Document) (*dyn.AttributeValue, error) { + var e encoder + if err := doc.Encode(&e); err != nil { + return nil, err + } + return e.av, nil +} + +// Encode the key fields of the given document into a map AttributeValue. +// pkey and skey are the names of the partition key field and the sort key field. +// pkey must always be non-empty, but skey may be empty if the collection has no sort key. +func encodeDocKeyFields(doc driver.Document, pkey, skey string) (*dyn.AttributeValue, error) { + m := map[string]*dyn.AttributeValue{} + + set := func(fieldName string) error { + fieldVal, err := doc.GetField(fieldName) + if err != nil { + return err + } + attrVal, err := encodeValue(fieldVal) + if err != nil { + return err + } + m[fieldName] = attrVal + return nil + } + + if err := set(pkey); err != nil { + return nil, err + } + if skey != "" { + if err := set(skey); err != nil { + return nil, err + } + } + return new(dyn.AttributeValue).SetM(m), nil +} + +func encodeValue(v interface{}) (*dyn.AttributeValue, error) { + var e encoder + if err := driver.Encode(reflect.ValueOf(v), &e); err != nil { + return nil, err + } + return e.av, nil +} + +func encodeFloat(f float64) *dyn.AttributeValue { + return new(dyn.AttributeValue).SetN(strconv.FormatFloat(f, 'f', -1, 64)) +} + +//////////////////////////////////////////////////////////////// + +func decodeDoc(item *dyn.AttributeValue, doc driver.Document) error { + return doc.Decode(decoder{av: item}) +} + +type decoder struct { + av *dyn.AttributeValue +} + +func (d decoder) String() string { + return d.av.String() +} + +func (d decoder) AsBool() (bool, bool) { + if d.av.BOOL == nil { + return false, false + } + return *d.av.BOOL, true +} + +func (d decoder) AsNull() bool { + return d.av.NULL != nil +} + +func (d decoder) AsString() (string, bool) { + // Empty string is represented by NULL. + if d.av.NULL != nil { + return "", true + } + if d.av.S == nil { + return "", false + } + return *d.av.S, true +} + +func (d decoder) AsInt() (int64, bool) { + if d.av.N == nil { + return 0, false + } + i, err := strconv.ParseInt(*d.av.N, 10, 64) + if err != nil { + return 0, false + } + return i, true +} + +func (d decoder) AsUint() (uint64, bool) { + if d.av.N == nil { + return 0, false + } + u, err := strconv.ParseUint(*d.av.N, 10, 64) + if err != nil { + return 0, false + } + return u, true +} + +func (d decoder) AsFloat() (float64, bool) { + if d.av.N == nil { + return 0, false + } + f, err := strconv.ParseFloat(*d.av.N, 64) + if err != nil { + return 0, false + } + return f, true +} + +func (d decoder) AsComplex() (complex128, bool) { + if d.av.L == nil { + return 0, false + } + if len(d.av.L) != 2 { + return 0, false + } + r, ok := decoder{d.av.L[0]}.AsFloat() + if !ok { + return 0, false + } + i, ok := decoder{d.av.L[1]}.AsFloat() + if !ok { + return 0, false + } + return complex(r, i), true +} + +func (d decoder) AsBytes() ([]byte, bool) { + if d.av.B == nil { + return nil, false + } + return d.av.B, true +} + +func (d decoder) ListLen() (int, bool) { + if d.av.L == nil { + return 0, false + } + return len(d.av.L), true +} + +func (d decoder) DecodeList(f func(i int, vd driver.Decoder) bool) { + for i, el := range d.av.L { + if !f(i, decoder{el}) { + break + } + } +} + +func (d decoder) MapLen() (int, bool) { + if d.av.M == nil { + return 0, false + } + return len(d.av.M), true +} + +func (d decoder) DecodeMap(f func(key string, vd driver.Decoder, exactMatch bool) bool) { + for k, av := range d.av.M { + if !f(k, decoder{av}, true) { + break + } + } +} + +func (d decoder) AsInterface() (interface{}, error) { + return toGoValue(d.av) +} + +func toGoValue(av *dyn.AttributeValue) (interface{}, error) { + switch { + case av.NULL != nil: + return nil, nil + case av.BOOL != nil: + return *av.BOOL, nil + case av.N != nil: + f, err := strconv.ParseFloat(*av.N, 64) + if err != nil { + return nil, err + } + i := int64(f) + if float64(i) == f { + return i, nil + } + u := uint64(f) + if float64(u) == f { + return u, nil + } + return f, nil + + case av.B != nil: + return av.B, nil + case av.S != nil: + return *av.S, nil + + case av.L != nil: + s := make([]interface{}, len(av.L)) + for i, v := range av.L { + x, err := toGoValue(v) + if err != nil { + return nil, err + } + s[i] = x + } + return s, nil + + case av.M != nil: + m := make(map[string]interface{}, len(av.M)) + for k, v := range av.M { + x, err := toGoValue(v) + if err != nil { + return nil, err + } + m[k] = x + } + return m, nil + + default: + return nil, fmt.Errorf("awsdynamodb: AttributeValue %s not supported", av) + } +} + +func (d decoder) AsSpecial(v reflect.Value) (bool, interface{}, error) { + unsupportedTypes := `unsupported type, the docstore driver for DynamoDB does + not decode DynamoDB set types, such as string set, number set and binary set` + if d.av.SS != nil || d.av.NS != nil || d.av.BS != nil { + return true, nil, errors.New(unsupportedTypes) + } + switch v.Type() { + case typeOfGoTime: + if d.av.S == nil { + return false, nil, errors.New("expected string field for time.Time") + } + t, err := time.Parse(time.RFC3339Nano, *d.av.S) + return true, t, err + } + return false, nil, nil +} diff --git a/go-cloud/docstore/awsdynamodb/codec_test.go b/go-cloud/docstore/awsdynamodb/codec_test.go new file mode 100644 index 000000000..0aaf13f94 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/codec_test.go @@ -0,0 +1,115 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "reflect" + "testing" + + dyn "github.com/aws/aws-sdk-go/service/dynamodb" + dynattr "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" +) + +func TestEncodeValue(t *testing.T) { + av := func() *dyn.AttributeValue { return &dyn.AttributeValue{} } + avn := func(s string) *dyn.AttributeValue { return av().SetN(s) } + avl := func(avs ...*dyn.AttributeValue) *dyn.AttributeValue { return av().SetL(avs) } + + var seven int32 = 7 + var nullptr *int + + for _, test := range []struct { + in interface{} + want *dyn.AttributeValue + }{ + {nil, nullValue}, + {0, avn("0")}, + {uint64(999), avn("999")}, + {3.5, avn("3.5")}, + {"", nullValue}, + {"x", av().SetS("x")}, + {true, av().SetBOOL(true)}, + {nullptr, nullValue}, + {seven, avn("7")}, + {&seven, avn("7")}, + {[]int(nil), nullValue}, + {[]int{}, av().SetL([]*dyn.AttributeValue{})}, + {[]int{1, 2}, avl(avn("1"), avn("2"))}, + {[...]int{1, 2}, avl(avn("1"), avn("2"))}, + {[]interface{}{nil, false}, avl(nullValue, av().SetBOOL(false))}, + {map[string]int(nil), nullValue}, + {map[string]int{}, av().SetM(map[string]*dyn.AttributeValue{})}, + { + map[string]int{"a": 1, "b": 2}, + av().SetM(map[string]*dyn.AttributeValue{ + "a": avn("1"), + "b": avn("2"), + }), + }, + } { + var e encoder + if err := driver.Encode(reflect.ValueOf(test.in), &e); err != nil { + t.Fatal(err) + } + got := e.av + if !cmp.Equal(got, test.want, cmpopts.IgnoreUnexported(dyn.AttributeValue{})) { + t.Errorf("%#v: got %#v, want %#v", test.in, got, test.want) + } + } +} + +func TestDecodeErrorOnUnsupported(t *testing.T) { + av := func() *dyn.AttributeValue { return &dyn.AttributeValue{} } + sptr := func(s string) *string { return &s } + for _, tc := range []struct { + in *dyn.AttributeValue + out interface{} + }{ + {av().SetSS([]*string{sptr("foo"), sptr("bar")}), []string{}}, + {av().SetNS([]*string{sptr("1.1"), sptr("-2.2"), sptr("3.3")}), []float64{}}, + {av().SetBS([][]byte{{4}, {5}, {6}}), [][]byte{}}, + } { + d := decoder{av: tc.in} + if err := driver.Decode(reflect.ValueOf(tc.out), &d); err == nil { + t.Error("got nil error, want unsupported error") + } + } +} + +type codecTester struct{} + +func (ct *codecTester) UnsupportedTypes() []drivertest.UnsupportedType { + return []drivertest.UnsupportedType{drivertest.BinarySet} +} + +func (ct *codecTester) NativeEncode(obj interface{}) (interface{}, error) { + return dynattr.Marshal(obj) +} + +func (ct *codecTester) NativeDecode(value, dest interface{}) error { + return dynattr.Unmarshal(value.(*dyn.AttributeValue), dest) +} + +func (ct *codecTester) DocstoreEncode(obj interface{}) (interface{}, error) { + return encodeDoc(drivertest.MustDocument(obj)) +} + +func (ct *codecTester) DocstoreDecode(value, dest interface{}) error { + return decodeDoc(value.(*dyn.AttributeValue), drivertest.MustDocument(dest)) +} diff --git a/go-cloud/docstore/awsdynamodb/create_tables.sh b/go-cloud/docstore/awsdynamodb/create_tables.sh new file mode 100755 index 000000000..d58c89ad2 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/create_tables.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Creates the DynamoDB tables needed for tests. +# +# If a table already exists, this script will fail. To re-create the table, run +# aws dynamodb delete-table --table-name ... +# and wait until the deletion completes. + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +# except we want to keep going if there is a failure. +set -uxo pipefail + +# The docstore-test-1 table has a single partition key called "name". + + +aws dynamodb create-table \ + --table-name docstore-test-1 \ + --attribute-definitions AttributeName=name,AttributeType=S \ + --key-schema AttributeName=name,KeyType=HASH \ + --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 + + +# The docstore-test-2 table has both a partition and a sort key, and two indexes. + +aws dynamodb create-table \ + --table-name docstore-test-2 \ + --attribute-definitions \ + AttributeName=Game,AttributeType=S \ + AttributeName=Player,AttributeType=S \ + AttributeName=Score,AttributeType=N \ + AttributeName=Time,AttributeType=S \ + --key-schema AttributeName=Game,KeyType=HASH AttributeName=Player,KeyType=RANGE \ + --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \ + --local-secondary-indexes \ + 'IndexName=local,KeySchema=[{AttributeName=Game,KeyType=HASH},{AttributeName=Score,KeyType=RANGE}],Projection={ProjectionType=ALL}' \ + --global-secondary-indexes \ + 'IndexName=global,KeySchema=[{AttributeName=Player,KeyType=HASH},{AttributeName=Time,KeyType=RANGE}],Projection={ProjectionType=ALL},ProvisionedThroughput={ReadCapacityUnits=5,WriteCapacityUnits=5}' + + diff --git a/go-cloud/docstore/awsdynamodb/dynamo.go b/go-cloud/docstore/awsdynamodb/dynamo.go new file mode 100644 index 000000000..57899c408 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/dynamo.go @@ -0,0 +1,736 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb provides a docstore implementation backed by Amazon +// DynamoDB. +// Use OpenCollection to construct a *docstore.Collection. +// +// # URLs +// +// For docstore.OpenCollection, awsdynamodb registers for the scheme +// "dynamodb". The default URL opener will use an AWS session with the default +// credentials and configuration; see +// https://docs.aws.amazon.com/sdk-for-go/api/aws/session/ for more details. +// To customize the URL opener, or for more details on the URL format, see +// URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// awsdynamodb exposes the following types for As: +// - Collection.As: *dynamodb.DynamoDB +// - ActionList.BeforeDo: *dynamodb.BatchGetItemInput or *dynamodb.PutItemInput or *dynamodb.DeleteItemInput +// or *dynamodb.UpdateItemInput +// - Query.BeforeQuery: *dynamodb.QueryInput or *dynamodb.ScanInput +// - DocumentIterator: *dynamodb.QueryOutput or *dynamodb.ScanOutput +// - ErrorAs: awserr.Error +package awsdynamodb + +import ( + "context" + "fmt" + "reflect" + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + dyn "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/aws/aws-sdk-go/service/dynamodb/expression" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + wire.Struct(new(URLOpener), "ConfigProvider"), +) + +type collection struct { + db *dyn.DynamoDB + table string // DynamoDB table name + partitionKey string + sortKey string + description *dyn.TableDescription + opts *Options +} + +// FallbackFunc is a function for executing queries that cannot be run by the built-in +// awsdynamodb logic. See Options.RunQueryFunc for details. +type FallbackFunc func(context.Context, *driver.Query, RunQueryFunc) (driver.DocumentIterator, error) + +// Options holds various options. +type Options struct { + // If false, queries that can only be executed by scanning the entire table + // return an error instead (with the exception of a query with no filters). + AllowScans bool + + // The name of the field holding the document revision. + // Defaults to docstore.DefaultRevisionField. + RevisionField string + + // If set, call this function on queries that we cannot execute at all (for + // example, a query with an OrderBy clause that lacks an equality filter on a + // partition key). The function should execute the query however it wishes, and + // return an iterator over the results. It can use the RunQueryFunc passed as its + // third argument to have the DynamoDB driver run a query, for instance a + // modified version of the original query. + // + // If RunQueryFallback is nil, queries that cannot be executed will fail with a + // error that has code Unimplemented. + RunQueryFallback FallbackFunc + + // The maximum number of concurrent goroutines started for a single call to + // ActionList.Do. If less than 1, there is no limit. + MaxOutstandingActionRPCs int + + // If true, a strongly consistent read is used whenever possible, including + // get, query, scan, etc.; default to false, where an eventually consistent + // read is used. + // + // Not all read operations support this mode however, such as querying against + // a global secondary index, the operation will return an InvalidArgument error + // in such case, please check the official DynamoDB documentation for more + // details. + // + // The native client for DynamoDB uses this option in a per-action basis, if + // you need the flexibility to run both modes on the same collection, create + // two collections with different mode. + ConsistentRead bool +} + +// RunQueryFunc is the type of the function passed to RunQueryFallback. +type RunQueryFunc func(context.Context, *driver.Query) (driver.DocumentIterator, error) + +// OpenCollection creates a *docstore.Collection representing a DynamoDB collection. +func OpenCollection(db *dyn.DynamoDB, tableName, partitionKey, sortKey string, opts *Options) (*docstore.Collection, error) { + c, err := newCollection(db, tableName, partitionKey, sortKey, opts) + if err != nil { + return nil, err + } + return docstore.NewCollection(c), nil +} + +func newCollection(db *dyn.DynamoDB, tableName, partitionKey, sortKey string, opts *Options) (*collection, error) { + out, err := db.DescribeTable(&dyn.DescribeTableInput{TableName: &tableName}) + if err != nil { + return nil, err + } + if opts == nil { + opts = &Options{} + } + if opts.RevisionField == "" { + opts.RevisionField = docstore.DefaultRevisionField + } + return &collection{ + db: db, + table: tableName, + partitionKey: partitionKey, + sortKey: sortKey, + description: out.Table, + opts: opts, + }, nil +} + +// Key returns a two-element array with the partition key and sort key, if any. +func (c *collection) Key(doc driver.Document) (interface{}, error) { + pkey, err := doc.GetField(c.partitionKey) + if err != nil || pkey == nil || driver.IsEmptyValue(reflect.ValueOf(pkey)) { + return nil, nil // missing key is not an error + } + keys := [2]interface{}{pkey} + if c.sortKey != "" { + keys[1], _ = doc.GetField(c.sortKey) // ignore error since keys[1] is nil in that case + } + return keys, nil +} + +func (c *collection) RevisionField() string { return c.opts.RevisionField } + +func (c *collection) RunActions(ctx context.Context, actions []*driver.Action, opts *driver.RunActionsOptions) driver.ActionListError { + errs := make([]error, len(actions)) + beforeGets, gets, writes, writesTx, afterGets := driver.GroupActions(actions) + c.runGets(ctx, beforeGets, errs, opts) + ch := make(chan struct{}) + ch2 := make(chan struct{}) + go func() { defer close(ch); c.runWrites(ctx, writes, errs, opts) }() + go func() { defer close(ch2); c.transactWrite(ctx, writesTx, errs, opts) }() + c.runGets(ctx, gets, errs, opts) + <-ch + <-ch2 + c.runGets(ctx, afterGets, errs, opts) + return driver.NewActionListError(errs) +} + +func (c *collection) runGets(ctx context.Context, actions []*driver.Action, errs []error, opts *driver.RunActionsOptions) { + const batchSize = 100 + t := driver.NewThrottle(c.opts.MaxOutstandingActionRPCs) + for _, group := range driver.GroupByFieldPath(actions) { + n := len(group) / batchSize + for i := 0; i < n; i++ { + i := i + t.Acquire() + go func(group []*driver.Action) { + defer t.Release() + c.batchGet(ctx, group, errs, opts, batchSize*i, batchSize*(i+1)-1) + }(group) + } + if n*batchSize < len(group) { + t.Acquire() + go func(group []*driver.Action) { + defer t.Release() + c.batchGet(ctx, group, errs, opts, batchSize*n, len(group)-1) + }(group) + } + } + t.Wait() +} + +func (c *collection) batchGet(ctx context.Context, gets []*driver.Action, errs []error, opts *driver.RunActionsOptions, start, end int) { + // errors need to be mapped to the actions' indices. + setErr := func(err error) { + for i := start; i <= end; i++ { + errs[gets[i].Index] = err + } + } + + keys := make([]map[string]*dyn.AttributeValue, 0, end-start+1) + for i := start; i <= end; i++ { + av, err := encodeDocKeyFields(gets[i].Doc, c.partitionKey, c.sortKey) + if err != nil { + errs[gets[i].Index] = err + } + + keys = append(keys, av.M) + } + ka := &dyn.KeysAndAttributes{ + Keys: keys, + ConsistentRead: aws.Bool(c.opts.ConsistentRead), + } + if len(gets[start].FieldPaths) != 0 { + // We need to add the key fields if the user doesn't include them. The + // BatchGet API doesn't return them otherwise. + var hasP, hasS bool + var nbs []expression.NameBuilder + for _, fp := range gets[start].FieldPaths { + p := strings.Join(fp, ".") + nbs = append(nbs, expression.Name(p)) + if p == c.partitionKey { + hasP = true + } else if p == c.sortKey { + hasS = true + } + } + if !hasP { + nbs = append(nbs, expression.Name(c.partitionKey)) + } + if c.sortKey != "" && !hasS { + nbs = append(nbs, expression.Name(c.sortKey)) + } + expr, err := expression.NewBuilder(). + WithProjection(expression.AddNames(expression.ProjectionBuilder{}, nbs...)). + Build() + if err != nil { + setErr(err) + return + } + ka.ProjectionExpression = expr.Projection() + ka.ExpressionAttributeNames = expr.Names() + } + in := &dyn.BatchGetItemInput{RequestItems: map[string]*dyn.KeysAndAttributes{c.table: ka}} + if opts.BeforeDo != nil { + if err := opts.BeforeDo(driver.AsFunc(in)); err != nil { + setErr(err) + return + } + } + out, err := c.db.BatchGetItemWithContext(ctx, in) + if err != nil { + setErr(err) + return + } + found := make([]bool, end-start+1) + am := mapActionIndices(gets, start, end) + for _, item := range out.Responses[c.table] { + if item != nil { + key := map[string]interface{}{c.partitionKey: nil} + if c.sortKey != "" { + key[c.sortKey] = nil + } + keysOnly, err := driver.NewDocument(key) + if err != nil { + panic(err) + } + err = decodeDoc(&dyn.AttributeValue{M: item}, keysOnly) + if err != nil { + continue + } + decKey, err := c.Key(keysOnly) + if err != nil { + continue + } + i := am[decKey] + errs[gets[i].Index] = decodeDoc(&dyn.AttributeValue{M: item}, gets[i].Doc) + found[i-start] = true + } + } + for delta, f := range found { + if !f { + errs[gets[start+delta].Index] = gcerr.Newf(gcerr.NotFound, nil, "item %v not found", gets[start+delta].Doc) + } + } +} + +func mapActionIndices(actions []*driver.Action, start, end int) map[interface{}]int { + m := make(map[interface{}]int) + for i := start; i <= end; i++ { + m[actions[i].Key] = i + } + return m +} + +// runWrites executes all the writes as separate RPCs, concurrently. +func (c *collection) runWrites(ctx context.Context, writes []*driver.Action, errs []error, opts *driver.RunActionsOptions) { + var ops []*writeOp + for _, w := range writes { + op, err := c.newWriteOp(w, opts) + if err != nil { + errs[w.Index] = err + } else { + ops = append(ops, op) + } + } + + t := driver.NewThrottle(c.opts.MaxOutstandingActionRPCs) + for _, op := range ops { + op := op + t.Acquire() + go func() { + defer t.Release() + err := op.run(ctx) + a := op.action + if err != nil { + errs[a.Index] = err + } else { + errs[a.Index] = c.onSuccess(op) + } + }() + } + t.Wait() +} + +// A writeOp describes a single write to DynamoDB. The write can be executed +// on its own, or included as part of a transaction. +type writeOp struct { + action *driver.Action + writeItem *dyn.TransactWriteItem // for inclusion in a transaction + newPartitionKey string // for a Create on a document without a partition key + newRevision string + run func(context.Context) error // run as a single RPC +} + +func (c *collection) newWriteOp(a *driver.Action, opts *driver.RunActionsOptions) (*writeOp, error) { + switch a.Kind { + case driver.Create, driver.Replace, driver.Put: + return c.newPut(a, opts) + case driver.Update: + return c.newUpdate(a, opts) + case driver.Delete: + return c.newDelete(a, opts) + default: + panic("bad write kind") + } +} + +func (c *collection) newPut(a *driver.Action, opts *driver.RunActionsOptions) (*writeOp, error) { + av, err := encodeDoc(a.Doc) + if err != nil { + return nil, err + } + mf := c.missingKeyField(av.M) + if a.Kind != driver.Create && mf != "" { + return nil, fmt.Errorf("missing key field %q", mf) + } + var newPartitionKey string + if mf == c.partitionKey { + newPartitionKey = driver.UniqueString() + av.M[c.partitionKey] = new(dyn.AttributeValue).SetS(newPartitionKey) + } + if c.sortKey != "" && mf == c.sortKey { + // It doesn't make sense to generate a random sort key. + return nil, fmt.Errorf("missing sort key %q", c.sortKey) + } + var rev string + if a.Doc.HasField(c.opts.RevisionField) { + rev = driver.UniqueString() + if av.M[c.opts.RevisionField], err = encodeValue(rev); err != nil { + return nil, err + } + } + dput := &dyn.Put{ + TableName: &c.table, + Item: av.M, + } + cb, err := c.precondition(a) + if err != nil { + return nil, err + } + if cb != nil { + ce, err := expression.NewBuilder().WithCondition(*cb).Build() + if err != nil { + return nil, err + } + dput.ExpressionAttributeNames = ce.Names() + dput.ExpressionAttributeValues = ce.Values() + dput.ConditionExpression = ce.Condition() + } + return &writeOp{ + action: a, + writeItem: &dyn.TransactWriteItem{Put: dput}, + newPartitionKey: newPartitionKey, + newRevision: rev, + run: func(ctx context.Context) error { + return c.runPut(ctx, dput, a, opts) + }, + }, nil +} + +func (c *collection) runPut(ctx context.Context, dput *dyn.Put, a *driver.Action, opts *driver.RunActionsOptions) error { + in := &dyn.PutItemInput{ + TableName: dput.TableName, + Item: dput.Item, + ConditionExpression: dput.ConditionExpression, + ExpressionAttributeNames: dput.ExpressionAttributeNames, + ExpressionAttributeValues: dput.ExpressionAttributeValues, + } + if opts.BeforeDo != nil { + if err := opts.BeforeDo(driver.AsFunc(in)); err != nil { + return err + } + } + _, err := c.db.PutItemWithContext(ctx, in) + if ae, ok := err.(awserr.Error); ok && ae.Code() == dyn.ErrCodeConditionalCheckFailedException { + if a.Kind == driver.Create { + err = gcerr.Newf(gcerr.AlreadyExists, err, "document already exists") + } + if rev, _ := a.Doc.GetField(c.opts.RevisionField); rev == nil && a.Kind == driver.Replace { + err = gcerr.Newf(gcerr.NotFound, nil, "document not found") + } + } + return err +} + +func (c *collection) newDelete(a *driver.Action, opts *driver.RunActionsOptions) (*writeOp, error) { + av, err := encodeDocKeyFields(a.Doc, c.partitionKey, c.sortKey) + if err != nil { + return nil, err + } + del := &dyn.Delete{ + TableName: &c.table, + Key: av.M, + } + cb, err := c.precondition(a) + if err != nil { + return nil, err + } + if cb != nil { + ce, err := expression.NewBuilder().WithCondition(*cb).Build() + if err != nil { + return nil, err + } + del.ExpressionAttributeNames = ce.Names() + del.ExpressionAttributeValues = ce.Values() + del.ConditionExpression = ce.Condition() + } + return &writeOp{ + action: a, + writeItem: &dyn.TransactWriteItem{Delete: del}, + run: func(ctx context.Context) error { + in := &dyn.DeleteItemInput{ + TableName: del.TableName, + Key: del.Key, + ConditionExpression: del.ConditionExpression, + ExpressionAttributeNames: del.ExpressionAttributeNames, + ExpressionAttributeValues: del.ExpressionAttributeValues, + } + if opts.BeforeDo != nil { + if err := opts.BeforeDo(driver.AsFunc(in)); err != nil { + return err + } + } + _, err := c.db.DeleteItemWithContext(ctx, in) + return err + }, + }, nil +} + +func (c *collection) newUpdate(a *driver.Action, opts *driver.RunActionsOptions) (*writeOp, error) { + av, err := encodeDocKeyFields(a.Doc, c.partitionKey, c.sortKey) + if err != nil { + return nil, err + } + var ub expression.UpdateBuilder + for _, m := range a.Mods { + // TODO(shantuo): check for invalid field paths + fp := expression.Name(strings.Join(m.FieldPath, ".")) + if inc, ok := m.Value.(driver.IncOp); ok { + ub = ub.Add(fp, expression.Value(inc.Amount)) + } else if m.Value == nil { + ub = ub.Remove(fp) + } else { + ub = ub.Set(fp, expression.Value(m.Value)) + } + } + var rev string + if a.Doc.HasField(c.opts.RevisionField) { + rev = driver.UniqueString() + ub = ub.Set(expression.Name(c.opts.RevisionField), expression.Value(rev)) + } + cb, err := c.precondition(a) + if err != nil { + return nil, err + } + ce, err := expression.NewBuilder().WithCondition(*cb).WithUpdate(ub).Build() + if err != nil { + return nil, err + } + up := &dyn.Update{ + TableName: &c.table, + Key: av.M, + ConditionExpression: ce.Condition(), + UpdateExpression: ce.Update(), + ExpressionAttributeNames: ce.Names(), + ExpressionAttributeValues: ce.Values(), + } + return &writeOp{ + action: a, + writeItem: &dyn.TransactWriteItem{Update: up}, + newRevision: rev, + run: func(ctx context.Context) error { + in := &dyn.UpdateItemInput{ + TableName: up.TableName, + Key: up.Key, + ConditionExpression: up.ConditionExpression, + UpdateExpression: up.UpdateExpression, + ExpressionAttributeNames: up.ExpressionAttributeNames, + ExpressionAttributeValues: up.ExpressionAttributeValues, + } + if opts.BeforeDo != nil { + if err := opts.BeforeDo(driver.AsFunc(in)); err != nil { + return err + } + } + _, err := c.db.UpdateItemWithContext(ctx, in) + return err + }, + }, nil +} + +// Handle the effects of successful execution. +func (c *collection) onSuccess(op *writeOp) error { + // Set the new partition key (if any) and the new revision into the user's document. + if op.newPartitionKey != "" { + _ = op.action.Doc.SetField(c.partitionKey, op.newPartitionKey) // cannot fail + } + if op.newRevision != "" { + return op.action.Doc.SetField(c.opts.RevisionField, op.newRevision) + } + return nil +} + +func (c *collection) missingKeyField(m map[string]*dyn.AttributeValue) string { + if v, ok := m[c.partitionKey]; !ok || v.NULL != nil { + return c.partitionKey + } + if v, ok := m[c.sortKey]; (!ok || v.NULL != nil) && c.sortKey != "" { + return c.sortKey + } + return "" +} + +// Construct the precondition for the action. +func (c *collection) precondition(a *driver.Action) (*expression.ConditionBuilder, error) { + switch a.Kind { + case driver.Create: + // Precondition: the document doesn't already exist. (Precisely: the partitionKey + // field is not on the document.) + c := expression.AttributeNotExists(expression.Name(c.partitionKey)) + return &c, nil + case driver.Replace, driver.Update: + // Precondition: the revision matches, or if there is no revision, then + // the document exists. + cb, err := revisionPrecondition(a.Doc, c.opts.RevisionField) + if err != nil { + return nil, err + } + if cb == nil { + c := expression.AttributeExists(expression.Name(c.partitionKey)) + cb = &c + } + return cb, nil + case driver.Put, driver.Delete: + // Precondition: the revision matches, if any. + return revisionPrecondition(a.Doc, c.opts.RevisionField) + case driver.Get: + // No preconditions on a Get. + return nil, nil + default: + panic("bad action kind") + } +} + +// revisionPrecondition returns a DynamoDB expression that asserts that the +// stored document's revision matches the revision of doc. +func revisionPrecondition(doc driver.Document, revField string) (*expression.ConditionBuilder, error) { + v, err := doc.GetField(revField) + if err != nil { // field not present + return nil, nil + } + if v == nil { // field is present, but nil + return nil, nil + } + rev, ok := v.(string) + if !ok { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, + "%s field contains wrong type: got %T, want string", + revField, v) + } + if rev == "" { + return nil, nil + } + // Value encodes rev to an attribute value. + cb := expression.Name(revField).Equal(expression.Value(rev)) + return &cb, nil +} + +// transactWrite executes the write actions atomically: either they all succeed or they all fail together. +func (c *collection) transactWrite(ctx context.Context, actions []*driver.Action, errs []error, opts *driver.RunActionsOptions) { + if len(actions) == 0 { + return + } + // all actions will fail atomically even if a single action fails + setErr := func(err error) { + for _, a := range actions { + errs[a.Index] = err + } + } + + tws := make([]*dyn.TransactWriteItem, 0, len(actions)) + var ops []*writeOp + for _, w := range actions { + op, err := c.newWriteOp(w, opts) + if err != nil { + setErr(err) + return + } else { + ops = append(ops, op) + tws = append(tws, op.writeItem) + } + } + + in := &dyn.TransactWriteItemsInput{ + ClientRequestToken: aws.String(driver.UniqueString()), + TransactItems: tws, + } + + if opts.BeforeDo != nil { + asFunc := func(i interface{}) bool { + p, ok := i.(**dyn.TransactWriteItemsInput) + if !ok { + return false + } + *p = in + return true + } + if err := opts.BeforeDo(asFunc); err != nil { + setErr(err) + return + } + } + if _, err := c.db.TransactWriteItemsWithContext(ctx, in); err != nil { + setErr(err) + return + } + for _, op := range ops { + errs[op.action.Index] = c.onSuccess(op) + } +} + +// RevisionToBytes implements driver.RevisionToBytes. +func (c *collection) RevisionToBytes(rev interface{}) ([]byte, error) { + s, ok := rev.(string) + if !ok { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "revision %v of type %[1]T is not a string", rev) + } + return []byte(s), nil +} + +// BytesToRevision implements driver.BytesToRevision. +func (c *collection) BytesToRevision(b []byte) (interface{}, error) { + return string(b), nil +} + +func (c *collection) As(i interface{}) bool { + p, ok := i.(**dyn.DynamoDB) + if !ok { + return false + } + *p = c.db + return true +} + +// ErrorAs implements driver.Collection.ErrorAs. +func (c *collection) ErrorAs(err error, i interface{}) bool { + e, ok := err.(awserr.Error) + if !ok { + return false + } + p, ok := i.(*awserr.Error) + if !ok { + return false + } + *p = e + return true +} + +func (c *collection) ErrorCode(err error) gcerrors.ErrorCode { + ae, ok := err.(awserr.Error) + if !ok { + return gcerrors.Unknown + } + ec, ok := errorCodeMap[ae.Code()] + if !ok { + return gcerrors.Unknown + } + return ec +} + +var errorCodeMap = map[string]gcerrors.ErrorCode{ + dyn.ErrCodeConditionalCheckFailedException: gcerrors.FailedPrecondition, + dyn.ErrCodeProvisionedThroughputExceededException: gcerrors.ResourceExhausted, + dyn.ErrCodeResourceNotFoundException: gcerrors.NotFound, + dyn.ErrCodeItemCollectionSizeLimitExceededException: gcerrors.ResourceExhausted, + dyn.ErrCodeTransactionConflictException: gcerrors.Internal, + dyn.ErrCodeRequestLimitExceeded: gcerrors.ResourceExhausted, + dyn.ErrCodeInternalServerError: gcerrors.Internal, + dyn.ErrCodeTransactionCanceledException: gcerrors.FailedPrecondition, + dyn.ErrCodeTransactionInProgressException: gcerrors.InvalidArgument, + dyn.ErrCodeIdempotentParameterMismatchException: gcerrors.InvalidArgument, + "ValidationException": gcerrors.InvalidArgument, +} + +// Close implements driver.Collection.Close. +func (c *collection) Close() error { return nil } diff --git a/go-cloud/docstore/awsdynamodb/dynamo_test.go b/go-cloud/docstore/awsdynamodb/dynamo_test.go new file mode 100644 index 000000000..4dcf772ff --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/dynamo_test.go @@ -0,0 +1,233 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "context" + "errors" + "fmt" + "io" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/session" + dyn "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" +) + +// To create the tables and indexes needed for these tests, run create_tables.sh in +// this directory. +// +// The docstore-test-2 table is set up to work with queries on the drivertest.HighScore +// struct like so: +// table: "Game" partition key, "Player" sort key +// local index: "Game" partition key, "Score" sort key +// global index: "Player" partition key, "Time" sort key +// The conformance test queries should exercise all of these. +// +// The docstore-test-3 table is used for running benchmarks only. To eliminate +// the effect of dynamo auto-scaling, run: +// aws dynamodb update-table --table-name docstore-test-3 \ +// --provisioned-throughput ReadCapacityUnits=1000,WriteCapacityUnits=1000 +// Don't forget to change it back when done benchmarking. + +const ( + region = "us-east-2" + collectionName1 = "docstore-test-1" + collectionName2 = "docstore-test-2" + collectionName3 = "docstore-test-3" // for benchmark +) + +type harness struct { + sess *session.Session + closer func() +} + +func (h *harness) SupportsAtomicWrites() bool { + return true +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + sess, _, done, state := setup.NewAWSSession(ctx, t, region) + drivertest.MakeUniqueStringDeterministicForTesting(state) + return &harness{sess: sess, closer: done}, nil +} + +func (*harness) BeforeDoTypes() []interface{} { + return []interface{}{ + &dyn.BatchGetItemInput{}, &dyn.TransactWriteItemsInput{}, + &dyn.PutItemInput{}, &dyn.DeleteItemInput{}, &dyn.UpdateItemInput{}, + } +} + +func (*harness) BeforeQueryTypes() []interface{} { + return []interface{}{&dyn.QueryInput{}, &dyn.ScanInput{}} +} + +func (*harness) RevisionsEqual(rev1, rev2 interface{}) bool { + return rev1 == rev2 +} + +func (h *harness) Close() { + h.closer() +} + +func (h *harness) MakeCollection(_ context.Context, kind drivertest.CollectionKind) (driver.Collection, error) { + switch kind { + case drivertest.SingleKey, drivertest.NoRev: + return newCollection(dyn.New(h.sess), collectionName1, drivertest.KeyField, "", &Options{ + AllowScans: true, + ConsistentRead: true, + }) + case drivertest.TwoKey: + // For query test we don't use strong consistency mode since some tests are + // running on global secondary index and it doesn't support ConsistentRead. + return newCollection(dyn.New(h.sess), collectionName2, "Game", "Player", &Options{ + AllowScans: true, + RunQueryFallback: InMemorySortFallback(func() interface{} { return new(drivertest.HighScore) }), + }) + case drivertest.AltRev: + return newCollection(dyn.New(h.sess), collectionName1, drivertest.KeyField, "", + &Options{ + AllowScans: true, + RevisionField: drivertest.AlternateRevisionField, + ConsistentRead: true, + }) + default: + panic("bad kind") + } +} + +func collectHighScores(ctx context.Context, iter driver.DocumentIterator) ([]*drivertest.HighScore, error) { + var hs []*drivertest.HighScore + for { + var h drivertest.HighScore + doc := drivertest.MustDocument(&h) + err := iter.Next(ctx, doc) + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + hs = append(hs, &h) + } + return hs, nil +} + +type highScoreSliceIterator struct { + hs []*drivertest.HighScore + next int +} + +func (it *highScoreSliceIterator) Next(ctx context.Context, doc driver.Document) error { + if it.next >= len(it.hs) { + return io.EOF + } + dest, ok := doc.Origin.(*drivertest.HighScore) + if !ok { + return fmt.Errorf("doc is %T, not HighScore", doc.Origin) + } + *dest = *it.hs[it.next] + it.next++ + return nil +} + +func (*highScoreSliceIterator) Stop() {} +func (*highScoreSliceIterator) As(interface{}) bool { return false } + +type verifyAs struct{} + +func (verifyAs) Name() string { + return "verify As" +} + +func (verifyAs) CollectionCheck(coll *docstore.Collection) error { + var db *dyn.DynamoDB + if !coll.As(&db) { + return errors.New("Collection.As failed") + } + return nil +} + +func (verifyAs) QueryCheck(it *docstore.DocumentIterator) error { + var so *dyn.ScanOutput + var qo *dyn.QueryOutput + if !it.As(&so) && !it.As(&qo) { + return errors.New("DocumentIterator.As failed") + } + return nil +} + +func (v verifyAs) ErrorCheck(k *docstore.Collection, err error) error { + var e awserr.Error + if !k.ErrorAs(err, &e) { + return errors.New("Collection.ErrorAs failed") + } + return nil +} + +func TestConformance(t *testing.T) { + // Note: when running -record repeatedly in a short time period, change the argument + // in the call below to generate unique transaction tokens. + drivertest.MakeUniqueStringDeterministicForTesting(1) + drivertest.RunConformanceTests(t, newHarness, &codecTester{}, []drivertest.AsTest{verifyAs{}}) +} + +func BenchmarkConformance(b *testing.B) { + sess := session.Must(session.NewSession(&aws.Config{ + Region: aws.String(region), + })) + coll, err := newCollection(dyn.New(sess), collectionName3, drivertest.KeyField, "", &Options{AllowScans: true}) + if err != nil { + b.Fatal(err) + } + drivertest.RunBenchmarks(b, docstore.NewCollection(coll)) +} + +// awsdynamodb-specific tests. + +func TestQueryErrors(t *testing.T) { + // Verify that bad queries return the right errors. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + dc, err := h.MakeCollection(ctx, drivertest.TwoKey) + if err != nil { + t.Fatal(err) + } + coll := docstore.NewCollection(dc) + defer coll.Close() + + // Here we are comparing a key field with the wrong type. DynamoDB cares about this + // because even though it's a document store and hence schemaless, the key fields + // do have a schema (that is, they have known, fixed types). + iter := coll.Query().Where("Game", "=", 1).Get(ctx) + defer iter.Stop() + err = iter.Next(ctx, &h) + if c := gcerrors.Code(err); c != gcerrors.InvalidArgument { + t.Errorf("got %v (code %s, type %T), want InvalidArgument", err, c, err) + } +} diff --git a/go-cloud/docstore/awsdynamodb/example_test.go b/go-cloud/docstore/awsdynamodb/example_test.go new file mode 100644 index 000000000..51b19b002 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/example_test.go @@ -0,0 +1,53 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb_test + +import ( + "context" + "log" + + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/awsdynamodb" +) + +func ExampleOpenCollection() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + sess, err := session.NewSession() + if err != nil { + log.Fatal(err) + } + coll, err := awsdynamodb.OpenCollection( + dynamodb.New(sess), "docstore-test", "partitionKeyField", "", nil) + if err != nil { + log.Fatal(err) + } + defer coll.Close() +} + +func Example_openCollectionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/docstore/awsdynamodb" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // docstore.OpenCollection creates a *docstore.Collection from a URL. + coll, err := docstore.OpenCollection(ctx, "dynamodb://my-table?partition_key=name") + if err != nil { + log.Fatal(err) + } + defer coll.Close() +} diff --git a/go-cloud/docstore/awsdynamodb/query.go b/go-cloud/docstore/awsdynamodb/query.go new file mode 100644 index 000000000..f2bbde43b --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/query.go @@ -0,0 +1,686 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "reflect" + "sort" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + dyn "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/aws/aws-sdk-go/service/dynamodb/expression" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +// TODO: support parallel scans (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.ParallelScan) + +// TODO(jba): support an empty item slice returned from an RPC: "A Query operation can +// return an empty result set and a LastEvaluatedKey if all the items read for the +// page of results are filtered out." + +type avmap = map[string]*dyn.AttributeValue + +func (c *collection) RunGetQuery(ctx context.Context, q *driver.Query) (driver.DocumentIterator, error) { + qr, err := c.planQuery(q) + if err != nil { + if gcerrors.Code(err) == gcerrors.Unimplemented && c.opts.RunQueryFallback != nil { + return c.opts.RunQueryFallback(ctx, q, c.RunGetQuery) + } + return nil, err + } + if err := c.checkPlan(qr); err != nil { + return nil, err + } + it := &documentIterator{ + qr: qr, + offset: q.Offset, + limit: q.Limit, + count: 0, // manually count limit since dynamodb uses "limit" as scan limit before filtering + } + it.items, it.last, it.asFunc, err = it.qr.run(ctx, nil) + if err != nil { + return nil, err + } + return it, nil +} + +func (c *collection) checkPlan(qr *queryRunner) error { + if qr.scanIn != nil && qr.scanIn.FilterExpression != nil && !c.opts.AllowScans { + return gcerr.Newf(gcerr.InvalidArgument, nil, "query requires a table scan; set Options.AllowScans to true to enable") + } + return nil +} + +func (c *collection) planQuery(q *driver.Query) (*queryRunner, error) { + var cb expression.Builder + cbUsed := false // It's an error to build an empty Builder. + // Set up the projection expression. + if len(q.FieldPaths) > 0 { + var pb expression.ProjectionBuilder + hasFields := map[string]bool{} + for _, fp := range q.FieldPaths { + if len(fp) == 1 { + hasFields[fp[0]] = true + } + pb = pb.AddNames(expression.Name(strings.Join(fp, "."))) + } + // Always include the keys. + for _, f := range []string{c.partitionKey, c.sortKey} { + if f != "" && !hasFields[f] { + pb = pb.AddNames(expression.Name(f)) + q.FieldPaths = append(q.FieldPaths, []string{f}) + } + } + cb = cb.WithProjection(pb) + cbUsed = true + } + + // Find the best thing to query (table or index). + indexName, pkey, skey := c.bestQueryable(q) + if indexName == nil && pkey == "" { + // No query can be done: fall back to scanning. + if q.OrderByField != "" { + // Scans are unordered, so we can't run this query. + // TODO(jba): If the user specifies all the partition keys, and there is a global + // secondary index whose sort key is the order-by field, then we can query that index + // for every value of the partition key and merge the results. + // TODO(jba): If the query has a reasonable limit N, then we can run a scan and keep + // the top N documents in memory. + return nil, gcerr.Newf(gcerr.Unimplemented, nil, "query requires a table scan, but has an ordering requirement; add an index or provide Options.RunQueryFallback") + } + if len(q.Filters) > 0 { + cb = cb.WithFilter(filtersToConditionBuilder(q.Filters)) + cbUsed = true + } + in := &dyn.ScanInput{ + TableName: &c.table, + ConsistentRead: aws.Bool(c.opts.ConsistentRead), + } + if cbUsed { + ce, err := cb.Build() + if err != nil { + return nil, err + } + in.ExpressionAttributeNames = ce.Names() + in.ExpressionAttributeValues = ce.Values() + in.FilterExpression = ce.Filter() + in.ProjectionExpression = ce.Projection() + } + return &queryRunner{c: c, scanIn: in, beforeRun: q.BeforeQuery}, nil + } + + // Do a query. + cb = processFilters(cb, q.Filters, pkey, skey) + ce, err := cb.Build() + if err != nil { + return nil, err + } + qIn := &dyn.QueryInput{ + TableName: &c.table, + IndexName: indexName, + ExpressionAttributeNames: ce.Names(), + ExpressionAttributeValues: ce.Values(), + KeyConditionExpression: ce.KeyCondition(), + FilterExpression: ce.Filter(), + ProjectionExpression: ce.Projection(), + ConsistentRead: aws.Bool(c.opts.ConsistentRead), + } + if q.OrderByField != "" && !q.OrderAscending { + qIn.ScanIndexForward = &q.OrderAscending + } + return &queryRunner{ + c: c, + queryIn: qIn, + beforeRun: q.BeforeQuery, + }, nil +} + +// Return the best choice of queryable (table or index) for this query. +// How to interpret the return values: +// - If indexName is nil but pkey is not empty, then use the table. +// - If all return values are zero, no query will work: do a scan. +func (c *collection) bestQueryable(q *driver.Query) (indexName *string, pkey, skey string) { + // If the query has an "=" filter on the table's partition key, look at the table + // and local indexes. + if hasEqualityFilter(q, c.partitionKey) { + // If the table has a sort key that's in the query, and the ordering + // constraint works with the sort key, use the table. + // (Query results are always ordered by sort key.) + if hasFilter(q, c.sortKey) && orderingConsistent(q, c.sortKey) { + return nil, c.partitionKey, c.sortKey + } + // Look at local indexes. They all have the same partition key as the base table. + // If one has a sort key in the query, use it. + for _, li := range c.description.LocalSecondaryIndexes { + pkey, skey := keyAttributes(li.KeySchema) + if hasFilter(q, skey) && localFieldsIncluded(q, li) && orderingConsistent(q, skey) { + return li.IndexName, pkey, skey + } + } + } + // Consider the global indexes: if one has a matching partition and sort key, and + // the projected fields of the index include those of the query, use it. + for _, gi := range c.description.GlobalSecondaryIndexes { + pkey, skey := keyAttributes(gi.KeySchema) + if skey == "" { + continue // We'll visit global indexes without a sort key later. + } + if hasEqualityFilter(q, pkey) && hasFilter(q, skey) && c.globalFieldsIncluded(q, gi) && orderingConsistent(q, skey) { + return gi.IndexName, pkey, skey + } + } + // There are no matches for both partition and sort key. Now consider matches on partition key only. + // That will still be better than a scan. + // First, check the table itself. + if hasEqualityFilter(q, c.partitionKey) && orderingConsistent(q, c.sortKey) { + return nil, c.partitionKey, c.sortKey + } + // No point checking local indexes: they have the same partition key as the table. + // Check the global indexes. + for _, gi := range c.description.GlobalSecondaryIndexes { + pkey, skey := keyAttributes(gi.KeySchema) + if hasEqualityFilter(q, pkey) && c.globalFieldsIncluded(q, gi) && orderingConsistent(q, skey) { + return gi.IndexName, pkey, skey + } + } + // We cannot do a query. + // TODO: return the reason why we couldn't. At a minimum, distinguish failure due to keys + // from failure due to projection (i.e. a global index had the right partition and sort key, + // but didn't project the necessary fields). + return nil, "", "" +} + +// localFieldsIncluded reports whether a local index supports all the selected fields +// of a query. Since DynamoDB will read explicitly provided fields from the table if +// they are not projected into the index, the only case where a local index cannot +// be used is when the query wants all the fields, and the index projection is not ALL. +// See https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LSI.html#LSI.Projections. +func localFieldsIncluded(q *driver.Query, li *dyn.LocalSecondaryIndexDescription) bool { + return len(q.FieldPaths) > 0 || *li.Projection.ProjectionType == "ALL" +} + +// orderingConsistent reports whether the ordering constraint is consistent with the sort key field. +// That is, either there is no OrderBy clause, or the clause specifies the sort field. +func orderingConsistent(q *driver.Query, sortField string) bool { + return q.OrderByField == "" || q.OrderByField == sortField +} + +// globalFieldsIncluded reports whether the fields selected by the query are +// projected into (that is, contained directly in) the global index. We need this +// check before using the index, because if a global index doesn't have all the +// desired fields, then a separate RPC for each returned item would be necessary to +// retrieve those fields, and we'd rather scan than do that. +func (c *collection) globalFieldsIncluded(q *driver.Query, gi *dyn.GlobalSecondaryIndexDescription) bool { + proj := gi.Projection + if *proj.ProjectionType == "ALL" { + // The index has all the fields of the table: we're good. + return true + } + if len(q.FieldPaths) == 0 { + // The query wants all the fields of the table, but we can't be sure that the + // index has them. + return false + } + // The table's keys and the index's keys are always in the index. + pkey, skey := keyAttributes(gi.KeySchema) + indexFields := map[string]bool{c.partitionKey: true, pkey: true} + if c.sortKey != "" { + indexFields[c.sortKey] = true + } + if skey != "" { + indexFields[skey] = true + } + for _, nka := range proj.NonKeyAttributes { + indexFields[*nka] = true + } + // Every field path in the query must be in the index. + for _, fp := range q.FieldPaths { + if !indexFields[strings.Join(fp, ".")] { + return false + } + } + return true +} + +// Extract the names of the partition and sort key attributes from the schema of a +// table or index. +func keyAttributes(ks []*dyn.KeySchemaElement) (pkey, skey string) { + for _, k := range ks { + switch *k.KeyType { + case "HASH": + pkey = *k.AttributeName + case "RANGE": + skey = *k.AttributeName + default: + panic("bad key type: " + *k.KeyType) + } + } + return pkey, skey +} + +// Reports whether q has a filter that mentions the top-level field. +func hasFilter(q *driver.Query, field string) bool { + if field == "" { + return false + } + for _, f := range q.Filters { + if driver.FieldPathEqualsField(f.FieldPath, field) { + return true + } + } + return false +} + +// Reports whether q has a filter that checks if the top-level field is equal to something. +func hasEqualityFilter(q *driver.Query, field string) bool { + for _, f := range q.Filters { + if f.Op == driver.EqualOp && driver.FieldPathEqualsField(f.FieldPath, field) { + return true + } + } + return false +} + +type queryRunner struct { + c *collection + scanIn *dyn.ScanInput + queryIn *dyn.QueryInput + beforeRun func(asFunc func(i interface{}) bool) error +} + +func (qr *queryRunner) run(ctx context.Context, startAfter avmap) (items []avmap, last avmap, asFunc func(i interface{}) bool, err error) { + if qr.scanIn != nil { + qr.scanIn.ExclusiveStartKey = startAfter + if qr.beforeRun != nil { + asFunc := func(i interface{}) bool { + p, ok := i.(**dyn.ScanInput) + if !ok { + return false + } + *p = qr.scanIn + return true + } + if err := qr.beforeRun(asFunc); err != nil { + return nil, nil, nil, err + } + } + out, err := qr.c.db.ScanWithContext(ctx, qr.scanIn) + if err != nil { + return nil, nil, nil, err + } + return out.Items, out.LastEvaluatedKey, + func(i interface{}) bool { + p, ok := i.(**dyn.ScanOutput) + if !ok { + return false + } + *p = out + return true + }, nil + } + qr.queryIn.ExclusiveStartKey = startAfter + if qr.beforeRun != nil { + asFunc := func(i interface{}) bool { + p, ok := i.(**dyn.QueryInput) + if !ok { + return false + } + *p = qr.queryIn + return true + } + if err := qr.beforeRun(asFunc); err != nil { + return nil, nil, nil, err + } + } + out, err := qr.c.db.QueryWithContext(ctx, qr.queryIn) + if err != nil { + return nil, nil, nil, err + } + return out.Items, out.LastEvaluatedKey, + func(i interface{}) bool { + p, ok := i.(**dyn.QueryOutput) + if !ok { + return false + } + *p = out + return true + }, nil +} + +func processFilters(cb expression.Builder, fs []driver.Filter, pkey, skey string) expression.Builder { + var kbs []expression.KeyConditionBuilder + var cfs []driver.Filter + for _, f := range fs { + if kb, ok := toKeyCondition(f, pkey, skey); ok { + kbs = append(kbs, kb) + continue + } + cfs = append(cfs, f) + } + keyBuilder := kbs[0] + for i := 1; i < len(kbs); i++ { + keyBuilder = keyBuilder.And(kbs[i]) + } + cb = cb.WithKeyCondition(keyBuilder) + if len(cfs) > 0 { + cb = cb.WithFilter(filtersToConditionBuilder(cfs)) + } + return cb +} + +func filtersToConditionBuilder(fs []driver.Filter) expression.ConditionBuilder { + if len(fs) == 0 { + panic("no filters") + } + var cb expression.ConditionBuilder + cb = toFilter(fs[0]) + for _, f := range fs[1:] { + cb = cb.And(toFilter(f)) + } + return cb +} + +func toKeyCondition(f driver.Filter, pkey, skey string) (expression.KeyConditionBuilder, bool) { + kp := strings.Join(f.FieldPath, ".") + if kp == pkey || kp == skey { + key := expression.Key(kp) + val := expression.Value(f.Value) + switch f.Op { + case "<": + return expression.KeyLessThan(key, val), true + case "<=": + return expression.KeyLessThanEqual(key, val), true + case driver.EqualOp: + return expression.KeyEqual(key, val), true + case ">=": + return expression.KeyGreaterThanEqual(key, val), true + case ">": + return expression.KeyGreaterThan(key, val), true + default: + panic(fmt.Sprint("invalid filter operation:", f.Op)) + } + } + return expression.KeyConditionBuilder{}, false +} + +func toFilter(f driver.Filter) expression.ConditionBuilder { + name := expression.Name(strings.Join(f.FieldPath, ".")) + val := expression.Value(f.Value) + switch f.Op { + case "<": + return expression.LessThan(name, val) + case "<=": + return expression.LessThanEqual(name, val) + case driver.EqualOp: + return expression.Equal(name, val) + case ">=": + return expression.GreaterThanEqual(name, val) + case ">": + return expression.GreaterThan(name, val) + case "in": + return toInCondition(f) + case "not-in": + return expression.Not(toInCondition(f)) + default: + panic(fmt.Sprint("invalid filter operation:", f.Op)) + } +} + +func toInCondition(f driver.Filter) expression.ConditionBuilder { + name := expression.Name(strings.Join(f.FieldPath, ".")) + vslice := reflect.ValueOf(f.Value) + right := expression.Value(vslice.Index(0).Interface()) + other := make([]expression.OperandBuilder, vslice.Len()-1) + for i := 1; i < vslice.Len(); i++ { + other[i-1] = expression.Value(vslice.Index(i).Interface()) + } + return expression.In(name, right, other...) +} + +type documentIterator struct { + qr *queryRunner // the query runner + items []map[string]*dyn.AttributeValue // items from the last query + curr int // index of the current item in items + offset int // number of items to skip + limit int // number of items to return + count int // number of items returned + last map[string]*dyn.AttributeValue // lastEvaluatedKey from the last query + asFunc func(i interface{}) bool // for As +} + +func (it *documentIterator) Next(ctx context.Context, doc driver.Document) error { + // Skip the first 'n' documents where 'n' is the offset. + for it.count < it.offset { + if err := it.next(ctx, doc, false); err != nil { + return err + } + } + return it.next(ctx, doc, true) +} + +func (it *documentIterator) next(ctx context.Context, doc driver.Document, decode bool) error { + // Only start counting towards the limit after the offset has been reached. + if it.limit > 0 && it.count >= it.offset+it.limit { + return io.EOF + } + // it.items can be empty after a call to it.qr.run, but unless it.last is nil there may be more items. + for it.curr >= len(it.items) { + // Make a new query request at the end of this page. + if it.last == nil { + return io.EOF + } + var err error + it.items, it.last, it.asFunc, err = it.qr.run(ctx, it.last) + if err != nil { + return err + } + it.curr = 0 + } + if decode { + if err := decodeDoc(&dyn.AttributeValue{M: it.items[it.curr]}, doc); err != nil { + return err + } + } + it.curr++ + it.count++ + return nil +} + +func (it *documentIterator) Stop() { + it.items = nil + it.last = nil +} + +func (it *documentIterator) As(i interface{}) bool { + return it.asFunc(i) +} + +func (c *collection) QueryPlan(q *driver.Query) (string, error) { + qr, err := c.planQuery(q) + if err != nil { + return "", err + } + return qr.queryPlan(), nil +} + +func (qr *queryRunner) queryPlan() string { + if qr.scanIn != nil { + return "Scan" + } + if qr.queryIn.IndexName != nil { + return fmt.Sprintf("Index: %q", *qr.queryIn.IndexName) + } + return "Table" +} + +// InMemorySortFallback returns a query fallback function for Options.RunQueryFallback. +// The function accepts a query with an OrderBy clause. It runs the query without that clause, +// reading all documents into memory, then sorts the documents according to the OrderBy clause. +// +// Only string, numeric, time and binary ([]byte) fields can be sorted. +// +// createDocument should create an empty document to be passed to DocumentIterator.Next. +// The DocumentIterator returned by the FallbackFunc will also expect the same type of document. +// If nil, then a map[string]interface{} will be used. +func InMemorySortFallback(createDocument func() interface{}) FallbackFunc { + if createDocument == nil { + createDocument = func() interface{} { return map[string]interface{}{} } + } + return func(ctx context.Context, q *driver.Query, run RunQueryFunc) (driver.DocumentIterator, error) { + if q.OrderByField == "" { + return nil, errors.New("InMemorySortFallback expects an OrderBy query") + } + // Run the query without the OrderBy. + orderByField := q.OrderByField + q.OrderByField = "" + iter, err := run(ctx, q) + if err != nil { + return nil, err + } + defer iter.Stop() + // Collect the results into a slice. + var docs []driver.Document + for { + doc, err := driver.NewDocument(createDocument()) + if err != nil { + return nil, err + } + err = iter.Next(ctx, doc) + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + docs = append(docs, doc) + } + // Sort the documents. + // OrderByField is a single field, not a field path. + // First, put the field values in another slice, so we can + // return on error. + sortValues := make([]interface{}, len(docs)) + for i, doc := range docs { + v, err := doc.GetField(orderByField) + if err != nil { + return nil, err + } + sortValues[i] = v + } + sort.Sort(docsForSorting{docs, sortValues, q.OrderAscending}) + return &sliceIterator{docs: docs}, nil + } +} + +type docsForSorting struct { + docs []driver.Document + vals []interface{} + ascending bool +} + +func (d docsForSorting) Len() int { return len(d.docs) } + +func (d docsForSorting) Swap(i, j int) { + d.docs[i], d.docs[j] = d.docs[j], d.docs[i] + d.vals[i], d.vals[j] = d.vals[j], d.vals[i] +} + +func (d docsForSorting) Less(i, j int) bool { + c := compare(d.vals[i], d.vals[j]) + if d.ascending { + return c < 0 + } + return c > 0 +} + +// compare returns -1 if v1 < v2, 0 if v1 == v2 and 1 if v1 > v2. +// +// Arbitrarily decide that strings < times < []byte < numbers. +// TODO(jba): find and use the actual sort order that DynamoDB uses. +func compare(v1, v2 interface{}) int { + switch v1 := v1.(type) { + case string: + if v2, ok := v2.(string); ok { + return strings.Compare(v1, v2) + } + return -1 + + case time.Time: + if v2, ok := v2.(time.Time); ok { + return driver.CompareTimes(v1, v2) + } + if _, ok := v2.(string); ok { + return 1 + } + return -1 + + case []byte: + if v2, ok := v2.([]byte); ok { + return bytes.Compare(v1, v2) + } + if _, ok := v2.(string); ok { + return 1 + } + if _, ok := v2.(time.Time); ok { + return 1 + } + return -1 + + default: + cmp, err := driver.CompareNumbers(v1, v2) + if err != nil { + return -1 + } + return cmp + } +} + +type sliceIterator struct { + docs []driver.Document + next int +} + +func (it *sliceIterator) Next(ctx context.Context, doc driver.Document) error { + if it.next >= len(it.docs) { + return io.EOF + } + it.next++ + return copyTopLevel(doc, it.docs[it.next-1]) +} + +// Copy the top-level fields of src into dest. +func copyTopLevel(dest, src driver.Document) error { + for _, f := range src.FieldNames() { + v, err := src.GetField(f) + if err != nil { + return err + } + if err := dest.SetField(f, v); err != nil { + return err + } + } + return nil +} + +func (*sliceIterator) Stop() {} +func (*sliceIterator) As(interface{}) bool { return false } diff --git a/go-cloud/docstore/awsdynamodb/query_test.go b/go-cloud/docstore/awsdynamodb/query_test.go new file mode 100644 index 000000000..8452ec873 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/query_test.go @@ -0,0 +1,680 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "context" + "errors" + "fmt" + "strings" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" +) + +func TestPlanQuery(t *testing.T) { + c := &collection{ + table: "T", + partitionKey: "tableP", + description: &dynamodb.TableDescription{}, + opts: &Options{AllowScans: true, RevisionField: "rev"}, + } + + // Build an ExpressionAttributeNames map with the given names. + eans := func(names ...string) map[string]*string { + m := map[string]*string{} + for i, n := range names { + m[fmt.Sprintf("#%d", i)] = aws.String(n) + } + return m + } + + // Build an ExpressionAttributeValues map. Filter values are always the number 1 + // and the keys are always :0, :1, ..., so we only need to know how many entries. + eavs := func(n int) map[string]*dynamodb.AttributeValue { + if n == 0 { + return nil + } + one := new(dynamodb.AttributeValue).SetN("1") + m := map[string]*dynamodb.AttributeValue{} + for i := 0; i < n; i++ { + m[fmt.Sprintf(":%d", i)] = one + } + return m + } + + // Ignores the ConsistentRead field from both QueryInput and ScanInput. + opts := []cmp.Option{ + cmpopts.IgnoreFields(dynamodb.ScanInput{}, "ConsistentRead"), + cmpopts.IgnoreFields(dynamodb.QueryInput{}, "ConsistentRead"), + } + + for _, test := range []struct { + desc string + // In all cases, the table has a partition key called "tableP". + tableSortKey string // if non-empty, the table sort key + localIndexSortKey string // if non-empty, there is a local index with this sort key + localIndexFields []string // the fields projected into the local index + globalIndexPartitionKey string // if non-empty, there is a global index with this partition key + globalIndexSortKey string // if non-empty, the global index has this sort key + globalIndexFields []string // the fields projected into the global index + query *driver.Query + want interface{} // either a ScanInput or a QueryInput + wantPlan string + }{ + { + desc: "empty query", + // A query with no filters requires a scan. + query: &driver.Query{}, + want: &dynamodb.ScanInput{TableName: &c.table}, + wantPlan: "Scan", + }, + { + desc: "equality filter on table partition field", + // A filter that compares the table's partition key for equality is the minimum + // requirement for querying the table. + query: &driver.Query{Filters: []driver.Filter{{[]string{"tableP"}, "=", 1}}}, + want: &dynamodb.QueryInput{ + KeyConditionExpression: aws.String("#0 = :0"), + ExpressionAttributeNames: eans("tableP"), + ExpressionAttributeValues: eavs(1), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on table partition field (sort key)", + // Same as above, but the table has a sort key; shouldn't make a difference. + tableSortKey: "tableS", + query: &driver.Query{Filters: []driver.Filter{{[]string{"tableP"}, "=", 1}}}, + want: &dynamodb.QueryInput{ + KeyConditionExpression: aws.String("#0 = :0"), + ExpressionAttributeNames: eans("tableP"), + ExpressionAttributeValues: eavs(1), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on other field", + // This query has an equality filter, but not on the table's partition key. + // Since there are no matching indexes, we must scan. + query: &driver.Query{Filters: []driver.Filter{{[]string{"other"}, "=", 1}}}, + want: &dynamodb.ScanInput{ + FilterExpression: aws.String("#0 = :0"), + ExpressionAttributeNames: eans("other"), + ExpressionAttributeValues: eavs(1), + }, + wantPlan: "Scan", + }, + { + desc: "non-equality filter on table partition field", + // If the query doesn't have an equality filter on the partition key, and there + // are no indexes, we must scan. The filter becomes a FilterExpression, evaluated + // on the backend. + query: &driver.Query{Filters: []driver.Filter{{[]string{"tableP"}, ">", 1}}}, + want: &dynamodb.ScanInput{ + FilterExpression: aws.String("#0 > :0"), + ExpressionAttributeNames: eans("tableP"), + ExpressionAttributeValues: eavs(1), + }, + wantPlan: "Scan", + }, + { + desc: "equality filter on partition, filter on other", + // The equality filter on the table's partition key lets us query the table. + // The other filter is used in the filter expression. + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"other"}, "<=", 1}, + }}, + want: &dynamodb.QueryInput{ + KeyConditionExpression: aws.String("#1 = :1"), + FilterExpression: aws.String("#0 <= :0"), + ExpressionAttributeNames: eans("other", "tableP"), + ExpressionAttributeValues: eavs(2), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on partition, filter on sort", + // If the table has a sort key and the query has a filter on it as well + // as an equality filter on the table's partition key, we can query the + // table. + tableSortKey: "tableS", + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"tableS"}, "<=", 1}, + }}, + want: &dynamodb.QueryInput{ + KeyConditionExpression: aws.String("(#0 = :0) AND (#1 <= :1)"), + ExpressionAttributeNames: eans("tableP", "tableS"), + ExpressionAttributeValues: eavs(2), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on table partition, filter on local index sort", + // The equality filter on the table's partition key allows us to query + // the table, but there is a better choice: a local index with a sort key + // that is mentioned in the query. + localIndexSortKey: "localS", + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"localS"}, "<=", 1}, + }}, + want: &dynamodb.QueryInput{ + IndexName: aws.String("local"), + KeyConditionExpression: aws.String("(#0 = :0) AND (#1 <= :1)"), + ExpressionAttributeNames: eans("tableP", "localS"), + }, + wantPlan: `Index: "local"`, + }, + { + desc: "equality filter on table partition, filter on local index sort, bad projection", + // The equality filter on the table's partition key allows us to query + // the table. There seems to be a better choice: a local index with a sort key + // that is mentioned in the query. But the query wants the entire document, + // and the local index only has some fields. + localIndexSortKey: "localS", + localIndexFields: []string{}, // keys only + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"localS"}, "<=", 1}, + }}, + want: &dynamodb.QueryInput{ + KeyConditionExpression: aws.String("#1 = :1"), + FilterExpression: aws.String("#0 <= :0"), + ExpressionAttributeNames: eans("localS", "tableP"), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on table partition, filter on local index sort, good projection", + // Same as above, but now the query no longer asks for all fields, so + // we will only read the requested fields from the table. + localIndexSortKey: "localS", + localIndexFields: []string{}, // keys only + query: &driver.Query{ + FieldPaths: [][]string{{"tableP"}, {"localS"}}, + Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"localS"}, "<=", 1}, + }, + }, + want: &dynamodb.QueryInput{ + IndexName: aws.String("local"), + KeyConditionExpression: aws.String("(#0 = :0) AND (#1 <= :1)"), + ExpressionAttributeNames: eans("tableP", "localS"), + ExpressionAttributeValues: eavs(2), + ProjectionExpression: aws.String("#0, #1"), + }, + wantPlan: `Index: "local"`, + }, + { + desc: "equality filter on table partition, filters on local index and table sort", + // Given the choice of querying the table or a local index, prefer the table. + tableSortKey: "tableS", + localIndexSortKey: "localS", + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"localS"}, "<=", 1}, + {[]string{"tableS"}, ">", 1}, + }}, + want: &dynamodb.QueryInput{ + IndexName: nil, + KeyConditionExpression: aws.String("(#1 = :1) AND (#2 > :2)"), + FilterExpression: aws.String("#0 <= :0"), + ExpressionAttributeNames: eans("localS", "tableP", "tableS"), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on other field with index", + // The query is the same as in "equality filter on other field," but now there + // is a global index with that field as partition key, so we can query it. + globalIndexPartitionKey: "other", + query: &driver.Query{Filters: []driver.Filter{{[]string{"other"}, "=", 1}}}, + want: &dynamodb.QueryInput{ + IndexName: aws.String("global"), + KeyConditionExpression: aws.String("#0 = :0"), + ExpressionAttributeNames: eans("other"), + }, + wantPlan: `Index: "global"`, + }, + { + desc: "equality filter on table partition, filter on global index sort", + // The equality filter on the table's partition key allows us to query + // the table, but there is a better choice: a global index with the same + // partition key and a sort key that is mentioned in the query. + // (In these tests, the global index has all the fields of the table by default.) + globalIndexPartitionKey: "tableP", + globalIndexSortKey: "globalS", + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"globalS"}, "<=", 1}, + }}, + want: &dynamodb.QueryInput{ + IndexName: aws.String("global"), + KeyConditionExpression: aws.String("(#0 = :0) AND (#1 <= :1)"), + ExpressionAttributeNames: eans("tableP", "globalS"), + }, + wantPlan: `Index: "global"`, + }, + { + desc: "equality filter on table partition, filter on global index sort, bad projection", + // Although there is a global index that matches the filters best, it doesn't + // have the necessary fields. So we query against the table. + // The query does not specify FilterPaths, so it retrieves the entire document. + // globalIndexFields explicitly lists the fields that the global index has. + // Since the global index does not have all the document fields, it can't be used. + globalIndexPartitionKey: "tableP", + globalIndexSortKey: "globalS", + globalIndexFields: []string{"other"}, + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"globalS"}, "<=", 1}, + }}, + want: &dynamodb.QueryInput{ + IndexName: nil, + KeyConditionExpression: aws.String("#1 = :1"), + FilterExpression: aws.String("#0 <= :0"), + ExpressionAttributeNames: eans("globalS", "tableP"), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on table partition, filter on global index sort, good projection", + // The global index matches the filters best and has the necessary + // fields. So we query against it. + globalIndexPartitionKey: "tableP", + globalIndexSortKey: "globalS", + globalIndexFields: []string{"other", "rev"}, + query: &driver.Query{ + FieldPaths: [][]string{{"other"}}, + Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"globalS"}, "<=", 1}, + }, + }, + want: &dynamodb.QueryInput{ + IndexName: aws.String("global"), + KeyConditionExpression: aws.String("(#0 = :0) AND (#1 <= :1)"), + ProjectionExpression: aws.String("#2, #0"), + ExpressionAttributeNames: eans("tableP", "globalS", "other"), + ExpressionAttributeValues: eavs(2), + }, + wantPlan: `Index: "global"`, + }, + } { + t.Run(test.desc, func(t *testing.T) { + c.sortKey = test.tableSortKey + if test.localIndexSortKey == "" { + c.description.LocalSecondaryIndexes = nil + } else { + c.description.LocalSecondaryIndexes = []*dynamodb.LocalSecondaryIndexDescription{ + { + IndexName: aws.String("local"), + KeySchema: keySchema("tableP", test.localIndexSortKey), + Projection: indexProjection(test.localIndexFields), + }, + } + } + if test.globalIndexPartitionKey == "" { + c.description.GlobalSecondaryIndexes = nil + } else { + c.description.GlobalSecondaryIndexes = []*dynamodb.GlobalSecondaryIndexDescription{ + { + IndexName: aws.String("global"), + KeySchema: keySchema(test.globalIndexPartitionKey, test.globalIndexSortKey), + Projection: indexProjection(test.globalIndexFields), + }, + } + } + gotRunner, err := c.planQuery(test.query) + if err != nil { + t.Fatal(err) + } + var got interface{} + switch tw := test.want.(type) { + case *dynamodb.ScanInput: + got = gotRunner.scanIn + tw.TableName = &c.table + if tw.ExpressionAttributeValues == nil { + tw.ExpressionAttributeValues = eavs(len(tw.ExpressionAttributeNames)) + } + case *dynamodb.QueryInput: + got = gotRunner.queryIn + tw.TableName = &c.table + if tw.ExpressionAttributeValues == nil { + tw.ExpressionAttributeValues = eavs(len(tw.ExpressionAttributeNames)) + } + default: + t.Fatalf("bad type for test.want: %T", test.want) + } + if diff := cmp.Diff(got, test.want, opts...); diff != "" { + t.Error("input:\n", diff) + } + gotPlan := gotRunner.queryPlan() + if diff := cmp.Diff(gotPlan, test.wantPlan); diff != "" { + t.Error("plan:\n", diff) + } + }) + } +} + +func TestQueryNoScans(t *testing.T) { + c := &collection{ + table: "T", + partitionKey: "tableP", + description: &dynamodb.TableDescription{}, + opts: &Options{AllowScans: false}, + } + + for _, test := range []struct { + q *driver.Query + wantErr bool + }{ + {&driver.Query{}, false}, + {&driver.Query{Filters: []driver.Filter{{[]string{"other"}, "=", 1}}}, true}, + } { + qr, err := c.planQuery(test.q) + if err != nil { + t.Fatalf("%v: %v", test.q, err) + } + err = c.checkPlan(qr) + if test.wantErr { + if err == nil || !strings.Contains(err.Error(), "AllowScans") { + t.Errorf("%v: got %v, want an error that mentions the AllowScans option", test.q, err) + } + } else if err != nil { + t.Errorf("%v: got %v, want nil", test.q, err) + } + } +} + +// Make a key schema from the names of the partition and sort keys. +func keySchema(pkey, skey string) []*dynamodb.KeySchemaElement { + return []*dynamodb.KeySchemaElement{ + {AttributeName: &pkey, KeyType: aws.String("HASH")}, + {AttributeName: &skey, KeyType: aws.String("RANGE")}, + } +} + +func indexProjection(fields []string) *dynamodb.Projection { + var ptype string + switch { + case fields == nil: + ptype = "ALL" + case len(fields) == 0: + ptype = "KEYS_ONLY" + default: + ptype = "INCLUDE" + } + proj := &dynamodb.Projection{ProjectionType: &ptype} + for _, f := range fields { + f := f + proj.NonKeyAttributes = append(proj.NonKeyAttributes, &f) + } + return proj +} + +func TestGlobalFieldsIncluded(t *testing.T) { + c := &collection{partitionKey: "tableP", sortKey: "tableS"} + gi := &dynamodb.GlobalSecondaryIndexDescription{ + KeySchema: keySchema("globalP", "globalS"), + } + for _, test := range []struct { + desc string + queryFields []string + wantKeysOnly bool // when the projection includes only table and index keys + wantInclude bool // when the projection includes fields "f" and "g". + }{ + { + desc: "all", + queryFields: nil, + wantKeysOnly: false, + wantInclude: false, + }, + { + desc: "key fields", + queryFields: []string{"tableS", "globalP"}, + wantKeysOnly: true, + wantInclude: true, + }, + { + desc: "included fields", + queryFields: []string{"f", "g"}, + wantKeysOnly: false, + wantInclude: true, + }, + { + desc: "included and key fields", + queryFields: []string{"f", "g", "tableP", "globalS"}, + wantKeysOnly: false, + wantInclude: true, + }, + { + desc: "not included field", + queryFields: []string{"f", "g", "h"}, + wantKeysOnly: false, + wantInclude: false, + }, + } { + t.Run(test.desc, func(t *testing.T) { + var fps [][]string + for _, qf := range test.queryFields { + fps = append(fps, strings.Split(qf, ".")) + } + q := &driver.Query{FieldPaths: fps} + for _, p := range []struct { + name string + proj *dynamodb.Projection + want bool + }{ + {"ALL", indexProjection(nil), true}, + {"KEYS_ONLY", indexProjection([]string{}), test.wantKeysOnly}, + {"INCLUDE", indexProjection([]string{"f", "g"}), test.wantInclude}, + } { + t.Run(p.name, func(t *testing.T) { + gi.Projection = p.proj + got := c.globalFieldsIncluded(q, gi) + if got != p.want { + t.Errorf("got %t, want %t", got, p.want) + } + }) + } + }) + } +} + +func TestCompare(t *testing.T) { + tm := time.Now() + for _, test := range []struct { + a, b interface{} + want int + }{ + {1, 1, 0}, + {1, 2, -1}, + {2, 1, 1}, + {1.5, 2, -1}, + {2.5, 2.1, 1}, + {3.8, 3.8, 0}, + {"x", "x", 0}, + {"x", "xx", -1}, + {"x", "a", 1}, + {tm, tm, 0}, + {tm, tm.Add(1), -1}, + {tm, tm.Add(-1), 1}, + {[]byte("x"), []byte("x"), 0}, + {[]byte("x"), []byte("xx"), -1}, + {[]byte("x"), []byte("a"), 1}, + } { + got := compare(test.a, test.b) + if got != test.want { + t.Errorf("compare(%v, %v) = %d, want %d", test.a, test.b, got, test.want) + } + } +} + +func TestCopyTopLevel(t *testing.T) { + type E struct{ C int } + type S struct { + A int + B int + E + } + + s := &S{A: 1, B: 2, E: E{C: 3}} + m := map[string]interface{}{"A": 1, "B": 2, "C": 3} + for _, test := range []struct { + dest, src interface{} + want interface{} + }{ + { + dest: map[string]interface{}{}, + src: m, + want: m, + }, + { + dest: &S{}, + src: s, + want: s, + }, + { + dest: map[string]interface{}{}, + src: s, + want: m, + }, + { + dest: &S{}, + src: m, + want: s, + }, + } { + dest := drivertest.MustDocument(test.dest) + src := drivertest.MustDocument(test.src) + if err := copyTopLevel(dest, src); err != nil { + t.Fatalf("src=%+v: %v", test.src, err) + } + if !cmp.Equal(test.dest, test.want) { + t.Errorf("src=%+v: got %v, want %v", test.src, test.dest, test.want) + } + } +} + +func Test_documentIterator_Next(t *testing.T) { + type fields struct { + qr *queryRunner + items []map[string]*dynamodb.AttributeValue + curr int + offset int + limit int + count int + last map[string]*dynamodb.AttributeValue + asFunc func(i interface{}) bool + } + type args struct { + ctx context.Context + doc driver.Document + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + { + name: "nextWithNoDecodeError", + fields: fields{ + qr: &queryRunner{}, + items: []map[string]*dynamodb.AttributeValue{ + {"key": {M: map[string]*dynamodb.AttributeValue{"key": {S: aws.String("value")}}}}, + }, + curr: 0, + offset: 0, + limit: 0, + count: 0, + last: map[string]*dynamodb.AttributeValue{}, + }, + args: args{ + ctx: context.Background(), + doc: drivertest.MustDocument(map[string]interface{}{}), + }, + wantErr: false, + }, + { + name: "nextWithDecodeError", + fields: fields{ + qr: &queryRunner{}, + items: []map[string]*dynamodb.AttributeValue{ + {"key": {M: nil}}, // set M to nil to trigger decode error + }, + curr: 0, + offset: 0, + limit: 0, + count: 0, + last: map[string]*dynamodb.AttributeValue{}, + }, + args: args{ + ctx: context.Background(), + doc: drivertest.MustDocument(map[string]interface{}{}), + }, + wantErr: true, + }, + { + name: "nextWhereCurrIsGreaterThanOrEqualToItemsAndLastIsNotNil", + fields: fields{ + qr: &queryRunner{ + scanIn: &dynamodb.ScanInput{}, + // hack to return error from run + beforeRun: func(asFunc func(i interface{}) bool) error { return errors.New("invalid") }, + }, + items: []map[string]*dynamodb.AttributeValue{{"key": {M: map[string]*dynamodb.AttributeValue{"key": {S: aws.String("value"), M: nil}}}}}, + curr: 1, + offset: 0, + limit: 0, + count: 0, + last: map[string]*dynamodb.AttributeValue{"key": {S: aws.String("value")}}, + }, + args: args{ + ctx: context.Background(), + doc: drivertest.MustDocument(map[string]interface{}{}), + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + it := &documentIterator{ + qr: tt.fields.qr, + items: tt.fields.items, + curr: tt.fields.curr, + offset: tt.fields.offset, + limit: tt.fields.limit, + count: tt.fields.count, + last: tt.fields.last, + asFunc: tt.fields.asFunc, + } + if err := it.Next(tt.args.ctx, tt.args.doc); (err != nil) != tt.wantErr { + t.Errorf("documentIterator.Next() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/ActionsOnStructNoRev.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/ActionsOnStructNoRev.replay new file mode 100644 index 000000000..1d08db774 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/ActionsOnStructNoRev.replay @@ -0,0 +1,539 @@ +{ + "Initial": "AQAAAA7gDLPGAjEKKgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "bb6a06da7dcaeaf1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "3UJJFA09DL8L07IPUV18PQDK4NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "7bc708ed1b451c96", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "155" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1324337382" + ], + "X-Amzn-Requestid": [ + "RK5KNEDQ45CP94GPU40B0CACUFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3RTZXJpYWxpemVSZXZpc2lvbiJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmMDc2MjMxNC04MjM1LTQ3MDYtYmY3Ny0zOGU3MWU5NWZhMDMifSwieCI6eyJOIjoiMSJ9fV0sIlNjYW5uZWRDb3VudCI6MX0=" + } + }, + { + "ID": "cb4e58b5d26e96f2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "241" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZjA3NjIzMTQtODIzNS00NzA2LWJmNzctMzhlNzFlOTVmYTAzIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFNlcmlhbGl6ZVJldmlzaW9uIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GRG9U0IQPJD9NF6NRCJ76HICN7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "aef37e38f9f820c6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkkiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoicHV0YW5kdXBkYXRlIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "D93EQ9UT5LB090KJ6R063OH4JVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "93f5eefb718022c2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "177" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJJIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6ImNyZWF0ZWFuZHJlcGxhY2UifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "ISSUOF37GRKF3MFEQV9DV23N4NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "91014b18f086c507", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "133" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJjcmVhdGVhbmRyZXBsYWNlIn19LHsibmFtZSI6eyJTIjoicHV0YW5kdXBkYXRlIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "148" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1989180713" + ], + "X-Amzn-Requestid": [ + "2MU0GGSOUV7K0001NTV7IM6727VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJJIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6ImNyZWF0ZWFuZHJlcGxhY2UifX0seyJJIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InB1dGFuZHVwZGF0ZSJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "5b7a6264e371e5f0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSJ9LCJJdGVtIjp7IkkiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoiY3JlYXRlYW5kcmVwbGFjZSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JB7NNMIPL10BJV4IV2TKM3LT5RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "35ed6f77bb0d71ac", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiSSJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7Ik4iOiIxIn19LCJLZXkiOnsibmFtZSI6eyJTIjoicHV0YW5kdXBkYXRlIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiU0VUICMxID0gOjBcbiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TRKQ2BI6136LKF3NN5GB6VL53BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "07f45ba5ccc11a47", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "215" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJJIiwiIzEiOiJuYW1lIn0sIktleXMiOlt7Im5hbWUiOnsiUyI6ImNyZWF0ZWFuZHJlcGxhY2UifX0seyJuYW1lIjp7IlMiOiJwdXRhbmR1cGRhdGUifX1dLCJQcm9qZWN0aW9uRXhwcmVzc2lvbiI6IiMwLCAjMSJ9fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "148" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1795518206" + ], + "X-Amzn-Requestid": [ + "CFCVHUFA9I19S1L9SVGT3LQFMBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJJIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6ImNyZWF0ZWFuZHJlcGxhY2UifX0seyJJIjp7Ik4iOiIxIn0sIm5hbWUiOnsiUyI6InB1dGFuZHVwZGF0ZSJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/ActionsWithCompositeID.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/ActionsWithCompositeID.replay new file mode 100644 index 000000000..e448bf954 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/ActionsWithCompositeID.replay @@ -0,0 +1,759 @@ +{ + "Initial": "AQAAAA7gDLPGM+SsxwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "4989fe3b5ad96ef8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1609" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3233200316" + ], + "X-Amzn-Requestid": [ + "9JMD60A95EREMU2N49D0LQONIJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIkF0dHJpYnV0ZVR5cGUiOiJTIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJBdHRyaWJ1dGVUeXBlIjoiTiJ9LHsiQXR0cmlidXRlTmFtZSI6IlRpbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwODA2OTVFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkdsb2JhbFNlY29uZGFyeUluZGV4ZXMiOlt7IkluZGV4QXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMi9pbmRleC9nbG9iYWwiLCJJbmRleE5hbWUiOiJnbG9iYWwiLCJJbmRleFNpemVCeXRlcyI6MTA3LCJJbmRleFN0YXR1cyI6IkFDVElWRSIsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiUGxheWVyIiwiS2V5VHlwZSI6IkhBU0gifSx7IkF0dHJpYnV0ZU5hbWUiOiJUaW1lIiwiS2V5VHlwZSI6IlJBTkdFIn1dLCJQcm9qZWN0aW9uIjp7IlByb2plY3Rpb25UeXBlIjoiQUxMIn0sIlByb3Zpc2lvbmVkVGhyb3VnaHB1dCI6eyJOdW1iZXJPZkRlY3JlYXNlc1RvZGF5IjowLCJSZWFkQ2FwYWNpdHlVbml0cyI6NSwiV3JpdGVDYXBhY2l0eVVuaXRzIjo1fSwiV2FybVRocm91Z2hwdXQiOnsiUmVhZFVuaXRzUGVyU2Vjb25kIjo1LCJTdGF0dXMiOiJBQ1RJVkUiLCJXcml0ZVVuaXRzUGVyU2Vjb25kIjo1fX1dLCJJdGVtQ291bnQiOjEsIktleVNjaGVtYSI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJLZXlUeXBlIjoiSEFTSCJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIktleVR5cGUiOiJSQU5HRSJ9XSwiTG9jYWxTZWNvbmRhcnlJbmRleGVzIjpbeyJJbmRleEFybiI6ImFybjphd3M6ZHluYW1vZGI6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3Njp0YWJsZS9kb2NzdG9yZS10ZXN0LTIvaW5kZXgvbG9jYWwiLCJJbmRleE5hbWUiOiJsb2NhbCIsIkluZGV4U2l6ZUJ5dGVzIjoxMDcsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiR2FtZSIsIktleVR5cGUiOiJIQVNIIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJLZXlUeXBlIjoiUkFOR0UifV0sIlByb2plY3Rpb24iOnsiUHJvamVjdGlvblR5cGUiOiJBTEwifX1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMiIsIlRhYmxlSWQiOiIwZDRmOTk4My1kOGE5LTRhZjEtYTY0NC05YmE3M2NlMGYyMjciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIiLCJUYWJsZVNpemVCeXRlcyI6MTA3LCJUYWJsZVN0YXR1cyI6IkFDVElWRSIsIldhcm1UaHJvdWdocHV0Ijp7IlJlYWRVbml0c1BlclNlY29uZCI6NSwiU3RhdHVzIjoiQUNUSVZFIiwiV3JpdGVVbml0c1BlclNlY29uZCI6NX19fQ==" + } + }, + { + "ID": "07e338ed0cff6dbf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "207" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1664530721" + ], + "X-Amzn-Requestid": [ + "G2TLDJ9BTTHPOADICSTFEOLA73VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IlRpbWUiOnsiUyI6IjIwMTktMDQtMjVUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoic3RlcGgifSwiU2NvcmUiOnsiTiI6IjI0In0sIkdhbWUiOnsiUyI6IkRheXMgR29uZSJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJjODNjY2M5Ni01OGUzLTQ5YzktYmU3MS1kZjMyMDQ4MTk1Y2UifX1dLCJTY2FubmVkQ291bnQiOjF9" + } + }, + { + "ID": "4181b673f870004c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYzgzY2NjOTYtNThlMy00OWM5LWJlNzEtZGYzMjA0ODE5NWNlIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiRGF5cyBHb25lIn0sIlBsYXllciI6eyJTIjoic3RlcGgifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "REL6O1MFKGIBAEG7QHQH98GLVRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cab62cbff4d516bd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "352" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIwZjU5ZTRhNi0xYWE4LTRlNzUtOTRmYi1kMzk1Njc0NWFjYTEifSwiR2FtZSI6eyJTIjoiMGM0MjBhMWItMjQ4YS00NTQ4LTg3NTQtNmQzMmZhZGEyNmRkIn0sIlBsYXllciI6eyJOVUxMIjp0cnVlfSwiU2NvcmUiOnsiTiI6IjAifSwiVGltZSI6eyJTIjoiMDAwMS0wMS0wMVQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "167" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2041333382" + ], + "X-Amzn-Requestid": [ + "35EKG0MA6Q5VA3OEEJFGLGEHVJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uLmNvcmFsLnZhbGlkYXRlI1ZhbGlkYXRpb25FeGNlcHRpb24iLCJtZXNzYWdlIjoiT25lIG9yIG1vcmUgcGFyYW1ldGVyIHZhbHVlcyB3ZXJlIGludmFsaWQ6IFR5cGUgbWlzbWF0Y2ggZm9yIGtleSBQbGF5ZXIgZXhwZWN0ZWQ6IFMgYWN0dWFsOiBOVUxMIn0=" + } + }, + { + "ID": "516029275f663650", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "235" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImIwMjMzZGEzLWRmMTEtNGU5Ni1iOGJmLTNkMjczMTU4Y2MzMiJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiVGltZSI6eyJTIjoiMjAxOS0wMy0yMFQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "4UC14GDSILI5PDJRN9L97BJJUJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cece38f2ec2ee053", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjkyYzk0N2ZkLWE5ODQtNGI1NS1hMGFiLThmODgyZDIxZWVkOSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTEzVDAwOjAwOjAwWiJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VPP19SN5HJ12MUID2JJ398O677VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "aa4341af0aeda309", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjdmZWVlMmViLTk3ZTYtNDJhZi04YjczLTQzMmUzMDY4MzdmNSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiI2MCJ9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "BK33OFICH6JPM7M8JJA88U0H33VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4ee77501caa6e421", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "244" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjhjODNmNTA3LWIzMDUtNGFmYy1iOTEzLWIyZGQ3ODIwNzYzMCJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiVGltZSI6eyJTIjoiMjAxOS0wMy0xOVQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DNRA91VUJKD2TODKK7CQI5JHQRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "740e552ec3b1ae65", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "244" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImU3ZmM3ZWM2LTYwNjktNDg2Ny04MWVhLTkxZWY2MmM4YTFjMCJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlBsYXllciI6eyJTIjoiYW5keSJ9LCJTY29yZSI6eyJOIjoiODEifSwiVGltZSI6eyJTIjoiMjAxOS0wMi0wMVQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "N91RUJDPNLOBRGVSO005SGC9JBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1692dfc9a7315480", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "238" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjdmYjhlOGNiLTExYTItNDNkOS04OWY4LWJhYWQxODkxZWIyMiJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlBsYXllciI6eyJTIjoiYmlsbGllIn0sIlNjb3JlIjp7Ik4iOiIxMTEifSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "RANKJC6HOJVP9A483SS7JSDNLVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6819590b062b63d4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjBiMGExMTQ5LTYwYjMtNGY2ZS05NWNlLTZkZGQzYTAxNzE5ZSJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiIxOTAifSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xOFQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "J2K9CEVQ20T0KD7777AG1H7CIVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ca027ca5bdde9b69", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImViYjM0OTRkLTgwZjktNDI5My1hNmU5LWNlNTI1NDY5MDMyNCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiIxMjAifSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "G86M5RBICGHB1FB1GL765A0G53VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0c2966132d21fd2f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "504" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0yIjp7IkNvbnNpc3RlbnRSZWFkIjpmYWxzZSwiS2V5cyI6W3siR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9fSx7IkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiUGxheWVyIjp7IlMiOiJtZWwifX0seyJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlBsYXllciI6eyJTIjoiYW5keSJ9fSx7IkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiUGxheWVyIjp7IlMiOiJmcmFuIn19LHsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9fSx7IkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiUGxheWVyIjp7IlMiOiJiaWxsaWUifX0seyJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlBsYXllciI6eyJTIjoibWVsIn19LHsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJQbGF5ZXIiOnsiUyI6ImZyYW4ifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1667" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2679106520" + ], + "X-Amzn-Requestid": [ + "JS0IO9RB9097AUAH2BU32L5M1NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0yIjpbeyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wMy0yMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJmcmFuIn0sIlNjb3JlIjp7Ik4iOiIzMyJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImIwMjMzZGEzLWRmMTEtNGU5Ni1iOGJmLTNkMjczMTU4Y2MzMiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZTdmYzdlYzYtNjA2OS00ODY3LTgxZWEtOTFlZjYyYzhhMWMwIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMTBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiI2MCJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjdmZWVlMmViLTk3ZTYtNDJhZi04YjczLTQzMmUzMDY4MzdmNSJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiN2ZiOGU4Y2ItMTFhMi00M2Q5LTg5ZjgtYmFhZDE4OTFlYjIyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjkyYzk0N2ZkLWE5ODQtNGI1NS1hMGFiLThmODgyZDIxZWVkOSJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6dHJ1ZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMDFUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiIxMjAifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlYmIzNDk0ZC04MGY5LTQyOTMtYTZlOS1jZTUyNTQ2OTAzMjQifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wMy0xOVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJmcmFuIn0sIlNjb3JlIjp7Ik4iOiIzMyJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjhjODNmNTA3LWIzMDUtNGFmYy1iOTEzLWIyZGQ3ODIwNzYzMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6dHJ1ZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMThUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiIxOTAifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIwYjBhMTE0OS02MGIzLTRmNmUtOTVjZS02ZGRkM2EwMTcxOWUifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As.replay new file mode 100644 index 000000000..83fc9beba --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As.replay @@ -0,0 +1,814 @@ +{ + "Initial": "AQAAAA7gDLPLKWlHaAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "915533ce6f27e5af", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1609" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3233200316" + ], + "X-Amzn-Requestid": [ + "21ERC72RT8B7HH2AJVN0MA7S2VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIkF0dHJpYnV0ZVR5cGUiOiJTIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJBdHRyaWJ1dGVUeXBlIjoiTiJ9LHsiQXR0cmlidXRlTmFtZSI6IlRpbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwODA2OTVFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkdsb2JhbFNlY29uZGFyeUluZGV4ZXMiOlt7IkluZGV4QXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMi9pbmRleC9nbG9iYWwiLCJJbmRleE5hbWUiOiJnbG9iYWwiLCJJbmRleFNpemVCeXRlcyI6MTA3LCJJbmRleFN0YXR1cyI6IkFDVElWRSIsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiUGxheWVyIiwiS2V5VHlwZSI6IkhBU0gifSx7IkF0dHJpYnV0ZU5hbWUiOiJUaW1lIiwiS2V5VHlwZSI6IlJBTkdFIn1dLCJQcm9qZWN0aW9uIjp7IlByb2plY3Rpb25UeXBlIjoiQUxMIn0sIlByb3Zpc2lvbmVkVGhyb3VnaHB1dCI6eyJOdW1iZXJPZkRlY3JlYXNlc1RvZGF5IjowLCJSZWFkQ2FwYWNpdHlVbml0cyI6NSwiV3JpdGVDYXBhY2l0eVVuaXRzIjo1fSwiV2FybVRocm91Z2hwdXQiOnsiUmVhZFVuaXRzUGVyU2Vjb25kIjo1LCJTdGF0dXMiOiJBQ1RJVkUiLCJXcml0ZVVuaXRzUGVyU2Vjb25kIjo1fX1dLCJJdGVtQ291bnQiOjEsIktleVNjaGVtYSI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJLZXlUeXBlIjoiSEFTSCJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIktleVR5cGUiOiJSQU5HRSJ9XSwiTG9jYWxTZWNvbmRhcnlJbmRleGVzIjpbeyJJbmRleEFybiI6ImFybjphd3M6ZHluYW1vZGI6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3Njp0YWJsZS9kb2NzdG9yZS10ZXN0LTIvaW5kZXgvbG9jYWwiLCJJbmRleE5hbWUiOiJsb2NhbCIsIkluZGV4U2l6ZUJ5dGVzIjoxMDcsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiR2FtZSIsIktleVR5cGUiOiJIQVNIIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJLZXlUeXBlIjoiUkFOR0UifV0sIlByb2plY3Rpb24iOnsiUHJvamVjdGlvblR5cGUiOiJBTEwifX1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMiIsIlRhYmxlSWQiOiIwZDRmOTk4My1kOGE5LTRhZjEtYTY0NC05YmE3M2NlMGYyMjciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIiLCJUYWJsZVNpemVCeXRlcyI6MTA3LCJUYWJsZVN0YXR1cyI6IkFDVElWRSIsIldhcm1UaHJvdWdocHV0Ijp7IlJlYWRVbml0c1BlclNlY29uZCI6NSwiU3RhdHVzIjoiQUNUSVZFIiwiV3JpdGVVbml0c1BlclNlY29uZCI6NX19fQ==" + } + }, + { + "ID": "351976f346c9916e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "AUH1P3NTII19CKEMONAUOFV963VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "36c42cb628b08b04", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "260" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYmFlMTJmODQtODE3MS00MDA5LThiMDYtN2EzYTgyYzFiZjA4In19LCJLZXkiOnsiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6B5JDL50AF1RSJBQCPGTH8D3JBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6d2a6a3e9def579d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "2EJSOOG3IRCHOSE73S6VQS3KARVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "dc9c287eb8b2ceaf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "260" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "D67MDN0RCESC8UUIIO24QLOM3JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a717d8aff5a960bf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0N4T4KNIUGFT2OGNG2VTR04U1BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e26adb201c81ef4f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "261" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8A7E5RCKNBTJ0A5M64NFGADFGRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2d1f38cdaa1f9d12", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZjBiNTY4ZmYtMGFjNC00ODRkLWE2MGUtZmRiN2Y3MDIzN2E2In19LCJLZXkiOnsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "2DNDSDGBNCQ116OOHNK65B188RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "85831026ff483664", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "261" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiN2U4NzY0N2MtNGJhNy00NjY0LTgxNzYtOWRlM2ZjY2EyZWY1In19LCJLZXkiOnsiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJQbGF5ZXIiOnsiUyI6ImZyYW4ifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "4GSF7CHMV8FUM465FFMPVTPCH3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "db5dcb1e459c90c2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZWVhZjE2MDEtMDFmNC00MGNiLTljYzEtODBiOTY3YjIwYjRjIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJQbGF5ZXIiOnsiUyI6ImZyYW4ifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3N1GHK1KN2L9THO5KUMPT75PRRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "44aea875ddfa50f4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "183" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiRGF5cyBHb25lIn19LCJLZXlDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "RD4VGNO53D6TLHJ5STDSU02GUJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "0dcd7391d56f0230", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IlNjb3JlIn0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiTiI6IjUwIn19LCJGaWx0ZXJFeHByZXNzaW9uIjoiIzAgPiA6MCIsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "AD0JV2H6RVTSOLGOC31U3IDHONVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "70e157542fb29539", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "326" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJjZDJjODk0NS1kMmU3LTRlNTAtYWVkMi0yZmFmNmNjZjVhMmMifSwiR2FtZSI6eyJTIjoiRGF5cyBHb25lIn0sIlBsYXllciI6eyJTIjoic3RlcGgifSwiU2NvcmUiOnsiTiI6IjI0In0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMjVUMDA6MDA6MDBaIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9T9KTP8AN2M147OLAVL52L4GJRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b9cf8d2923922b32", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "326" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJkYzkzNGJlOS00NDhjLTQxMDEtOWU5MS00ODU4MjI5NDkzNmUifSwiR2FtZSI6eyJTIjoiRGF5cyBHb25lIn0sIlBsYXllciI6eyJTIjoic3RlcGgifSwiU2NvcmUiOnsiTiI6IjI0In0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMjVUMDA6MDA6MDBaIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "K7CMQDOBT79S39QN2AV2DFBOB3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As.yaml b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As.yaml new file mode 100644 index 000000000..0e26b211b --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As.yaml @@ -0,0 +1,244 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"docstore-test-2"}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "31" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125305Z + X-Amz-Target: + - DynamoDB_20120810.DescribeTable + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{"Table":{"AttributeDefinitions":[{"AttributeName":"Game","AttributeType":"S"},{"AttributeName":"Player","AttributeType":"S"},{"AttributeName":"Score","AttributeType":"N"},{"AttributeName":"Time","AttributeType":"S"}],"CreationDateTime":1.556147916461E9,"GlobalSecondaryIndexes":[{"IndexArn":"arn:aws:dynamodb:us-east-2:462380225722:table/docstore-test-2/index/global","IndexName":"global","IndexSizeBytes":212,"IndexStatus":"ACTIVE","ItemCount":2,"KeySchema":[{"AttributeName":"Player","KeyType":"HASH"},{"AttributeName":"Time","KeyType":"RANGE"}],"Projection":{"ProjectionType":"ALL"},"ProvisionedThroughput":{"NumberOfDecreasesToday":0,"ReadCapacityUnits":5,"WriteCapacityUnits":5}}],"ItemCount":2,"KeySchema":[{"AttributeName":"Game","KeyType":"HASH"},{"AttributeName":"Player","KeyType":"RANGE"}],"LocalSecondaryIndexes":[{"IndexArn":"arn:aws:dynamodb:us-east-2:462380225722:table/docstore-test-2/index/local","IndexName":"local","IndexSizeBytes":212,"ItemCount":2,"KeySchema":[{"AttributeName":"Game","KeyType":"HASH"},{"AttributeName":"Score","KeyType":"RANGE"}],"Projection":{"ProjectionType":"ALL"}}],"ProvisionedThroughput":{"NumberOfDecreasesToday":0,"ReadCapacityUnits":5,"WriteCapacityUnits":5},"TableArn":"arn:aws:dynamodb:us-east-2:462380225722:table/docstore-test-2","TableId":"5c4c6014-7e6a-4db7-93de-a174552cf78d","TableName":"docstore-test-2","TableSizeBytes":266,"TableStatus":"ACTIVE"}}' + headers: + Connection: + - keep-alive + Content-Length: + - "1407" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:05 GMT + Server: + - Server + X-Amz-Crc32: + - "325584166" + X-Amzn-Requestid: + - GJ97UPS5OS6KIT0DJRNFI0UH73VV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"ClientRequestToken":"7d7ad684-7b3d-461a-b6d5-4be758ee986a","TransactItems":[{"Put":{"Item":{"DocstoreRevision":{"S":"2fd2d1fd-c1ce-46d7-b335-258215f94f2f"},"Game":{"S":"Days + Gone"},"Player":{"S":"steph"},"Score":{"N":"24"},"Time":{"S":"2019-04-25T00:00:00Z"}},"TableName":"docstore-test-2"}},{"Put":{"Item":{"DocstoreRevision":{"S":"eb43aab0-5a21-4f65-b604-2ac5e32f3606"},"Game":{"S":"Days + Gone"},"Player":{"S":"mia"},"Score":{"N":"99"},"Time":{"S":"2019-04-26T00:00:00Z"}},"TableName":"docstore-test-2"}}]}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "509" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125305Z + X-Amz-Target: + - DynamoDB_20120810.TransactWriteItems + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{}' + headers: + Connection: + - keep-alive + Content-Length: + - "2" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:05 GMT + Server: + - Server + X-Amz-Crc32: + - "2745614147" + X-Amzn-Requestid: + - K4JNLM37EL1D58TPSLOH7NL99FVV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"ConsistentRead":true,"ExpressionAttributeNames":{"#0":"Game"},"ExpressionAttributeValues":{":0":{"S":"Days + Gone"}},"KeyConditionExpression":"#0 = :0","TableName":"docstore-test-2"}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "182" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125305Z + X-Amz-Target: + - DynamoDB_20120810.Query + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{"Count":2,"Items":[{"Time":{"S":"2019-04-26T00:00:00Z"},"Player":{"S":"mia"},"Score":{"N":"99"},"Game":{"S":"Days + Gone"},"DocstoreRevision":{"S":"eb43aab0-5a21-4f65-b604-2ac5e32f3606"}},{"Time":{"S":"2019-04-25T00:00:00Z"},"Player":{"S":"steph"},"Score":{"N":"24"},"Game":{"S":"Days + Gone"},"DocstoreRevision":{"S":"2fd2d1fd-c1ce-46d7-b335-258215f94f2f"}}],"ScannedCount":2}' + headers: + Connection: + - keep-alive + Content-Length: + - "374" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:05 GMT + Server: + - Server + X-Amz-Crc32: + - "3144266929" + X-Amzn-Requestid: + - F1EB7Q9TIHJKFD16JBPFL8M5I3VV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"ConsistentRead":true,"ExpressionAttributeNames":{"#0":"Score"},"ExpressionAttributeValues":{":0":{"N":"50"}},"FilterExpression":"#0 + > :0","TableName":"docstore-test-2"}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "170" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125306Z + X-Amz-Target: + - DynamoDB_20120810.Scan + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{"Count":1,"Items":[{"Time":{"S":"2019-04-26T00:00:00Z"},"Player":{"S":"mia"},"Score":{"N":"99"},"Game":{"S":"Days + Gone"},"DocstoreRevision":{"S":"eb43aab0-5a21-4f65-b604-2ac5e32f3606"}}],"ScannedCount":2}' + headers: + Connection: + - keep-alive + Content-Length: + - "205" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:05 GMT + Server: + - Server + X-Amz-Crc32: + - "2965315507" + X-Amzn-Requestid: + - U96606SLHKOQ3FCJFN03BI8OGRVV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"TableName":"docstore-test-2"}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "31" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125306Z + X-Amz-Target: + - DynamoDB_20120810.Scan + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{"Count":2,"Items":[{"Time":{"S":"2019-04-26T00:00:00Z"},"Player":{"S":"mia"},"Score":{"N":"99"},"Game":{"S":"Days + Gone"},"DocstoreRevision":{"S":"eb43aab0-5a21-4f65-b604-2ac5e32f3606"}},{"Time":{"S":"2019-04-25T00:00:00Z"},"Player":{"S":"steph"},"Score":{"N":"24"},"Game":{"S":"Days + Gone"},"DocstoreRevision":{"S":"2fd2d1fd-c1ce-46d7-b335-258215f94f2f"}}],"ScannedCount":2}' + headers: + Connection: + - keep-alive + Content-Length: + - "374" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:05 GMT + Server: + - Server + X-Amz-Crc32: + - "3144266929" + X-Amzn-Requestid: + - HOOQ68CQH3FTI7RDS77VE03FHFVV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"ClientRequestToken":"b36a96df-94a3-42ae-ad52-e65302cd8847","TransactItems":[{"Delete":{"ConditionExpression":"#0 + = :0","ExpressionAttributeNames":{"#0":"DocstoreRevision"},"ExpressionAttributeValues":{":0":{"S":"eb43aab0-5a21-4f65-b604-2ac5e32f3606"}},"Key":{"Game":{"S":"Days + Gone"},"Player":{"S":"mia"}},"TableName":"docstore-test-2"}},{"Delete":{"ConditionExpression":"#0 + = :0","ExpressionAttributeNames":{"#0":"DocstoreRevision"},"ExpressionAttributeValues":{":0":{"S":"2fd2d1fd-c1ce-46d7-b335-258215f94f2f"}},"Key":{"Game":{"S":"Days + Gone"},"Player":{"S":"steph"}},"TableName":"docstore-test-2"}}]}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "605" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125306Z + X-Amz-Target: + - DynamoDB_20120810.TransactWriteItems + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{}' + headers: + Connection: + - keep-alive + Content-Length: + - "2" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:05 GMT + Server: + - Server + X-Amz-Crc32: + - "2745614147" + X-Amzn-Requestid: + - BBQ9E7M0KLRHJS47UNLLA4FIPNVV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..4966ca848 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,429 @@ +{ + "Initial": "AQAAAA7gDLPMGFIk5AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "44d2a13517ad9a64", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1609" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3233200316" + ], + "X-Amzn-Requestid": [ + "NAHM9G3JHPIJO5JTDURPRD4323VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIkF0dHJpYnV0ZVR5cGUiOiJTIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJBdHRyaWJ1dGVUeXBlIjoiTiJ9LHsiQXR0cmlidXRlTmFtZSI6IlRpbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwODA2OTVFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkdsb2JhbFNlY29uZGFyeUluZGV4ZXMiOlt7IkluZGV4QXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMi9pbmRleC9nbG9iYWwiLCJJbmRleE5hbWUiOiJnbG9iYWwiLCJJbmRleFNpemVCeXRlcyI6MTA3LCJJbmRleFN0YXR1cyI6IkFDVElWRSIsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiUGxheWVyIiwiS2V5VHlwZSI6IkhBU0gifSx7IkF0dHJpYnV0ZU5hbWUiOiJUaW1lIiwiS2V5VHlwZSI6IlJBTkdFIn1dLCJQcm9qZWN0aW9uIjp7IlByb2plY3Rpb25UeXBlIjoiQUxMIn0sIlByb3Zpc2lvbmVkVGhyb3VnaHB1dCI6eyJOdW1iZXJPZkRlY3JlYXNlc1RvZGF5IjowLCJSZWFkQ2FwYWNpdHlVbml0cyI6NSwiV3JpdGVDYXBhY2l0eVVuaXRzIjo1fSwiV2FybVRocm91Z2hwdXQiOnsiUmVhZFVuaXRzUGVyU2Vjb25kIjo1LCJTdGF0dXMiOiJBQ1RJVkUiLCJXcml0ZVVuaXRzUGVyU2Vjb25kIjo1fX1dLCJJdGVtQ291bnQiOjEsIktleVNjaGVtYSI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJLZXlUeXBlIjoiSEFTSCJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIktleVR5cGUiOiJSQU5HRSJ9XSwiTG9jYWxTZWNvbmRhcnlJbmRleGVzIjpbeyJJbmRleEFybiI6ImFybjphd3M6ZHluYW1vZGI6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3Njp0YWJsZS9kb2NzdG9yZS10ZXN0LTIvaW5kZXgvbG9jYWwiLCJJbmRleE5hbWUiOiJsb2NhbCIsIkluZGV4U2l6ZUJ5dGVzIjoxMDcsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiR2FtZSIsIktleVR5cGUiOiJIQVNIIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJLZXlUeXBlIjoiUkFOR0UifV0sIlByb2plY3Rpb24iOnsiUHJvamVjdGlvblR5cGUiOiJBTEwifX1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMiIsIlRhYmxlSWQiOiIwZDRmOTk4My1kOGE5LTRhZjEtYTY0NC05YmE3M2NlMGYyMjciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIiLCJUYWJsZVNpemVCeXRlcyI6MTA3LCJUYWJsZVN0YXR1cyI6IkFDVElWRSIsIldhcm1UaHJvdWdocHV0Ijp7IlJlYWRVbml0c1BlclNlY29uZCI6NSwiU3RhdHVzIjoiQUNUSVZFIiwiV3JpdGVVbml0c1BlclNlY29uZCI6NX19fQ==" + } + }, + { + "ID": "6d4c6025fcb9046c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "235" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3763226110" + ], + "X-Amzn-Requestid": [ + "LSSMH9NTUST8KTEKTOIMSKTUMFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTI1VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InN0ZXBoIn0sIlNjb3JlIjp7Ik4iOiIyNCJ9LCJHYW1lIjp7IlMiOiJEYXlzIEdvbmUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiY2QyYzg5NDUtZDJlNy00ZTUwLWFlZDItMmZhZjZjY2Y1YTJjIn19XSwiU2Nhbm5lZENvdW50IjoxfQ==" + } + }, + { + "ID": "8d0e29ff6563833d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiY2QyYzg5NDUtZDJlNy00ZTUwLWFlZDItMmZhZjZjY2Y1YTJjIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiRGF5cyBHb25lIn0sIlBsYXllciI6eyJTIjoic3RlcGgifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MBDASL6HJA6663RHG7RQU6KS8RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f876f6baaaf9ecaa", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "183" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiRGF5cyBHb25lIn19LCJLZXlDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "QDJ25Q5F1DGGA1PCDAQ63LDQANVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "a464c8c56a22b08a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IlNjb3JlIn0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiTiI6IjUwIn19LCJGaWx0ZXJFeHByZXNzaW9uIjoiIzAgPiA6MCIsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "KBVDCOBLTGE6R51UL5G58NVJ6FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "b179b0ad91b2255c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "326" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI1YmNjMjc3MC0xYTkwLTQxYmMtOGM2My03MmRkM2M5NTU3ZTMifSwiR2FtZSI6eyJTIjoiRGF5cyBHb25lIn0sIlBsYXllciI6eyJTIjoic3RlcGgifSwiU2NvcmUiOnsiTiI6IjI0In0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMjVUMDA6MDA6MDBaIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "NK97L3TDHB38T10I6B5I25PB4JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9df167585357c592", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "326" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhYTAxZTJiYy1iNjNiLTQ5YzQtODA5ZC03NWNmZWM0MWEwZjQifSwiR2FtZSI6eyJTIjoiRGF5cyBHb25lIn0sIlBsYXllciI6eyJTIjoic3RlcGgifSwiU2NvcmUiOnsiTiI6IjI0In0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMjVUMDA6MDA6MDBaIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "8KVVDIBHKTB9T439JVKTPU1GE7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.yaml b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.yaml new file mode 100644 index 000000000..2c537bf55 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.yaml @@ -0,0 +1,244 @@ +--- +version: 1 +interactions: +- request: + body: '{"TableName":"docstore-test-2"}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "31" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125306Z + X-Amz-Target: + - DynamoDB_20120810.DescribeTable + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{"Table":{"AttributeDefinitions":[{"AttributeName":"Game","AttributeType":"S"},{"AttributeName":"Player","AttributeType":"S"},{"AttributeName":"Score","AttributeType":"N"},{"AttributeName":"Time","AttributeType":"S"}],"CreationDateTime":1.556147916461E9,"GlobalSecondaryIndexes":[{"IndexArn":"arn:aws:dynamodb:us-east-2:462380225722:table/docstore-test-2/index/global","IndexName":"global","IndexSizeBytes":212,"IndexStatus":"ACTIVE","ItemCount":2,"KeySchema":[{"AttributeName":"Player","KeyType":"HASH"},{"AttributeName":"Time","KeyType":"RANGE"}],"Projection":{"ProjectionType":"ALL"},"ProvisionedThroughput":{"NumberOfDecreasesToday":0,"ReadCapacityUnits":5,"WriteCapacityUnits":5}}],"ItemCount":2,"KeySchema":[{"AttributeName":"Game","KeyType":"HASH"},{"AttributeName":"Player","KeyType":"RANGE"}],"LocalSecondaryIndexes":[{"IndexArn":"arn:aws:dynamodb:us-east-2:462380225722:table/docstore-test-2/index/local","IndexName":"local","IndexSizeBytes":212,"ItemCount":2,"KeySchema":[{"AttributeName":"Game","KeyType":"HASH"},{"AttributeName":"Score","KeyType":"RANGE"}],"Projection":{"ProjectionType":"ALL"}}],"ProvisionedThroughput":{"NumberOfDecreasesToday":0,"ReadCapacityUnits":5,"WriteCapacityUnits":5},"TableArn":"arn:aws:dynamodb:us-east-2:462380225722:table/docstore-test-2","TableId":"5c4c6014-7e6a-4db7-93de-a174552cf78d","TableName":"docstore-test-2","TableSizeBytes":266,"TableStatus":"ACTIVE"}}' + headers: + Connection: + - keep-alive + Content-Length: + - "1407" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:06 GMT + Server: + - Server + X-Amz-Crc32: + - "325584166" + X-Amzn-Requestid: + - V5J8K6UCUUM9AS846K5M8P5IR7VV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"ClientRequestToken":"961acd1e-44bb-4ace-8e9f-5244d42df229","TransactItems":[{"Put":{"Item":{"DocstoreRevision":{"S":"303beac7-02de-49b9-b82a-fc1b83d532c1"},"Game":{"S":"Days + Gone"},"Player":{"S":"steph"},"Score":{"N":"24"},"Time":{"S":"2019-04-25T00:00:00Z"}},"TableName":"docstore-test-2"}},{"Put":{"Item":{"DocstoreRevision":{"S":"762f11fe-9de1-4d3a-a55d-a4adca89663e"},"Game":{"S":"Days + Gone"},"Player":{"S":"mia"},"Score":{"N":"99"},"Time":{"S":"2019-04-26T00:00:00Z"}},"TableName":"docstore-test-2"}}]}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "509" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125306Z + X-Amz-Target: + - DynamoDB_20120810.TransactWriteItems + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{}' + headers: + Connection: + - keep-alive + Content-Length: + - "2" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:06 GMT + Server: + - Server + X-Amz-Crc32: + - "2745614147" + X-Amzn-Requestid: + - 4G02U9ME82551GFGQNK4LU4DFJVV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"ExpressionAttributeNames":{"#0":"Game"},"ExpressionAttributeValues":{":0":{"S":"Days + Gone"}},"KeyConditionExpression":"#0 = :0","TableName":"docstore-test-2"}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "160" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125306Z + X-Amz-Target: + - DynamoDB_20120810.Query + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{"Count":2,"Items":[{"Time":{"S":"2019-04-26T00:00:00Z"},"Player":{"S":"mia"},"Score":{"N":"99"},"Game":{"S":"Days + Gone"},"DocstoreRevision":{"S":"762f11fe-9de1-4d3a-a55d-a4adca89663e"}},{"Time":{"S":"2019-04-25T00:00:00Z"},"Player":{"S":"steph"},"Score":{"N":"24"},"Game":{"S":"Days + Gone"},"DocstoreRevision":{"S":"303beac7-02de-49b9-b82a-fc1b83d532c1"}}],"ScannedCount":2}' + headers: + Connection: + - keep-alive + Content-Length: + - "374" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:06 GMT + Server: + - Server + X-Amz-Crc32: + - "3008081910" + X-Amzn-Requestid: + - P4K0RDNU12G46IVV0RFCN2AVBVVV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"ExpressionAttributeNames":{"#0":"Score"},"ExpressionAttributeValues":{":0":{"N":"50"}},"FilterExpression":"#0 + > :0","TableName":"docstore-test-2"}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "148" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125306Z + X-Amz-Target: + - DynamoDB_20120810.Scan + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{"Count":1,"Items":[{"Time":{"S":"2019-04-26T00:00:00Z"},"Player":{"S":"mia"},"Score":{"N":"99"},"Game":{"S":"Days + Gone"},"DocstoreRevision":{"S":"762f11fe-9de1-4d3a-a55d-a4adca89663e"}}],"ScannedCount":2}' + headers: + Connection: + - keep-alive + Content-Length: + - "205" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:06 GMT + Server: + - Server + X-Amz-Crc32: + - "3718331234" + X-Amzn-Requestid: + - QTC1AIK7LGQOK55V51P8UN8OIJVV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"TableName":"docstore-test-2"}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "31" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125306Z + X-Amz-Target: + - DynamoDB_20120810.Scan + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{"Count":2,"Items":[{"Time":{"S":"2019-04-26T00:00:00Z"},"Player":{"S":"mia"},"Score":{"N":"99"},"Game":{"S":"Days + Gone"},"DocstoreRevision":{"S":"762f11fe-9de1-4d3a-a55d-a4adca89663e"}},{"Time":{"S":"2019-04-25T00:00:00Z"},"Player":{"S":"steph"},"Score":{"N":"24"},"Game":{"S":"Days + Gone"},"DocstoreRevision":{"S":"303beac7-02de-49b9-b82a-fc1b83d532c1"}}],"ScannedCount":2}' + headers: + Connection: + - keep-alive + Content-Length: + - "374" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:06 GMT + Server: + - Server + X-Amz-Crc32: + - "3008081910" + X-Amzn-Requestid: + - TU5BNC2AJN3BHBTDJTGML67I07VV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"ClientRequestToken":"cc182671-10dd-412a-a86b-42bdaf130679","TransactItems":[{"Delete":{"ConditionExpression":"#0 + = :0","ExpressionAttributeNames":{"#0":"DocstoreRevision"},"ExpressionAttributeValues":{":0":{"S":"762f11fe-9de1-4d3a-a55d-a4adca89663e"}},"Key":{"Game":{"S":"Days + Gone"},"Player":{"S":"mia"}},"TableName":"docstore-test-2"}},{"Delete":{"ConditionExpression":"#0 + = :0","ExpressionAttributeNames":{"#0":"DocstoreRevision"},"ExpressionAttributeValues":{":0":{"S":"303beac7-02de-49b9-b82a-fc1b83d532c1"}},"Key":{"Game":{"S":"Days + Gone"},"Player":{"S":"steph"}},"TableName":"docstore-test-2"}}]}' + form: {} + headers: + Accept-Encoding: + - identity + Content-Length: + - "605" + Content-Type: + - application/x-amz-json-1.0 + User-Agent: + - aws-sdk-go/1.19.16 (go1.12; linux; amd64) + X-Amz-Date: + - 20190502T125306Z + X-Amz-Target: + - DynamoDB_20120810.TransactWriteItems + url: https://dynamodb.us-east-2.amazonaws.com/ + method: POST + response: + body: '{}' + headers: + Connection: + - keep-alive + Content-Length: + - "2" + Content-Type: + - application/x-amz-json-1.0 + Date: + - Thu, 02 May 2019 12:53:06 GMT + Server: + - Server + X-Amz-Crc32: + - "2745614147" + X-Amzn-Requestid: + - 0PK493UFTE8VM6QN04JD9JKSRBVV4KQNSO5AEMVJF66Q9ASUAAJG + status: 200 OK + code: 200 + duration: "" diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/AtomicWrites.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/AtomicWrites.replay new file mode 100644 index 000000000..ee19f5767 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/AtomicWrites.replay @@ -0,0 +1,2739 @@ +{ + "Initial": "AQAAAA7gDLOuLHoq/gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "a6b30b7eb1d5cc8b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "E4S353NNO8OQ974D2C7JTAAVGRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "964b9a7979681a19", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "951" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1532720799" + ], + "X-Amzn-Requestid": [ + "M8QNSBRB26VR8SJODNQETC001RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7IkIiOnsiQk9PTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiJjYWUwNjFkMC04NjA3LTQyY2ItYmYxMC0xYThkMzA2YWNlNDIifSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdENyZWF0ZVN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fSx7IkIiOnsiQk9PTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiI5ZjdjZmFhYS01MmQzLTRjM2UtODE3My02NGM5ZWZjZDZmNGYifSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoiZGE2MTY4ODctYmM2YS00NzczLTk3NWYtOGZjY2VmYzAyYTBkIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19LHsiRXRhZyI6eyJTIjoiNDFmZjkyYmUtODg1ZC00NjkzLWI5MmMtY2E0YjhkYmU5YjE3In0sIm5hbWUiOnsiUyI6InRlc3RDcmVhdGVNYXAifSwiYiI6eyJCT09MIjp0cnVlfX0seyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiNTZmZTQ4N2MtZWU4Ni00ZDU3LTk0NGQtOTBlMGY1NTcxODVmIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6IjlkMDBkYTQxLWRkZjQtNDY2My05ZmQzLWM0N2MzZjlmOTViMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fSx7IkV0YWciOnsiUyI6ImRkMmU5MThiLTBjYzEtNGEyOS04MTczLWYwYTgxMDZkYmFlMyJ9LCJuYW1lIjp7IlMiOiJiOTk2ZmYxMy05OWFmLTRiNTYtYjQ3Ni0xOTA0NTIxOTJkYzYifSwiYiI6eyJCT09MIjp0cnVlfX1dLCJTY2FubmVkQ291bnQiOjV9" + } + }, + { + "ID": "036318b690400382", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoiYjk5NmZmMTMtOTlhZi00YjU2LWI0NzYtMTkwNDUyMTkyZGM2In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UBLJP513KAOVPUF90UCT17EGARVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "638f2e485006bc88", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoiZGE2MTY4ODctYmM2YS00NzczLTk3NWYtOGZjY2VmYzAyYTBkIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "D4QRAF8LLBHOP5RE89L7U71LP7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e171d15b5aebfbc3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoiOWQwMGRhNDEtZGRmNC00NjYzLTlmZDMtYzQ3YzNmOWY5NWIzIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5EMQU6K7DOUO3AL54VRI15QBRVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8e62cfdc9f4a2471", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdENyZWF0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MVRF5I98OQHGGFLE0N87LAGMN3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6f171c5e6927e0f4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdENyZWF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "1JIQ751N51E61Q7NNQPK9S3HF3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3c2372147027bd96", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZmJlZGJlOC00ODFlLTRkMWEtYTFkNy1hYzBhOTVmNWI1ODAifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczgifSwicyI6eyJTIjoiOCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SU43V1VA0EASUHCDKKBOKJRU63VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4d1657167356f600", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhNTIyZGJlZS01ZTMyLTQyNmYtOTE5MC04ZjQ3MTZlYWE0NmMifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifSwicyI6eyJTIjoiMyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PV7V9PDB74NGAUC8F2QOSC5S87VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f58ab03aea4b0f09", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhOGYwY2RkNy03MDZhLTRiYmUtODcxNi0yMDE4NGUwZjY3ZTAifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczEifSwicyI6eyJTIjoiMSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MIQCRCNTRNT42D51FGFQA20AGRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ff116a58d21c63a8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4NGIyMTk3ZS02ZmRkLTRmMzktYWI1MC1jMmJhYWI0MmYwMDIifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczAifSwicyI6eyJTIjoiMCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "86VI29LUOQ6AJD6MJ7G3HG5K2JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2fa51464078fabdc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIxZDNkNzgzZS01NzdjLTQxZGUtOTk5Zi1hYjRlMjE0YjgxNzMifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifSwicyI6eyJTIjoiNyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TFPR0D2V7IOALBIRDULN65VL93VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7e9944c8ace7e69f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4NTlmNDZhNy05MWQ3LTQ1MzQtYTllZi1lYTE0ZTViNDY5YWIifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwicyI6eyJTIjoiNSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "BEFNM9OI4H5830CE3EAB3G745NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3f9b3e16b9fcebd4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlMmFkOWFjNC1kN2YxLTQ3ZTgtOTYzNC05OTY3MjgzYjQ1OTEifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifSwicyI6eyJTIjoiNCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3TM7A9VCI7192ONGR46OTME7H7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0ff7f29eb708406b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3NzEyOTk1ZC1iNjVjLTQ3Y2QtOGY5ZS03OWY0ZDY3ZjhiOWUifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwicyI6eyJTIjoiNiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FQNRQET0CSSDBJS8UK1VE4B2F3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "51570d7cd9f5447b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiZWViY2Y4MC1mNWQxLTQ2MGQtOGIzZC0xZmJhMzg2NGFiMmUifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczIifSwicyI6eyJTIjoiMiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SLPDUFILHRPUUS7F778MKHLJR3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3b3efeb22769afef", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "174" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "395" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2015364000" + ], + "X-Amzn-Requestid": [ + "IVF20ERD5CV3OG4BQN7JQN5DRNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhNTIyZGJlZS01ZTMyLTQyNmYtOTE5MC04ZjQ3MTZlYWE0NmMifSwicyI6eyJTIjoiMyJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImUyYWQ5YWM0LWQ3ZjEtNDdlOC05NjM0LTk5NjcyODNiNDU5MSJ9LCJzIjp7IlMiOiI0In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiODU5ZjQ2YTctOTFkNy00NTM0LWE5ZWYtZWExNGU1YjQ2OWFiIn0sInMiOnsiUyI6IjUifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "49fbefff5fbc9ac0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYmVlYmNmODAtZjVkMS00NjBkLThiM2QtMWZiYTM4NjRhYjJlIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczIifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GFH7C87C0V4KL2DI17CAIFNC1FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0b458fa892ff1f87", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "1183" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.TransactWriteItems" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJkOTA0M2M0My05NjExLTQwZjctYmMzMy0yMjEzMTY0YTM2YTQiLCJUcmFuc2FjdEl0ZW1zIjpbeyJVcGRhdGUiOnsiQ29uZGl0aW9uRXhwcmVzc2lvbiI6IiMwID0gOjAiLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJEb2NzdG9yZVJldmlzaW9uIiwiIzEiOiJzIn0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiUyI6Ijc3MTI5OTVkLWI2NWMtNDdjZC04ZjllLTc5ZjRkNjdmOGI5ZSJ9LCI6MSI6eyJTIjoiNjYifSwiOjIiOnsiUyI6ImE1Y2JmZDczLWQ5NmEtNGMxNS05MjRjLTkxZTBkMGU1YTFlYyJ9fSwiS2V5Ijp7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM2In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiU0VUICMxID0gOjEsICMwID0gOjJcbiJ9fSx7IlVwZGF0ZSI6eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24iLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMWQzZDc4M2UtNTc3Yy00MWRlLTk5OWYtYWI0ZTIxNGI4MTczIn0sIjoxIjp7IlMiOiI3NyJ9LCI6MiI6eyJTIjoiZTgwNzFmN2ItMDdhMi00YzViLTk4YWUtMGM3MzViMzliODk3In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn19LHsiVXBkYXRlIjp7IkNvbmRpdGlvbkV4cHJlc3Npb24iOiIjMCA9IDowIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoiRG9jc3RvcmVSZXZpc2lvbiIsIiMxIjoicyJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiI3ZmJlZGJlOC00ODFlLTRkMWEtYTFkNy1hYzBhOTVmNWI1ODAifSwiOjEiOnsiUyI6Ijg4In0sIjoyIjp7IlMiOiI3ZTQ4ZGY2ZS0yZTZlLTQyYzMtYjUwOC1lNGIwNDgxYTZjMTEifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzOCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIiwiVXBkYXRlRXhwcmVzc2lvbiI6IlNFVCAjMSA9IDoxLCAjMCA9IDoyXG4ifX1dfQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "I636S1TKO05EI4KSJNJLHT5UQVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cbcd9fbfb07375e1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiODRiMjE5N2UtNmZkZC00ZjM5LWFiNTAtYzJiYWFiNDJmMDAyIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "BDEFI4F3TV53Q6MRJ21OMLN387VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1eb0d96483fd9009", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYThmMGNkZDctNzA2YS00YmJlLTg3MTYtMjAxODRlMGY2N2UwIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczEifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7OG5L79CD1R47ROB075119GO73VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9635faf6d4563a5d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNiJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "170" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4109450000" + ], + "X-Amzn-Requestid": [ + "JQ350S3JNTILQ39C58F9K0MHDNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhNWNiZmQ3My1kOTZhLTRjMTUtOTI0Yy05MWUwZDBlNWExZWMifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwicyI6eyJTIjoiNjYifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "fb02ddae3011fc75", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "170" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1717565704" + ], + "X-Amzn-Requestid": [ + "1DBHEA6D53KHT9AHBUUIV7IVJRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlODA3MWY3Yi0wN2EyLTRjNWItOThhZS0wYzczNWIzOWI4OTcifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifSwicyI6eyJTIjoiNzcifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "e2364bde599fd93f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzOCJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "170" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3094741983" + ], + "X-Amzn-Requestid": [ + "B3VC02GKQD6R9PN2SQHJGK29GNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTQ4ZGY2ZS0yZTZlLTQyYzMtYjUwOC1lNGIwNDgxYTZjMTEifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczgifSwicyI6eyJTIjoiODgifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "3425c2b7149b8a49", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "68MM92KP4UN8686H31FTMA3POVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "30b920536f45da33", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "719" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4176799693" + ], + "X-Amzn-Requestid": [ + "6LUUFDVTOMBOE5NHTQLD5RUHDNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NiwiSXRlbXMiOlt7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjdlNDhkZjZlLTJlNmUtNDJjMy1iNTA4LWU0YjA0ODFhNmMxMSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzOCJ9LCJzIjp7IlMiOiI4OCJ9fSx7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImU4MDcxZjdiLTA3YTItNGM1Yi05OGFlLTBjNzM1YjM5Yjg5NyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9LCJzIjp7IlMiOiI3NyJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImUyYWQ5YWM0LWQ3ZjEtNDdlOC05NjM0LTk5NjcyODNiNDU5MSJ9LCJzIjp7IlMiOiI0In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiODU5ZjQ2YTctOTFkNy00NTM0LWE5ZWYtZWExNGU1YjQ2OWFiIn0sInMiOnsiUyI6IjUifX0seyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhNTIyZGJlZS01ZTMyLTQyNmYtOTE5MC04ZjQ3MTZlYWE0NmMifSwicyI6eyJTIjoiMyJ9fSx7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImE1Y2JmZDczLWQ5NmEtNGMxNS05MjRjLTkxZTBkMGU1YTFlYyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNiJ9LCJzIjp7IlMiOiI2NiJ9fV0sIlNjYW5uZWRDb3VudCI6Nn0=" + } + }, + { + "ID": "79b2d953ddf5e6ce", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TO6L19IEQ8T04QSHGS0BT7B0B7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8495230c120f1191", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DM8TD1T2QEJ05RO4NQCDM1AV2VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "10a277d8a5abe5c2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PO32LUTQHATGQI7R7JIB6R6G47VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e26faf6a5ebbc22f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UP5PM4QL6RKHUOVM3V5KFDBH37VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "00ad6ab81154144c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczgifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "F2CNHH9MMVMHHPE89URB8JGJ5JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7472117e169a14b4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KUG6PBED965H5L4ITLH7PISI13VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "75f7136fdc94d91c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiIzMTBmMWYyNS1mOGY0LTQyMzctODY3Yy0yMDFmOGZhNDc3NWQifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifSwicyI6eyJTIjoiMyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "36AVFBF54TFV2JDLFTMUBP0QJNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "72bd85a928d7d3da", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiIxOTA3YzViNi03ZDNkLTQ4NmItYTZmZS0zNzUyNWQzNTNiNGEifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczgifSwicyI6eyJTIjoiOCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:19 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "IU6HJDUAVLBR3OO8BL8HJCOP8VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a4cf74162c107e58", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiJmNmMxMjQ0Yy0yOWI0LTRmODktYmExMC04MDEwODE5NTU0ZGMifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczIifSwicyI6eyJTIjoiMiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "Q2B41U0F4KJ8EDAHJBNS1PAIAVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "38ec8845d204a6a3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiJlMGI2ZGFiYi04YjkxLTQzNjctOGJkMy0xNDAxOGQzMDZlMzAifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwicyI6eyJTIjoiNSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LAF781N8GG2IQNARDGOH5BFKI7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "311df714dd627d9e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiIyY2ZiMWY5Ni00ZDI4LTRlYWEtOWZhYS1lMzlmZTFiOTg4YTYifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwicyI6eyJTIjoiNiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OT4CV2N1KKV4S64S877L7PR27NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "13c6773c1ea644a1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiJiMjBjMTk4ZC02Y2RlLTQ1YmEtYTJkOC1jMTlmYWY5OTJjNTEifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifSwicyI6eyJTIjoiNyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "EF2A78I6BOR0TLD8IQ7K502I13VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "90e1db10871692f9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiIwZGExMGFhYS05ZmFjLTRhNTItYmU5My0wYWYwOWM3MzUwNGIifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczAifSwicyI6eyJTIjoiMCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MLTPLSGIULD0JHPFRI3JDE4CT3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "605facdeca12d4b3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiIxODdjYzQwYS0xZDc5LTQ3N2EtODUwNS1jMmRhMmEwOTBiMTAifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczEifSwicyI6eyJTIjoiMSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GRQRGSIDFNAC70VJ4JO1VGLDJJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5e118dd5f628337b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiI4YTI1NmUwYS03NzY4LTQyZmYtOTQ2Ni1mZDdhYzQ0ODU0ZDIifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifSwicyI6eyJTIjoiNCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "T7DOGK7UJCQ0D84VJ67AGI3JC7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "926cffc115f538ea", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "174" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "359" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4056327663" + ], + "X-Amzn-Requestid": [ + "BMF0TBUNJC5UVR51RARGE4BLR3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiJlMGI2ZGFiYi04YjkxLTQzNjctOGJkMy0xNDAxOGQzMDZlMzAifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwicyI6eyJTIjoiNSJ9fSx7IkV0YWciOnsiUyI6IjMxMGYxZjI1LWY4ZjQtNDIzNy04NjdjLTIwMWY4ZmE0Nzc1ZCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9LCJzIjp7IlMiOiIzIn19LHsiRXRhZyI6eyJTIjoiOGEyNTZlMGEtNzc2OC00MmZmLTk0NjYtZmQ3YWM0NDg1NGQyIn0sIm5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In0sInMiOnsiUyI6IjQifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "f74e2ed5f6b54506", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZjZjMTI0NGMtMjliNC00Zjg5LWJhMTAtODAxMDgxOTU1NGRjIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczIifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "BRA1EP9DTEE14HFHTJQDQ46RB3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "69bc2e3f9843e6cd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMGRhMTBhYWEtOWZhYy00YTUyLWJlOTMtMGFmMDljNzM1MDRiIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JR2AKU1TPPS3M8B9798PQ1IP3NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f2090e4684a790a6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMTg3Y2M0MGEtMWQ3OS00NzdhLTg1MDUtYzJkYTJhMDkwYjEwIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczEifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VOTPGSU7ISGQTV0GSBT360PIJBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "321079f58f87b5c8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "1147" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.TransactWriteItems" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJiYjcwMGE5NC1lOTUxLTRhOTItYWRlZi1hNTdjOGIzMzk0NDgiLCJUcmFuc2FjdEl0ZW1zIjpbeyJVcGRhdGUiOnsiQ29uZGl0aW9uRXhwcmVzc2lvbiI6IiMwID0gOjAiLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJFdGFnIiwiIzEiOiJzIn0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiUyI6IjJjZmIxZjk2LTRkMjgtNGVhYS05ZmFhLWUzOWZlMWI5ODhhNiJ9LCI6MSI6eyJTIjoiNjYifSwiOjIiOnsiUyI6IjJkOTdjZjE1LWY1ZDgtNGFlYS1hODAwLWM5MmNiOWVkMzhkYyJ9fSwiS2V5Ijp7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM2In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiU0VUICMxID0gOjEsICMwID0gOjJcbiJ9fSx7IlVwZGF0ZSI6eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWciLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYjIwYzE5OGQtNmNkZS00NWJhLWEyZDgtYzE5ZmFmOTkyYzUxIn0sIjoxIjp7IlMiOiI3NyJ9LCI6MiI6eyJTIjoiYThhZmVhNjktMDIzMi00NWRhLTk5NTAtY2MyM2IyZGI3MTJmIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn19LHsiVXBkYXRlIjp7IkNvbmRpdGlvbkV4cHJlc3Npb24iOiIjMCA9IDowIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoiRXRhZyIsIiMxIjoicyJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiIxOTA3YzViNi03ZDNkLTQ4NmItYTZmZS0zNzUyNWQzNTNiNGEifSwiOjEiOnsiUyI6Ijg4In0sIjoyIjp7IlMiOiI4OWQ4MmY4MC0yZTYyLTQ0YjktYTU5Ni1kNWJhMjMyOTVkMzEifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzOCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIiwiVXBkYXRlRXhwcmVzc2lvbiI6IlNFVCAjMSA9IDoxLCAjMCA9IDoyXG4ifX1dfQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "D0B0NL578A0J8EMB0QI70LURDRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2c4043ca0ee9a102", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNiJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "158" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4187363985" + ], + "X-Amzn-Requestid": [ + "813M98V3M02SMP56OKP52S84J3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiIyZDk3Y2YxNS1mNWQ4LTRhZWEtYTgwMC1jOTJjYjllZDM4ZGMifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwicyI6eyJTIjoiNjYifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "8c8734a8f46f72e2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "158" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4281843062" + ], + "X-Amzn-Requestid": [ + "152R9NQ73AJ4SCT1IE0UT29KKBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiJhOGFmZWE2OS0wMjMyLTQ1ZGEtOTk1MC1jYzIzYjJkYjcxMmYifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifSwicyI6eyJTIjoiNzcifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "c390e93ba92d648c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzOCJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "158" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4253875228" + ], + "X-Amzn-Requestid": [ + "45BLNKAANT9TOBPF4KD3KPALDRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI4OWQ4MmY4MC0yZTYyLTQ0YjktYTU5Ni1kNWJhMjMyOTVkMzEifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczgifSwicyI6eyJTIjoiODgifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/AtomicWritesFail.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/AtomicWritesFail.replay new file mode 100644 index 000000000..6c8eeda8d --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/AtomicWritesFail.replay @@ -0,0 +1,2519 @@ +{ + "Initial": "AQAAAA7gDLOwJ4XmMgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "516d92727e059ac0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "CIQIJ036H0O4AGD7HQ5I40ELL7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "081b6476840727a2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "647" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1784410815" + ], + "X-Amzn-Requestid": [ + "MKUL5R9GV7JPMLR8VL2O54TJ9RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NiwiSXRlbXMiOlt7IkV0YWciOnsiUyI6Ijg5ZDgyZjgwLTJlNjItNDRiOS1hNTk2LWQ1YmEyMzI5NWQzMSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzOCJ9LCJzIjp7IlMiOiI4OCJ9fSx7IkV0YWciOnsiUyI6ImE4YWZlYTY5LTAyMzItNDVkYS05OTUwLWNjMjNiMmRiNzEyZiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9LCJzIjp7IlMiOiI3NyJ9fSx7IkV0YWciOnsiUyI6IjhhMjU2ZTBhLTc3NjgtNDJmZi05NDY2LWZkN2FjNDQ4NTRkMiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNCJ9LCJzIjp7IlMiOiI0In19LHsiRXRhZyI6eyJTIjoiZTBiNmRhYmItOGI5MS00MzY3LThiZDMtMTQwMThkMzA2ZTMwIn0sIm5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM1In0sInMiOnsiUyI6IjUifX0seyJFdGFnIjp7IlMiOiIzMTBmMWYyNS1mOGY0LTQyMzctODY3Yy0yMDFmOGZhNDc3NWQifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifSwicyI6eyJTIjoiMyJ9fSx7IkV0YWciOnsiUyI6IjJkOTdjZjE1LWY1ZDgtNGFlYS1hODAwLWM5MmNiOWVkMzhkYyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNiJ9LCJzIjp7IlMiOiI2NiJ9fV0sIlNjYW5uZWRDb3VudCI6Nn0=" + } + }, + { + "ID": "71a53ee21958ca78", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8386KIJ5L59BIEI904JOI068SJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "112682df673ff877", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "NLU94JFH6I9ID6UR0LS5E8FHP7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "46fec26cd7d5a64a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczgifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:20 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "2QKAPP8D7QQ9LHOMQU91UU5K8RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0baf4d22893b5ebc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3FDH1F8UK40L4I5HELV4P4U2VFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "738adf6241200500", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "96V8VN7J48DN1D3LK8M0SRBA9VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cbdf69e7e8bcd150", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "AV03HBBQ1I5OKPMMKJEUPGK3SBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "29f8708e02a901a1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2OGQwNWM2ZC0wNjRhLTRmZmYtOTRhMy0yZTdkYjMxNmFkN2IifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifSwicyI6eyJTIjoiNyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KBGRBO2FA0V5NVJ7I0DN1CA9RRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "254243cc37715d1d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIyOGFhMDQzOC1jYTMyLTRhZTctYWViMS00ZDU4Y2E1ZWJiZjkifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifSwicyI6eyJTIjoiMyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DH98S24ICR52OAEIATG0MH4OPNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c7bb5115b54f61eb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI1Yjk2ZWUwNS0zZjU1LTQ5ZTctOTA5Yi0zYmMwMzMxMmYyMzcifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwicyI6eyJTIjoiNSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3B65UAKD1QA99RJIM0JBUIUG37VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1501e14b86e7b78e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlYWZjNjkyMS1mYWE5LTQzZWUtYjYzNS1mY2VlOWQ2MmY3MzEifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczEifSwicyI6eyJTIjoiMSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "4DURGTSJ50FGOBHUUQHVB5IVAFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6db83016ee9c9af1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIzZjhiYTE4NC04MzdlLTRiNDgtYjkyYi0xMjJlZWRiY2Q5YmYifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczAifSwicyI6eyJTIjoiMCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "H522ERDRVN337FMPO4119TC4GJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e212d88446c13e7a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4NDhmYWRlNy05NjNmLTQ3MDgtYjA3Mi0xMWQyNTU0MmQ3YmYifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifSwicyI6eyJTIjoiNCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3737EG1UBF8GVDAE7HJ3VI36EBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "706b3caa606c3c0f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhMjhkMDdlOC1jMGFlLTRhYTctYjJkMC1iZmU4ODcwZDU5MDcifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwicyI6eyJTIjoiNiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "T4C21619BOCN85M85272H9H44BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2f4799b055edc2ce", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIwYzM1MmQ5YS01ZTNmLTRmYmYtODg4ZS03OGQ4YzE0ZmYyM2IifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczIifSwicyI6eyJTIjoiMiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7G54N2UVNRPD38QAO8U2BERDG7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ea4ff213ae573211", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMGMzNTJkOWEtNWUzZi00ZmJmLTg4OGUtNzhkOGMxNGZmMjNiIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczIifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VIBJL4P9I0B76RBJC6F57BKC3RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "29c15eb1835cdcd4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "174" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "395" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4107973444" + ], + "X-Amzn-Requestid": [ + "F8C6955U8T7BMCVCIJIL0Q67I7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4NDhmYWRlNy05NjNmLTQ3MDgtYjA3Mi0xMWQyNTU0MmQ3YmYifSwicyI6eyJTIjoiNCJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM1In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjViOTZlZTA1LTNmNTUtNDllNy05MDliLTNiYzAzMzEyZjIzNyJ9LCJzIjp7IlMiOiI1In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMjhhYTA0MzgtY2EzMi00YWU3LWFlYjEtNGQ1OGNhNWViYmY5In0sInMiOnsiUyI6IjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "b5d43367c69d26f8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZWFmYzY5MjEtZmFhOS00M2VlLWI2MzUtZmNlZTlkNjJmNzMxIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczEifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "EU89IG6EDVICFJLNTO9K1HVSFNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "005937a91557dd90", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiM2Y4YmExODQtODM3ZS00YjQ4LWI5MmItMTIyZWVkYmNkOWJmIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "48N9JFG1PHHQE7GJCK00STMQE7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "94fc68738476bc80", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "1159" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.TransactWriteItems" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJhZGQ4ZmQ0Zi0yNzM1LTQ2MzAtYWIwYS1lZjYwZGZmM2JlNTMiLCJUcmFuc2FjdEl0ZW1zIjpbeyJVcGRhdGUiOnsiQ29uZGl0aW9uRXhwcmVzc2lvbiI6IiMwID0gOjAiLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJEb2NzdG9yZVJldmlzaW9uIiwiIzEiOiJzIn0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiUyI6ImEyOGQwN2U4LWMwYWUtNGFhNy1iMmQwLWJmZTg4NzBkNTkwNyJ9LCI6MSI6eyJTIjoiNjYifSwiOjIiOnsiUyI6IjY0YzYxMDczLWI3OTktNDY1Ni05NjFiLWE2MTgzMDM2NzQ5NiJ9fSwiS2V5Ijp7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM2In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiU0VUICMxID0gOjEsICMwID0gOjJcbiJ9fSx7IlVwZGF0ZSI6eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24iLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNjhkMDVjNmQtMDY0YS00ZmZmLTk0YTMtMmU3ZGIzMTZhZDdiIn0sIjoxIjp7IlMiOiI3NyJ9LCI6MiI6eyJTIjoiODIwNjVkNGQtNmEyNC00YjBkLTg0NGYtMTMzNDg3YjFmNDI3In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn19LHsiVXBkYXRlIjp7IkNvbmRpdGlvbkV4cHJlc3Npb24iOiJhdHRyaWJ1dGVfZXhpc3RzICgjMCkiLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJuYW1lIiwiIzEiOiJzIiwiIzIiOiJEb2NzdG9yZVJldmlzaW9uIn0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiUyI6Ijg4In0sIjoxIjp7IlMiOiI3NGNjMjA2OS03MzE4LTQ0ZDQtYTBmYS05ZGJmZGEyNjk5OGIifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzOCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIiwiVXBkYXRlRXhwcmVzc2lvbiI6IlNFVCAjMSA9IDowLCAjMiA9IDoxXG4ifX1dfQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "334" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2597991568" + ], + "X-Amzn-Requestid": [ + "UU699RDF6BTAV2F34SHMLH8L2FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNUcmFuc2FjdGlvbkNhbmNlbGVkRXhjZXB0aW9uIiwiQ2FuY2VsbGF0aW9uUmVhc29ucyI6W3siQ29kZSI6Ik5vbmUifSx7IkNvZGUiOiJOb25lIn0seyJDb2RlIjoiQ29uZGl0aW9uYWxDaGVja0ZhaWxlZCIsIk1lc3NhZ2UiOiJUaGUgY29uZGl0aW9uYWwgcmVxdWVzdCBmYWlsZWQifV0sIk1lc3NhZ2UiOiJUcmFuc2FjdGlvbiBjYW5jZWxsZWQsIHBsZWFzZSByZWZlciBjYW5jZWxsYXRpb24gcmVhc29ucyBmb3Igc3BlY2lmaWMgcmVhc29ucyBbTm9uZSwgTm9uZSwgQ29uZGl0aW9uYWxDaGVja0ZhaWxlZF0ifQ==" + } + }, + { + "ID": "40aee26b42896b67", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNiJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "169" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2475008283" + ], + "X-Amzn-Requestid": [ + "RTLB0J2ER1S7DS1HV63P7D60LBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNiJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhMjhkMDdlOC1jMGFlLTRhYTctYjJkMC1iZmU4ODcwZDU5MDcifSwicyI6eyJTIjoiNiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "56127f130b88d1cc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "169" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "734569141" + ], + "X-Amzn-Requestid": [ + "3FRHL2LA0KV6S6N41KQS56A21RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2OGQwNWM2ZC0wNjRhLTRmZmYtOTRhMy0yZTdkYjMxNmFkN2IifSwicyI6eyJTIjoiNyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "b788174c2d999eda", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "12JCE0AS2EKCL6211VFNKKTLQRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "61b4ec684f814cbb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "603" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3457942447" + ], + "X-Amzn-Requestid": [ + "CKKSU1JN5F0G386C5RFMSBR9IRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM3In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY4ZDA1YzZkLTA2NGEtNGZmZi05NGEzLTJlN2RiMzE2YWQ3YiJ9LCJzIjp7IlMiOiI3In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiODQ4ZmFkZTctOTYzZi00NzA4LWIwNzItMTFkMjU1NDJkN2JmIn0sInMiOnsiUyI6IjQifX0seyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNSJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI1Yjk2ZWUwNS0zZjU1LTQ5ZTctOTA5Yi0zYmMwMzMxMmYyMzcifSwicyI6eyJTIjoiNSJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXMzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjI4YWEwNDM4LWNhMzItNGFlNy1hZWIxLTRkNThjYTVlYmJmOSJ9LCJzIjp7IlMiOiIzIn19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYTI4ZDA3ZTgtYzBhZS00YWE3LWIyZDAtYmZlODg3MGQ1OTA3In0sInMiOnsiUyI6IjYifX1dLCJTY2FubmVkQ291bnQiOjV9" + } + }, + { + "ID": "c485261fbd5a9c9c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KD7OFV51L29OPFSCJS0D18RVMNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c34359765739b7d1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6Q5I1N6J9984I7JPHS03JKQ0GBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "10ea958d2acf0bc4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PTBAHNBM515EP3658G15R3BGQVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8c1d7e79c1249b51", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "C2SAVIP6CMD6C5M943NNVCRBV3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0d79658b497fe429", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "4H1QT7EEHT3073MM9R1P7LKMC3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d6e962b3357c5c85", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiIxZDI4M2FkNC1mZGE5LTQ0ZmItYjdiYi0xNTVjMTI3ZjdiOWQifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifSwicyI6eyJTIjoiNyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "10DRVOVHA9L1UGMA4T5O0RMK7NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6849a416177cd57a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiI1OWMzZDI0Mi04YWQ4LTQ2ZjItYmU4YS01ZjM2NGM3OTg5NTQifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifSwicyI6eyJTIjoiMyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "C8KIG8VPABBAPBQSNM9E7CU5JBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e8c747b43499d18d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiI5Yzc0Yjg0Ny1iNzVhLTQ4ZmEtYTEyMi0zOGIzOWExNmNlNGUifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczAifSwicyI6eyJTIjoiMCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M4OEF4NN7C4TNG1RULEE2G83KFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6632481a11c420b5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiI1N2UwMzNiMi1hZWJlLTQ5ZDQtOWZkOS01MGY4YTkyMGIzZDYifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczEifSwicyI6eyJTIjoiMSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "S4GD3GAVGLAEU39BM1LINC5CVJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1d57a846b0123c88", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiIxZjExM2JlNy1lYTk2LTRjZTEtYWViMC04MDEwZTc4MjU0MzIifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczIifSwicyI6eyJTIjoiMiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "E42LISV1N0H6PUU628OJ3AK1M3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "28a126eaae5fb2c8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiJhMDQ2YjllNi1jNjEyLTRkNmMtYTE5ZS1hZDBmMWI3OGQyODcifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwicyI6eyJTIjoiNSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "AJO2IM6S85FF1A6A5MBSDVJABJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "211bd546112a6710", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiIzNWY1Zjk2OC0zMWZjLTQ2OTctYTEzOC1iMjc5YjYwZTg5ODEifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifSwicyI6eyJTIjoiNCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "48KO1MQRF4SMGKQLFJSBOCILGNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "433fb3334184698c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiI2YzRkMDUxMi00NDJmLTQxNWItYjA4NS05YzRkMTg2M2EwYzcifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwicyI6eyJTIjoiNiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "D9HFQTUBM6O483UM5IB5CVA6B3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b40ed150e35f21c2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "174" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "359" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2566562212" + ], + "X-Amzn-Requestid": [ + "63HBOGSAGTDB584GAUVJN2UHONVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI1OWMzZDI0Mi04YWQ4LTQ2ZjItYmU4YS01ZjM2NGM3OTg5NTQifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifSwicyI6eyJTIjoiMyJ9fSx7IkV0YWciOnsiUyI6IjM1ZjVmOTY4LTMxZmMtNDY5Ny1hMTM4LWIyNzliNjBlODk4MSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNCJ9LCJzIjp7IlMiOiI0In19LHsiRXRhZyI6eyJTIjoiYTA0NmI5ZTYtYzYxMi00ZDZjLWExOWUtYWQwZjFiNzhkMjg3In0sIm5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM1In0sInMiOnsiUyI6IjUifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "37f221e3a803db9e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMWYxMTNiZTctZWE5Ni00Y2UxLWFlYjAtODAxMGU3ODI1NDMyIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczIifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "RHV8J10JRLM7P0U8VV1QGVTJO3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "24a9f7746f44d86f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "1123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.TransactWriteItems" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiI5Y2E5OTZlNC05MzE3LTQ5ZTEtOGQ5Yy0yNjMzNDAwNjkxZDQiLCJUcmFuc2FjdEl0ZW1zIjpbeyJVcGRhdGUiOnsiQ29uZGl0aW9uRXhwcmVzc2lvbiI6IiMwID0gOjAiLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJFdGFnIiwiIzEiOiJzIn0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiUyI6IjZjNGQwNTEyLTQ0MmYtNDE1Yi1iMDg1LTljNGQxODYzYTBjNyJ9LCI6MSI6eyJTIjoiNjYifSwiOjIiOnsiUyI6ImFmMGEyN2M4LTA2YjgtNDY4MC1iMDhhLTZkY2Q4MzA1YmQ3NSJ9fSwiS2V5Ijp7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM2In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiU0VUICMxID0gOjEsICMwID0gOjJcbiJ9fSx7IlVwZGF0ZSI6eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWciLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMWQyODNhZDQtZmRhOS00NGZiLWI3YmItMTU1YzEyN2Y3YjlkIn0sIjoxIjp7IlMiOiI3NyJ9LCI6MiI6eyJTIjoiNzJjMWZmODItNWQ4ZC00MmI2LWI5NDYtNjQzNTg2YWQ2NzI2In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn19LHsiVXBkYXRlIjp7IkNvbmRpdGlvbkV4cHJlc3Npb24iOiJhdHRyaWJ1dGVfZXhpc3RzICgjMCkiLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJuYW1lIiwiIzEiOiJzIiwiIzIiOiJFdGFnIn0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiUyI6Ijg4In0sIjoxIjp7IlMiOiIyN2Q2NTFjYy00ZWRmLTQ3NjItOTEyYy1mMjVlMzA5MTM5NmIifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzOCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIiwiVXBkYXRlRXhwcmVzc2lvbiI6IlNFVCAjMSA9IDowLCAjMiA9IDoxXG4ifX1dfQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "334" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2597991568" + ], + "X-Amzn-Requestid": [ + "91LJ2HPUI97J3EQRKS37J8VV4RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNUcmFuc2FjdGlvbkNhbmNlbGVkRXhjZXB0aW9uIiwiQ2FuY2VsbGF0aW9uUmVhc29ucyI6W3siQ29kZSI6Ik5vbmUifSx7IkNvZGUiOiJOb25lIn0seyJDb2RlIjoiQ29uZGl0aW9uYWxDaGVja0ZhaWxlZCIsIk1lc3NhZ2UiOiJUaGUgY29uZGl0aW9uYWwgcmVxdWVzdCBmYWlsZWQifV0sIk1lc3NhZ2UiOiJUcmFuc2FjdGlvbiBjYW5jZWxsZWQsIHBsZWFzZSByZWZlciBjYW5jZWxsYXRpb24gcmVhc29ucyBmb3Igc3BlY2lmaWMgcmVhc29ucyBbTm9uZSwgTm9uZSwgQ29uZGl0aW9uYWxDaGVja0ZhaWxlZF0ifQ==" + } + }, + { + "ID": "3af38e750d7af5dc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNTdlMDMzYjItYWViZS00OWQ0LTlmZDktNTBmOGE5MjBiM2Q2In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczEifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "094FBV95JSV913773SJVB723IJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "23b9a92311be8f45", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOWM3NGI4NDctYjc1YS00OGZhLWExMjItMzhiMzlhMTZjZTRlIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FD8PQ28NP12ROSBAIQR2560P5NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "949c8b37ac1eb2d7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNiJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "157" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "361218062" + ], + "X-Amzn-Requestid": [ + "J3IUQ5JFMRRV9HH9JOGENCII1VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI2YzRkMDUxMi00NDJmLTQxNWItYjA4NS05YzRkMTg2M2EwYzcifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwicyI6eyJTIjoiNiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "d0d65301d27fdc70", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "157" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2926504354" + ], + "X-Amzn-Requestid": [ + "FJ61A49K0N9DVNBG6HNJOGJBH3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiIxZDI4M2FkNC1mZGE5LTQ0ZmItYjdiYi0xNTVjMTI3ZjdiOWQifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifSwicyI6eyJTIjoiNyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/BeforeDo.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/BeforeDo.replay new file mode 100644 index 000000000..07762e89a --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/BeforeDo.replay @@ -0,0 +1,484 @@ +{ + "Initial": "AQAAAA7gDLPKI/QhugAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "f82525021ddc1392", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "0CFIOIKVSOJTQJ912PS722SG9NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "259bcb6c1f657cda", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "NH887HLKVDT4JBB37PK4VC1AAVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "3d0b8b24f643933d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "159" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJuYW1lIjp7IlMiOiJ0ZXN0QmVmb3JlRG8ifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "NT82DEDIMLCGB059KB3OKO2JDBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "61d5b1129ff06d8c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSJ9LCJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3RCZWZvcmVEbyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9HOM5REJIP3VVV6AN23DI0B4O3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3471e5e5660965ee", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3RCZWZvcmVEbyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "ORDCCT6DU67DL242BH8GVR8H27VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "69274d538ff6197b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiYSJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7Ik4iOiIxIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEJlZm9yZURvIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiU0VUICMxID0gOjBcbiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JJTANSDAAT3SP6HNJNJ63FII6BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ca475e4c417acd5f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "99" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QmVmb3JlRG8ifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "100" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3495001968" + ], + "X-Amzn-Requestid": [ + "Q9M82SKD2V975RQ224T0QTO9TJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7Ik4iOiIxIn0sIm5hbWUiOnsiUyI6InRlc3RCZWZvcmVEbyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "4f46e5a66f876e5f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEJlZm9yZURvIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DKUB5U3QPD0FFEQOREVDJNDIVBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/BeforeQuery.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/BeforeQuery.replay new file mode 100644 index 000000000..e3676154f --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/BeforeQuery.replay @@ -0,0 +1,209 @@ +{ + "Initial": "AQAAAA7gDLPLDDav/gAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "25985dfce956a2b3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "F943A5J6RQBT6DHH63287VTK9BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "c92d91cca4d25269", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "J8SAL6AETV2TP50A4J5JIL2EEFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "a5bef31fae9aa911", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "SI4VDDN5PL7JALQVVNFFRCI8TNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Create.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Create.replay new file mode 100644 index 000000000..35512d721 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Create.replay @@ -0,0 +1,1749 @@ +{ + "Initial": "AQAAAA7gDLOsDhKh7QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b02543e6f92f65cd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "BKUJ4VRHOT40KTQ1PV37C99JHVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "288740416befe683", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "MNEOCHSFP2FEU76444LGLOCM5JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "4ad5fb296260c2f3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIxZDNhMzlhNC0xNGMzLTQ2YjktOTczNy1iNGJmNmU5ZjJlYzcifSwiYiI6eyJCT09MIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdENyZWF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "U1TNN0DNEOE2KC7VHRI9GVEK23VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fae056436a4df3a5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0Q3JlYXRlTWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "169" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4285006963" + ], + "X-Amzn-Requestid": [ + "GGC35GD7L4NTM1KP83HIEVHHJNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0Q3JlYXRlTWFwIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjFkM2EzOWE0LTE0YzMtNDZiOS05NzM3LWI0YmY2ZTlmMmVjNyJ9LCJiIjp7IkJPT0wiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "f4a160448cdda7c5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "224" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlYWFhNGFiMy05YWRiLTRhMzUtOWUwYy1mN2ZjMDNiNzZiMGMifSwibmFtZSI6eyJTIjoidGVzdENyZWF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "M66T3LMDSQGECS5L7QDO663V07VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "adc217bb2d31b2a4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "265" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI1Yjg2ZWJiOS1mZDBlLTQ4NGEtOWZhOC0wNDc0M2MyNzU4ZTMifSwiYiI6eyJCT09MIjp0cnVlfSwibmFtZSI6eyJTIjoiMTRkMzJjMmQtYTg4MC00ZjdiLTk5NWItMjU2NWY0ZjJlYzVjIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3HVKNAB3J43GMSKT2CCNRBFM0FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d5e4cf60e6b2d488", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiIxNGQzMmMyZC1hODgwLTRmN2ItOTk1Yi0yNTY1ZjRmMmVjNWMifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "192" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2802005282" + ], + "X-Amzn-Requestid": [ + "5BRTDQB02FI4QFFIGQG29BCEARVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiIxNGQzMmMyZC1hODgwLTRmN2ItOTk1Yi0yNTY1ZjRmMmVjNWMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNWI4NmViYjktZmQwZS00ODRhLTlmYTgtMDQ3NDNjMjc1OGUzIn0sImIiOnsiQk9PTCI6dHJ1ZX19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "621ee5aba207f445", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "345" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJCIjp7IkJPT0wiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3MDJjN2RiMy1mZWViLTRiZDQtOGMzMC0xY2IzNGVlM2UwYTAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RDcmVhdGVTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5ED1I5OGUV64JNL49QODBEST03VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "be6153f1bfa598f0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0Q3JlYXRlU3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "272" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2297379890" + ], + "X-Amzn-Requestid": [ + "H3UNDS4DUC29VF0ISB1LHJL39FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdENyZWF0ZVN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3MDJjN2RiMy1mZWViLTRiZDQtOGMzMC0xY2IzNGVlM2UwYTAifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "c081cc57d1e5cad4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "365" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJCIjp7IkJPT0wiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhOWVlZDM2OS03Mzk4LTRmZWMtYmNlMS03ZGI3YWFlYjI5ODMifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6IjVmYTE3OWY5LTkyNGQtNGYwNy1hYWQ2LTlmNGYyZTM2OGIyZSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M5H69S1ID71Q2375HN3HF7QK3BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "120c9fe10b7cc14e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiI1ZmExNzlmOS05MjRkLTRmMDctYWFkNi05ZjRmMmUzNjhiMmUifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1401079067" + ], + "X-Amzn-Requestid": [ + "Q6T3NAB8FRF9J51BCBDDNS17URVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoiNWZhMTc5ZjktOTI0ZC00ZjA3LWFhZDYtOWY0ZjJlMzY4YjJlIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImE5ZWVkMzY5LTczOTgtNGZlYy1iY2UxLTdkYjdhYWViMjk4MyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "d4c564d15b075cc1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "365" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJCIjp7IkJPT0wiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI5NjZiZWVmYi02NzM5LTRhNGUtYjFkZS05NjNkZmIxNTRmM2MifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6ImNhYWQ5MmU1LWQyYmItNDkzMy1iZGU3LTE5M2RkOWIyNDg3MyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "1KQNBI78VG17U40PHSJ0FMG4EVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d2afe39439625e97", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJjYWFkOTJlNS1kMmJiLTQ5MzMtYmRlNy0xOTNkZDliMjQ4NzMifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2623410360" + ], + "X-Amzn-Requestid": [ + "8AGO8GRONFJ0LR85MKCL1EKUHFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoiY2FhZDkyZTUtZDJiYi00OTMzLWJkZTctMTkzZGQ5YjI0ODczIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijk2NmJlZWZiLTY3MzktNGE0ZS1iMWRlLTk2M2RmYjE1NGYzYyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "e884941e5ef79c93", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "1E03EB1C1TH50CCP5RH9SRVGEJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "897b0e3f7df63a45", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "975" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4087392995" + ], + "X-Amzn-Requestid": [ + "12EIAGVFGGB4OFT1NTMC2N5CIFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7IkIiOnsiQk9PTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0Q3JlYXRlU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjcwMmM3ZGIzLWZlZWItNGJkNC04YzMwLTFjYjM0ZWUzZTBhMCJ9fSx7Im5hbWUiOnsiUyI6InRlc3RDcmVhdGVNYXAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMWQzYTM5YTQtMTRjMy00NmI5LTk3MzctYjRiZjZlOWYyZWM3In0sImIiOnsiQk9PTCI6dHJ1ZX19LHsibmFtZSI6eyJTIjoiMTRkMzJjMmQtYTg4MC00ZjdiLTk5NWItMjU2NWY0ZjJlYzVjIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjViODZlYmI5LWZkMGUtNDg0YS05ZmE4LTA0NzQzYzI3NThlMyJ9LCJiIjp7IkJPT0wiOnRydWV9fSx7IkIiOnsiQk9PTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJjYWFkOTJlNS1kMmJiLTQ5MzMtYmRlNy0xOTNkZDliMjQ4NzMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOTY2YmVlZmItNjczOS00YTRlLWIxZGUtOTYzZGZiMTU0ZjNjIn19LHsiQiI6eyJCT09MIjp0cnVlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6IjVmYTE3OWY5LTkyNGQtNGYwNy1hYWQ2LTlmNGYyZTM2OGIyZSJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhOWVlZDM2OS03Mzk4LTRmZWMtYmNlMS03ZGI3YWFlYjI5ODMifX1dLCJTY2FubmVkQ291bnQiOjV9" + } + }, + { + "ID": "032ad4333811aacf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoiNWZhMTc5ZjktOTI0ZC00ZjA3LWFhZDYtOWY0ZjJlMzY4YjJlIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "35KKG4P26BC4REGBG9O72HIK3BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ef3ba1ce8fd6fb67", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoiMTRkMzJjMmQtYTg4MC00ZjdiLTk5NWItMjU2NWY0ZjJlYzVjIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "G5LMQ2594ORJMF9Q4QS3RQ5HLFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "221167191e6e922b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdENyZWF0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "829DHFR5N9GQMRH24AF96RLQRRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7f6ff29c14dacc41", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdENyZWF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "J5TP5SBSAEVAUOVMUNJOR0DGP7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "849f0a66e2959175", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoiY2FhZDkyZTUtZDJiYi00OTMzLWJkZTctMTkzZGQ5YjI0ODczIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8I58I4ULJVGN2K6V8SKOB1DBVRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "00435ab6dcd4635e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiI0MWZmOTJiZS04ODVkLTQ2OTMtYjkyYy1jYTRiOGRiZTliMTcifSwiYiI6eyJCT09MIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdENyZWF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:17 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "T2BLQAVDO31GB2N8SQ77BBCBSRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fae70666f3483538", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0Q3JlYXRlTWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "157" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1450596860" + ], + "X-Amzn-Requestid": [ + "QGDF0BPU6A1FE40DQG1JJ2UC0VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI0MWZmOTJiZS04ODVkLTQ2OTMtYjkyYy1jYTRiOGRiZTliMTcifSwibmFtZSI6eyJTIjoidGVzdENyZWF0ZU1hcCJ9LCJiIjp7IkJPT0wiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "395d767010ac3d1f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "212" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiI0N2VmOTk0Ni0xMzRhLTRmNjUtODBiNi0yZGMwZDQ0YmJlZmQifSwibmFtZSI6eyJTIjoidGVzdENyZWF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "7LG84BI7SUFC7EJFF4OQCVIQ6NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "f04582e2dfad840a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiJkZDJlOTE4Yi0wY2MxLTRhMjktODE3My1mMGE4MTA2ZGJhZTMifSwiYiI6eyJCT09MIjp0cnVlfSwibmFtZSI6eyJTIjoiYjk5NmZmMTMtOTlhZi00YjU2LWI0NzYtMTkwNDUyMTkyZGM2In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7HHT6IS1NDCNQNN8TB8EJK3PVNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8268062dfd3c745a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJiOTk2ZmYxMy05OWFmLTRiNTYtYjQ3Ni0xOTA0NTIxOTJkYzYifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "180" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1074403081" + ], + "X-Amzn-Requestid": [ + "C7UBOB87ALRM9PVTTCQ205NNUBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiJkZDJlOTE4Yi0wY2MxLTRhMjktODE3My1mMGE4MTA2ZGJhZTMifSwibmFtZSI6eyJTIjoiYjk5NmZmMTMtOTlhZi00YjU2LWI0NzYtMTkwNDUyMTkyZGM2In0sImIiOnsiQk9PTCI6dHJ1ZX19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "69f9db9ceab7da05", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "345" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJCIjp7IkJPT0wiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiJjYWUwNjFkMC04NjA3LTQyY2ItYmYxMC0xYThkMzA2YWNlNDIifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RDcmVhdGVTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "E5D7TOBFHS1DSVME227DNVARRVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "859f7317afc8fba8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0Q3JlYXRlU3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "272" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3509346261" + ], + "X-Amzn-Requestid": [ + "KLKN2C1FM7E29IV94KLTFPPPNBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiY2FlMDYxZDAtODYwNy00MmNiLWJmMTAtMWE4ZDMwNmFjZTQyIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RDcmVhdGVTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJOVUxMIjp0cnVlfX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "08b36afe9daafa44", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "365" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJCIjp7IkJPT0wiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiI5ZjdjZmFhYS01MmQzLTRjM2UtODE3My02NGM5ZWZjZDZmNGYifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6ImRhNjE2ODg3LWJjNmEtNDc3My05NzVmLThmY2NlZmMwMmEwZCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DALUV7LLHKJ7NRB7KT2GP21E7VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b37432389c311452", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJkYTYxNjg4Ny1iYzZhLTQ3NzMtOTc1Zi04ZmNjZWZjMDJhMGQifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2282293027" + ], + "X-Amzn-Requestid": [ + "NTV21S1APS4J02E7J0PBO5DRABVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiOWY3Y2ZhYWEtNTJkMy00YzNlLTgxNzMtNjRjOWVmY2Q2ZjRmIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6ImRhNjE2ODg3LWJjNmEtNDc3My05NzVmLThmY2NlZmMwMmEwZCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "2d2a4997fc34b96d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "365" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJCIjp7IkJPT0wiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiI1NmZlNDg3Yy1lZTg2LTRkNTctOTQ0ZC05MGUwZjU1NzE4NWYifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6IjlkMDBkYTQxLWRkZjQtNDY2My05ZmQzLWM0N2MzZjlmOTViMyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "042T6RI2L7J1CD9H39D786S5C3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "01648a0ff9749fcc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiI5ZDAwZGE0MS1kZGY0LTQ2NjMtOWZkMy1jNDdjM2Y5Zjk1YjMifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:18 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "334812223" + ], + "X-Amzn-Requestid": [ + "KV08B3K5OIHUB1B2CNR80SO9GRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiNTZmZTQ4N2MtZWU4Ni00ZDU3LTk0NGQtOTBlMGY1NTcxODVmIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6IjlkMDBkYTQxLWRkZjQtNDY2My05ZmQzLWM0N2MzZjlmOTViMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Data.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Data.replay new file mode 100644 index 000000000..fb90be80c --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Data.replay @@ -0,0 +1,1914 @@ +{ + "Initial": "AQAAAA7gDLO/KINN5wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "92fef2478e6d1106", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "ETK6K37LVIMUCNRJCMOAGFPAHRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "96ac8442c7c3e2e6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1393" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3403659439" + ], + "X-Amzn-Requestid": [ + "GQO1A2T98MPCMCLF9LIIILCJ4RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoic3RyIn0sIlUiOnsiTiI6IjQifSwiRiI6eyJOIjoiMC41In0sIkV0YWciOnsiUyI6ImFiN2M3MTM0LTFjMGUtNGI2NS05MWVlLTA1N2JjODVmNWY3OCJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0In19LHsiRXRhZyI6eyJTIjoiM2U5MDVhYTMtNTM2ZC00M2Y5LTk2NjMtNGVlMjQ0ZmM0YWI5In0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvbk1hcCJ9LCJzIjp7IlMiOiJjIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJzdHIifSwiVSI6eyJOIjoiNCJ9LCJGIjp7Ik4iOiIwIn0sIkV0YWciOnsiUyI6ImE2MDRlNzM4LTU3MmQtNDkyNy1hYjI4LTRiYzVhZTM3ZjBjNCJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0V3J0In19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJzdCJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAuNSJ9LCJJIjp7Ik4iOiIxIn0sIkV0YWciOnsiUyI6IjA0NzIyMzUyLTZhN2MtNDFjNC1iYWZkLTkzYzk3YTFlYTIxYyJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0SW5jIn19LHsiYSI6eyJTIjoiQSJ9LCJpIjp7Ik4iOiIzLjUifSwiRXRhZyI6eyJTIjoiN2JkM2Y3ZjItNDI1NC00MTBkLTkzZGEtNzFhZDY0OTQyNTM1In0sIm0iOnsiTiI6IjMifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBJbmMifX0seyJhIjp7IlMiOiJYIn0sIkV0YWciOnsiUyI6IjdjMDRmZjA5LWQ3YTUtNDc3Yy1hZjU2LTI0NGEzNjMyODUxNiJ9LCJjIjp7IlMiOiJDIn0sIm0iOnsiTiI6IjMifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXAifX0seyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwicyI6eyJTIjoiYyJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiIxZWRjMTQ1Zi0xZWE3LTQ5NmUtOTY4My1iZDVjNzYxYzI2ZTgifSwiTSI6eyJOVUxMIjp0cnVlfSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LHsiYSI6eyJTIjoiWCJ9LCJFdGFnIjp7IlMiOiJhODgwYWI5Zi04NTVmLTRhZDctOTZmNS1hMjlmOTgwOGQ5MTEifSwibSI6eyJOIjoiMyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwV3J0In19XSwiU2Nhbm5lZENvdW50Ijo4fQ==" + } + }, + { + "ID": "fb231b267c96f513", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcFdydCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "AK7UAS4EPSVVTH2LE1TMQHODUBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3d66a0b3f7ef67a4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "74" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdFdydCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LIOLDKD84A628A97EV484F3AVJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9ebb8d6a75eb1bad", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GG0QQU2P6RT3R24VS62TF6TDGRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5ec0a7a8a2b7c959", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9QU2U4TUB69UC8LVJ6DR8EOPFBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4e99f69dc8ce0389", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "74" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdEluYyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M0GOTVM8GDFQQR60M7LDNFPKQ3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0ab61fdae13dc58a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcEluYyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LJJ3OBLOULAMGMJEO6H8H8N76NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3a5695c3f097aa34", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FUHQ35N1LNOK7JNJG9BTU66K6BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5c1d16a81b53bf2d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VPUQNADJMG06BADNV37943P20JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "381d63f2025ba31d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJOIjoiLTEifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QS4GFQC1M37U508R8M3IVV91RNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0da4665bd94a178b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3054047241" + ], + "X-Amzn-Requestid": [ + "Q0PDOL9H3TNIID9CV8F4RUJH8JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6Ii0xIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "1c5f010ce799070d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJOIjoiLTgifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JNNQF5HD3OGRRT48VGH9MQ0T6FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b6b98bfe93245867", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3121808892" + ], + "X-Amzn-Requestid": [ + "GH95N7PI5HC7FO2V9U3BF19B13VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6Ii04In19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "3f179791b66e1469", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJOIjoiLTE2In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "67GHB2159Q6C980D1N61RTC32VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4dee0d9f7bd5d2be", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "100" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2455135972" + ], + "X-Amzn-Requestid": [ + "RU9FD4U79RB1A0MO34HT046AGFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6Ii0xNiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "e539d64e3930eae2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJOIjoiLTMyIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KOFLJBHHA9CS8L4TEPPH3B65F3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ea0df6f54c64b311", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "100" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385046232" + ], + "X-Amzn-Requestid": [ + "K8JPECHKQ63JN1SO59M5N5A3S7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6Ii0zMiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "03ba2d5b9986fd51", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJOIjoiLTY0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "IL1KI550EVLBDTH6Q3FCS7JTMRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "270cbbd2c7f5dbba", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "100" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1666946403" + ], + "X-Amzn-Requestid": [ + "HCRTG6QPIJHM4VPMGC85PD38AVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6Ii02NCJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "c8d287d445c22924", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "80" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJOIjoiMSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "T11UEQQ9PJ3FIV4J3527H4O86BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "97bfc8d8a5e49cda", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "98" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2670645296" + ], + "X-Amzn-Requestid": [ + "60J8PH2LRF3IPUR0EPNVMIBGLVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "686dfbe6fdb452a6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "80" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJOIjoiOCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SRS63KBSCMIG0NCA5FRDKS56DRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "de73a5808a8fa887", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "98" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2469709253" + ], + "X-Amzn-Requestid": [ + "RRSPVN49M0JOT2IU9JDLPQF4U7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjgifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "a7af2b8c466c66f0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJOIjoiMTYifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V13BGEHAU9MJV4N78G0POJ5L6VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "97b932474b4f7804", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3447376172" + ], + "X-Amzn-Requestid": [ + "4FRRTJ8C6U7O0PU4IJTJ39BVTJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjE2In19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "7373048711918330", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJOIjoiMzIifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QTGQBE8AN1M3R7OUOQ3E8017AVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6a331b17dbf4f2d3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "228757264" + ], + "X-Amzn-Requestid": [ + "1Q7M3SR4J6HHVMF88THJE1M0AJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjMyIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "d29326dcc2e6bb88", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJOIjoiNjQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SINSCS9QA682OSAT4C4DB16VI3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4b16413e02040b72", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1014446763" + ], + "X-Amzn-Requestid": [ + "497BJIQVA07POR6L2SNIKH4TOJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjY0In19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "8f1faf0dbedfd55c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJOIjoiMy41In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OJGG4B35GTSEFFD1SI7AVKM983VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8b475972778b08bb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "100" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2334279914" + ], + "X-Amzn-Requestid": [ + "K5L4P0EI1GK4QV364D77NB3GNNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjMuNSJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "568d8419e14849a0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "83" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJCIjoiQUFFQyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GV7VLFU7L11S3FVNHBV0NUCVGBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cd297d1a82ff712c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "101" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "129752700" + ], + "X-Amzn-Requestid": [ + "4CDG1P6IECGBR9POP2G6ERN5M7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiQiI6IkFBRUMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Delete.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Delete.replay new file mode 100644 index 000000000..b39f4324d --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Delete.replay @@ -0,0 +1,1859 @@ +{ + "Initial": "AQAAAA7gDLO5KSQRcwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "66c6194903ad1fc6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "UJ17KQEC3CVSQ3N4Q31FS606LNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "6f75e0012e11a854", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1139" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "292632734" + ], + "X-Amzn-Requestid": [ + "B8LVHOH8152FV6G1SSH7S8DL9NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7ImkiOnsiTiI6Ijk1In0sIkV0YWciOnsiUyI6ImFmN2IxNjJlLWExMGItNDg4My1iNWM4LTIzMWMwMGFkZGVmMyJ9LCJzIjp7IlMiOiJhIHN0cmluZyJ9LCJtIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRNYXBGUCJ9LCJmIjp7Ik4iOiIzMi4zIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJhIHN0cmluZyJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjMyLjMifSwiSSI6eyJOIjoiOTUifSwiRXRhZyI6eyJTIjoiM2RhOWIyZjQtMTAyMS00OWQ3LTk0OGQtMjliZjExNzZjZGZjIn0sIk0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSBzdHJpbmcifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIzMi4zIn0sIkkiOnsiTiI6Ijk1In0sIkV0YWciOnsiUyI6IjI1M2ZlNWMyLTc0OTEtNGExMi1hY2QxLTU5OTFhY2EzZTMyYyJ9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3RXQyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fSx7ImkiOnsiTiI6Ijk1In0sIkV0YWciOnsiUyI6IjE5YWUxZmVjLTA5ZWYtNDVkNC05YjUzLTIzNzNiZTA1ZGMzNiJ9LCJzIjp7IlMiOiJhIHN0cmluZyJ9LCJtIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRNYXAifSwiZiI6eyJOIjoiMzIuMyJ9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSBzdHJpbmcifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIzMi4zIn0sIkkiOnsiTiI6Ijk1In0sIkV0YWciOnsiUyI6IjU0YTA5NTFjLWU0N2MtNGM4ZS04YThlLTQxYTI2OWQxMjc3YSJ9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3RGUCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV0sIlNjYW5uZWRDb3VudCI6NX0=" + } + }, + { + "ID": "2aa90d1e2d9eb9c5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdEZQIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "4T9QD4NB50ME1T0QKT2GENGHN3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9fb1dc42b13a88a8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdFdDIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "B575M585PJCN9IH3IJNEJFJCUNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d27f046fb44fc9d4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEdldE1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "4UPEH9MBBHKOFO044TRU9NEPPJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "26065586c38e9023", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEdldE1hcEZQIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UI01S3OUDMUJDL4K8F6T0G347RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6b39cb01a0c84eea", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3F38JH9QHDAH79LKHT2CIDJVOFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bad11b2ecd009eff", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "133" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjQxNmUxYWE2LWM0NDUtNGJkOS1iZTUwLTNkMGViMTcxMzQ2MiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0RGVsZXRlTWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "ETE8OPEBFC92OI4OPMVK2C96LJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "68022fe5b8dd4206", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "233" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNDE2ZTFhYTYtYzQ0NS00YmQ5LWJlNTAtM2QwZWIxNzEzNDYyIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GKE9DV98E67BBC378LIFBH1TO3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d3f0bdbab78868ca", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGVsZXRlTWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "2LQTFIK006N2DH9ELATGMJ6JTFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "590e1d803a8a8916", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "151" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImQ0OWEyYjFmLWFhNTEtNDFjYi1iMDkzLTk0MDFjYzJhYmJlYSJ9LCJiIjp7IkJPT0wiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0RGVsZXRlTWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5CSQ21VSKLM22VO7RQCORA83N7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a73343c35c54ab7c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "233" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNDE2ZTFhYTYtYzQ0NS00YmQ5LWJlNTAtM2QwZWIxNzEzNDYyIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "835M5KD1BVQBBSKD4AS1P0VJ8JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "8e6671cfacbcd7b6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "255" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI5YTQwOWQ4NS1kOThhLTQ4YmUtOTJiZS1mYWQ2YmFjODQ2YjQifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3REZWxldGVTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HN0FQCFIRH67407HUQ1TA10LNFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7c0a66359ba8c39f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "236" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOWE0MDlkODUtZDk4YS00OGJlLTkyYmUtZmFkNmJhYzg0NmI0In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CV5AODCUQ7VTM6MKI3KT7QKNLBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4ff042d1ccf85330", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGVsZXRlU3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "E31VULBUG1MD1V42PL4QHN3ITRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "50054afb9f6c3ae7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImQ3NjAzY2NhLWNmZjUtNGMzNy1iMDViLTFjYjZmZTEwMzA1YiJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiTSI6eyJOVUxMIjp0cnVlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdERlbGV0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3S5DFQJFEOF23ESO4O3HLDLB93VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4ae4f5e1c0d96de8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "236" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOWE0MDlkODUtZDk4YS00OGJlLTkyYmUtZmFkNmJhYzg0NmI0In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "BD2DLMHN1JJ1REO93NRUSUUVR7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "885d05e45360df90", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoiZG9lc05vdEV4aXN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "T3V6GK0V8JRUKS8MTGE6CCO83FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b4c297422fa4eee2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "1SFFQP53CRK8753K271J9EOL5VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "2fa1921c8a5de6de", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "367" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3376166886" + ], + "X-Amzn-Requestid": [ + "D5BS1RGNOQ4DR1T1C8JLJE74JNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3REZWxldGVNYXAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZDQ5YTJiMWYtYWE1MS00MWNiLWIwOTMtOTQwMWNjMmFiYmVhIn0sImIiOnsiQk9PTCI6dHJ1ZX19LHsiQiI6eyJCT09MIjp0cnVlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3REZWxldGVTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZDc2MDNjY2EtY2ZmNS00YzM3LWIwNWItMWNiNmZlMTAzMDViIn19XSwiU2Nhbm5lZENvdW50IjoyfQ==" + } + }, + { + "ID": "5936efcee6ecd5ed", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UM15VE82EQIIKG46JOLVIDBE53VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "168a1aee60ed36c6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DFKRLDPF4542JL9PJA51NOQN0VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "986120043dbfb74f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "121" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6ImZkNDk4Y2EzLWE4NmMtNDY5Ni04NTI4LTlkMDI1MGYyYjFkZSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0RGVsZXRlTWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "G7A8L4SP7GHUD8J8GDITCTJVRNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "52241ea1cb3cb25b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "221" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZmQ0OThjYTMtYTg2Yy00Njk2LTg1MjgtOWQwMjUwZjJiMWRlIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PJ52IF9JQ3D1LTLSEUVHLFUTTJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7b98a50a77f77604", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGVsZXRlTWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "S74K75VN9LFJM9DFNKCRFSMHSJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "c93a6c4e72181e92", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "139" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6IjcxODZiZWYwLTM2ZDQtNDcxZS1hYmUxLWJiNTI3MzJhZDVlMiJ9LCJiIjp7IkJPT0wiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0RGVsZXRlTWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SKLIMNEPIKF4C79S3OSEH06LPBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c6b8f188e50b0465", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "221" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZmQ0OThjYTMtYTg2Yy00Njk2LTg1MjgtOWQwMjUwZjJiMWRlIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "CG39SKBQV97BFRC9FSR22PU3LNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "56eecbc89ca8cd89", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "255" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiIxMDc1YTMyNC1kMjFiLTQxYzktODgyZS04ODg1ZTM4NjJjZjEifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3REZWxldGVTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HLF1M2S22IR3UR7865DAI7U92RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "526d743b4ee1ff16", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "224" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMTA3NWEzMjQtZDIxYi00MWM5LTg4MmUtODg4NWUzODYyY2YxIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "U2VME7BAJ5G3AIS3B51F8H2PVFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5dcbcac59c85b517", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGVsZXRlU3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "FIP2B82AB6PQJOV4TT8518SEUNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "102763c71e7fa2e5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX0sIkV0YWciOnsiUyI6ImUyNWZiYzViLTU1YWMtNGQxNy1hMTc1LTc3M2FlMDhhNzNiZSJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiTSI6eyJOVUxMIjp0cnVlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdERlbGV0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "26OI0A5NV73CBJMJTLMK62HCUFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e18b9cdcbc586981", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "224" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMTA3NWEzMjQtZDIxYi00MWM5LTg4MmUtODg4NWUzODYyY2YxIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "UNM2CKEKJPFE3FMNBC2MMPV073VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "27e136bf50b7c3fc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoiZG9lc05vdEV4aXN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FGH27I19AJ2TF2GHSGPJQCRQCVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/ExampleInDoc.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/ExampleInDoc.replay new file mode 100644 index 000000000..cb3fcf4e1 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/ExampleInDoc.replay @@ -0,0 +1,594 @@ +{ + "Initial": "AQAAAA7gDLPJOcyRtgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b2d918afdb053e8a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "7N3ULIT8BHR69RIQGRG66ATFBNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "73569f82b6860912", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "130" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2772784065" + ], + "X-Amzn-Requestid": [ + "646UBG20OR48THROQEBUJ9584NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7IkkiOnsiTiI6IjEifSwibmFtZSI6eyJTIjoicHV0YW5kdXBkYXRlIn19LHsiSSI6eyJOIjoiMCJ9LCJuYW1lIjp7IlMiOiJjcmVhdGVhbmRyZXBsYWNlIn19XSwiU2Nhbm5lZENvdW50IjoyfQ==" + } + }, + { + "ID": "34a87065b5a35090", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoiY3JlYXRlYW5kcmVwbGFjZSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "65UIPVDS2J4SA6A5DT1V0P422RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cf56003055bd3b89", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoicHV0YW5kdXBkYXRlIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GP8QFLJIE4O959A2JD76E0V1LRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5f00d27d3fc481a6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "185" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7ImF1dGhvciI6eyJNIjp7IkZpcnN0Ijp7IlMiOiJNaWtoYWlsIn0sIkxhc3QiOnsiUyI6IkJ1bGdha292In19fSwibmFtZSI6eyJTIjoiVGhlIEhlYXJ0IG9mIGEgRG9nIn0sInB1Yl95ZWFycyI6eyJMIjpbeyJOIjoiMTk2OCJ9LHsiTiI6IjE5ODcifV19fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0BC0M368DRHA6BTP563PN4PU0JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4ad25dbdb976bb67", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "282" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJhdXRob3IiOnsiTSI6eyJGaXJzdCI6eyJTIjoiTWlraGFpbCJ9LCJMYXN0Ijp7IlMiOiJCdWxnYWtvdiJ9fX0sIm5hbWUiOnsiUyI6IlRoZSBNYXN0ZXIgYW5kIE1hcmdhcml0YSJ9LCJwdWJfeWVhcnMiOnsiTCI6W3siTiI6IjE5NjcifSx7Ik4iOiIxOTczIn1dfX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KIRS74MQAVHM2O9KA8HCCP08BNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6e956dc3d41734c4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "147" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJUaGUgTWFzdGVyIGFuZCBNYXJnYXJpdGEifX0seyJuYW1lIjp7IlMiOiJUaGUgSGVhcnQgb2YgYSBEb2cifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "356" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3110860075" + ], + "X-Amzn-Requestid": [ + "2HG7AUKJAF1NL0H875UQP2KQEVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJwdWJfeWVhcnMiOnsiTCI6W3siTiI6IjE5NjgifSx7Ik4iOiIxOTg3In1dfSwibmFtZSI6eyJTIjoiVGhlIEhlYXJ0IG9mIGEgRG9nIn0sImF1dGhvciI6eyJNIjp7Ikxhc3QiOnsiUyI6IkJ1bGdha292In0sIkZpcnN0Ijp7IlMiOiJNaWtoYWlsIn19fX0seyJwdWJfeWVhcnMiOnsiTCI6W3siTiI6IjE5NjcifSx7Ik4iOiIxOTczIn1dfSwibmFtZSI6eyJTIjoiVGhlIE1hc3RlciBhbmQgTWFyZ2FyaXRhIn0sImF1dGhvciI6eyJNIjp7Ikxhc3QiOnsiUyI6IkJ1bGdha292In0sIkZpcnN0Ijp7IlMiOiJNaWtoYWlsIn19fX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "0c46c7407000ec9d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "192" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoiYXV0aG9yIiwiIzEiOiJMYXN0In0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiUyI6IkJ1bGdha292In19LCJGaWx0ZXJFeHByZXNzaW9uIjoiIzAuIzEgPSA6MCIsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "338" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2286982984" + ], + "X-Amzn-Requestid": [ + "GU3OBIL57JHJSM3L845LR9T4SVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7InB1Yl95ZWFycyI6eyJMIjpbeyJOIjoiMTk2OCJ9LHsiTiI6IjE5ODcifV19LCJuYW1lIjp7IlMiOiJUaGUgSGVhcnQgb2YgYSBEb2cifSwiYXV0aG9yIjp7Ik0iOnsiTGFzdCI6eyJTIjoiQnVsZ2Frb3YifSwiRmlyc3QiOnsiUyI6Ik1pa2hhaWwifX19fSx7InB1Yl95ZWFycyI6eyJMIjpbeyJOIjoiMTk2NyJ9LHsiTiI6IjE5NzMifV19LCJuYW1lIjp7IlMiOiJUaGUgTWFzdGVyIGFuZCBNYXJnYXJpdGEifSwiYXV0aG9yIjp7Ik0iOnsiTGFzdCI6eyJTIjoiQnVsZ2Frb3YifSwiRmlyc3QiOnsiUyI6Ik1pa2hhaWwifX19fV0sIlNjYW5uZWRDb3VudCI6Mn0=" + } + }, + { + "ID": "d06e5b7aeb541499", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoiVGhlIEhlYXJ0IG9mIGEgRG9nIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TC26T87SP310NUQDUTUA9A6JQFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "39062c91f5e1e57b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "79" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoiVGhlIE1hc3RlciBhbmQgTWFyZ2FyaXRhIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MULDA4R7LQ1HK239KMUEN2CLKVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Get.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Get.replay new file mode 100644 index 000000000..57bd506a9 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Get.replay @@ -0,0 +1,1969 @@ +{ + "Initial": "AQAAAA7gDLO3JmLtqQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "8026d3993ca49404", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "77M4D7NN0GAFTNJCQI4GVU3K53VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "30578ac756d9e156", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "664" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "325193658" + ], + "X-Amzn-Requestid": [ + "C1EH1AGGRQSL12ECOVUB3H4HCVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7IkV0YWciOnsiUyI6IjkxYjJkOTMzLTM4NGEtNDlhNy04NGVhLTMzZmYzZWVhMzQ4OCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZU1hcCJ9LCJzIjp7IlMiOiJiIn19LHsiRXRhZyI6eyJTIjoiZTY1MmZmZTYtNDYyOS00ZjZjLWEwZGQtNTY4NjhiNjkyN2I0In0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvbk1hcCJ9LCJzIjp7IlMiOiJhIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJiIn0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiUyI6IjU0NjkwZGUxLTJlZWEtNDhiMy1iOTgzLThjYjIwODI1NDE5ZCJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZVN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiJjODE3MGM3Mi1mYjcwLTRhNDctYTMxMS1lZmE2YmVkNTYxYjkifSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19XSwiU2Nhbm5lZENvdW50Ijo0fQ==" + } + }, + { + "ID": "d10fb83563883cc7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6DUFT58HJMREIQS30DHSAURPQFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a469fa084400e2d2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VIGV1A4VGP0PRDE1RR0SJE5SMRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0f69b42ea2cce3a1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VNYXAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V8I8L4ELR11KQMP14EIUBBV49BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "96d54be5be0c96aa", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7KLSDOAN62H3Q7RFPLFPP1CU6NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cb5d8f7afc1e66c9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "227" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjE4YzVkYTY4LTNiMjgtNDFjMi05NDYyLTYyMTA1MDY2OTQ5NCJ9LCJmIjp7Ik4iOiIzMi4zIn0sImkiOnsiTiI6Ijk1In0sIm0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldE1hcCJ9LCJzIjp7IlMiOiJhIHN0cmluZyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V490P6SD39MP5K7HL8VK98G3FBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bbb475c0156546a2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0TWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "245" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "198765060" + ], + "X-Amzn-Requestid": [ + "EURB1EV23KT2R94HTQTVMM845NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJpIjp7Ik4iOiI5NSJ9LCJzIjp7IlMiOiJhIHN0cmluZyJ9LCJtIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRNYXAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMThjNWRhNjgtM2IyOC00MWMyLTk0NjItNjIxMDUwNjY5NDk0In0sImYiOnsiTiI6IjMyLjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "bd05fb3d2d514ba7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "285" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJkMGU3YWE0Ny01NWE3LTQ5Y2ItYmM5MC04NWM4NjJiOTNlM2IifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMzIuMyJ9LCJJIjp7Ik4iOiI5NSJ9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIlN0Ijp7IlMiOiJhIHN0cmluZyJ9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SKOR6AL3KGV2I1C2JD53LGAT9RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6898cd2b812fdfd2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "303" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1507481226" + ], + "X-Amzn-Requestid": [ + "OU9U80CDJ2FTCOLPRTC11NTPB3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEgc3RyaW5nIn0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMzIuMyJ9LCJJIjp7Ik4iOiI5NSJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZDBlN2FhNDctNTVhNy00OWNiLWJjOTAtODVjODYyYjkzZTNiIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "00b4fae87285178c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "229" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjQxY2RhNmYyLWU4NGEtNDVmNS04NGFhLTNhMDVmY2FjZDllZiJ9LCJmIjp7Ik4iOiIzMi4zIn0sImkiOnsiTiI6Ijk1In0sIm0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldE1hcEZQIn0sInMiOnsiUyI6ImEgc3RyaW5nIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8HUL09P3B2DM7R6EG3SIDO2CTRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3ff498af0bd3dea7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJmIiwiIzEiOiJtIiwiIzIiOiJiIiwiIzMiOiJEb2NzdG9yZVJldmlzaW9uIiwiIzQiOiJuYW1lIn0sIktleXMiOlt7Im5hbWUiOnsiUyI6InRlc3RHZXRNYXBGUCJ9fV0sIlByb2plY3Rpb25FeHByZXNzaW9uIjoiIzAsICMxLiMyLCAjMywgIzQifX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "195" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1750194121" + ], + "X-Amzn-Requestid": [ + "OBQBTL47ETJDU37RFCTSJSJ25FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJtIjp7Ik0iOnsiYiI6eyJTIjoidHdvIn19fSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNDFjZGE2ZjItZTg0YS00NWY1LTg0YWEtM2EwNWZjYWNkOWVmIn0sImYiOnsiTiI6IjMyLjMifSwibmFtZSI6eyJTIjoidGVzdEdldE1hcEZQIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "d71f1f93bc2a9a11", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "287" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3Y2Q5MzNkMi01YzE3LTQzZDAtOWQ1NS04MjY2ZjRjMGMyNzMifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMzIuMyJ9LCJJIjp7Ik4iOiI5NSJ9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIlN0Ijp7IlMiOiJhIHN0cmluZyJ9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3RGUCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "RN38RALLGDBTIM3SNN84PD8URVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "86235fb9db8d34b3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "238" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJTdCIsIiMxIjoiTSIsIiMyIjoiYSIsIiMzIjoiRG9jc3RvcmVSZXZpc2lvbiIsIiM0IjoibmFtZSJ9LCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0RlAifX1dLCJQcm9qZWN0aW9uRXhwcmVzc2lvbiI6IiMwLCAjMS4jMiwgIzMsICM0In19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "203" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1908347554" + ], + "X-Amzn-Requestid": [ + "TGKM4OP4FEG5R3MJB822KHJKPBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJTdCI6eyJTIjoiYSBzdHJpbmcifSwiTSI6eyJNIjp7ImEiOnsiUyI6Im9uZSJ9fX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjdjZDkzM2QyLTVjMTctNDNkMC05ZDU1LTgyNjZmNGMwYzI3MyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0RlAifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "57e057499877aeb2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "287" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiMDAyY2U5MS0wMzJiLTRkNzEtOGZmYy03ODQ3MGRhYmQ1MjcifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMzIuMyJ9LCJJIjp7Ik4iOiI5NSJ9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIlN0Ijp7IlMiOiJhIHN0cmluZyJ9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3RXQyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9O8R707GGV99OLK695U2U0JOU7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b2468b2fafddce28", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "210" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJzdCIsIiMxIjoibSIsIiMyIjoiYSIsIiMzIjoibmFtZSJ9LCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0V0MifX1dLCJQcm9qZWN0aW9uRXhwcmVzc2lvbiI6IiMwLCAjMS4jMiwgIzMifX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "89" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2845408016" + ], + "X-Amzn-Requestid": [ + "KBL6ROF0L9AS4AAN57F3Q660PBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0V0MifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "67e064081b81c38a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "99" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJkb2VzTm90RXhpc3QifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "Q5RSF0CGPRKMSPTHS47J5GNLMRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "9402acc25e116aea", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "TUNCJ4K91O3HD2K3TV834UGDLBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "82b6790613d8b0b8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1163" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3824987913" + ], + "X-Amzn-Requestid": [ + "M2EQVTAPKRH8QBSUG96E6SK1OBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7ImkiOnsiTiI6Ijk1In0sInMiOnsiUyI6ImEgc3RyaW5nIn0sIm0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldE1hcEZQIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjQxY2RhNmYyLWU4NGEtNDVmNS04NGFhLTNhMDVmY2FjZDllZiJ9LCJmIjp7Ik4iOiIzMi4zIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJhIHN0cmluZyJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjMyLjMifSwiSSI6eyJOIjoiOTUifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJNIjp7ImEiOnsiUyI6Im9uZSJ9LCJiIjp7IlMiOiJ0d28ifX19LCJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImQwZTdhYTQ3LTU1YTctNDljYi1iYzkwLTg1Yzg2MmI5M2UzYiJ9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSBzdHJpbmcifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIzMi4zIn0sIkkiOnsiTiI6Ijk1In0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdFdDIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImIwMDJjZTkxLTAzMmItNGQ3MS04ZmZjLTc4NDcwZGFiZDUyNyJ9fSx7ImkiOnsiTiI6Ijk1In0sInMiOnsiUyI6ImEgc3RyaW5nIn0sIm0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldE1hcCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIxOGM1ZGE2OC0zYjI4LTQxYzItOTQ2Mi02MjEwNTA2Njk0OTQifSwiZiI6eyJOIjoiMzIuMyJ9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSBzdHJpbmcifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIzMi4zIn0sIkkiOnsiTiI6Ijk1In0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdEZQIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjdjZDkzM2QyLTVjMTctNDNkMC05ZDU1LTgyNjZmNGMwYzI3MyJ9fV0sIlNjYW5uZWRDb3VudCI6NX0=" + } + }, + { + "ID": "ccf50f3cef62d8ef", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEdldE1hcEZQIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "ATTKRPF95EK9JI3T0AS79KOTAVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d2284b212b200d08", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "NG5TPEMNSAE0N44VH25A6ST4N3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "672b07b27f2d0174", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEdldE1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OBVFQMB17CURESVOVU76UGV0CNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ff1487d2605dcd91", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdFdDIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "EU6LB5N8ITQDEMS5T35O9LT4GFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "67b0e4f1b00e64d4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdEZQIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0OQS6UMQCFP5QTF7M9U26F0R9VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c73cd17ca209a3ed", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "215" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6IjE5YWUxZmVjLTA5ZWYtNDVkNC05YjUzLTIzNzNiZTA1ZGMzNiJ9LCJmIjp7Ik4iOiIzMi4zIn0sImkiOnsiTiI6Ijk1In0sIm0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldE1hcCJ9LCJzIjp7IlMiOiJhIHN0cmluZyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M6JHPB71C379BC50VAHB2GFABRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5840d641fc39faa6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0TWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "233" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1920791583" + ], + "X-Amzn-Requestid": [ + "ND44KPU7LN2JGH41Q69O0DPPPVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJpIjp7Ik4iOiI5NSJ9LCJFdGFnIjp7IlMiOiIxOWFlMWZlYy0wOWVmLTQ1ZDQtOWI1My0yMzczYmUwNWRjMzYifSwicyI6eyJTIjoiYSBzdHJpbmcifSwibSI6eyJNIjp7ImEiOnsiUyI6Im9uZSJ9LCJiIjp7IlMiOiJ0d28ifX19LCJuYW1lIjp7IlMiOiJ0ZXN0R2V0TWFwIn0sImYiOnsiTiI6IjMyLjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "00e7f61e57508973", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "285" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiIzZGE5YjJmNC0xMDIxLTQ5ZDctOTQ4ZC0yOWJmMTE3NmNkZmMifSwiRiI6eyJOIjoiMzIuMyJ9LCJJIjp7Ik4iOiI5NSJ9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIlN0Ijp7IlMiOiJhIHN0cmluZyJ9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3UD93H82MNEM7RVAA7UDKFPMINVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bd86a1d080dd7d14", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "303" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3503414013" + ], + "X-Amzn-Requestid": [ + "VTI0UB8HVM33E1UDKH2083EI1NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEgc3RyaW5nIn0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMzIuMyJ9LCJJIjp7Ik4iOiI5NSJ9LCJFdGFnIjp7IlMiOiIzZGE5YjJmNC0xMDIxLTQ5ZDctOTQ4ZC0yOWJmMTE3NmNkZmMifSwiTSI6eyJNIjp7ImEiOnsiUyI6Im9uZSJ9LCJiIjp7IlMiOiJ0d28ifX19LCJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "6c3a309a5f9a6e3a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "217" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6ImFmN2IxNjJlLWExMGItNDg4My1iNWM4LTIzMWMwMGFkZGVmMyJ9LCJmIjp7Ik4iOiIzMi4zIn0sImkiOnsiTiI6Ijk1In0sIm0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldE1hcEZQIn0sInMiOnsiUyI6ImEgc3RyaW5nIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "P9AO2M40IOK3VR9V5M4RRLAUS3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fa328cefd9e42dbf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "222" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJmIiwiIzEiOiJtIiwiIzIiOiJiIiwiIzMiOiJFdGFnIiwiIzQiOiJuYW1lIn0sIktleXMiOlt7Im5hbWUiOnsiUyI6InRlc3RHZXRNYXBGUCJ9fV0sIlByb2plY3Rpb25FeHByZXNzaW9uIjoiIzAsICMxLiMyLCAjMywgIzQifX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "183" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2607800856" + ], + "X-Amzn-Requestid": [ + "G1O6TT3N4JD7RCDLE1958D4NURVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiJhZjdiMTYyZS1hMTBiLTQ4ODMtYjVjOC0yMzFjMDBhZGRlZjMifSwibSI6eyJNIjp7ImIiOnsiUyI6InR3byJ9fX0sImYiOnsiTiI6IjMyLjMifSwibmFtZSI6eyJTIjoidGVzdEdldE1hcEZQIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "a2556337a84c09ac", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "287" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiI1NGEwOTUxYy1lNDdjLTRjOGUtOGE4ZS00MWEyNjlkMTI3N2EifSwiRiI6eyJOIjoiMzIuMyJ9LCJJIjp7Ik4iOiI5NSJ9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIlN0Ijp7IlMiOiJhIHN0cmluZyJ9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3RGUCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "S2ING9CPOV134LIUAMS0HK095VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b08b06f4c150d9fd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "226" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJTdCIsIiMxIjoiTSIsIiMyIjoiYSIsIiMzIjoiRXRhZyIsIiM0IjoibmFtZSJ9LCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0RlAifX1dLCJQcm9qZWN0aW9uRXhwcmVzc2lvbiI6IiMwLCAjMS4jMiwgIzMsICM0In19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "191" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2208663432" + ], + "X-Amzn-Requestid": [ + "2DDC3OMPBRO1A4L088FGCNFB3NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI1NGEwOTUxYy1lNDdjLTRjOGUtOGE4ZS00MWEyNjlkMTI3N2EifSwiU3QiOnsiUyI6ImEgc3RyaW5nIn0sIk0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifX19LCJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0RlAifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "43cfdc430791f0ef", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "287" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiIyNTNmZTVjMi03NDkxLTRhMTItYWNkMS01OTkxYWNhM2UzMmMifSwiRiI6eyJOIjoiMzIuMyJ9LCJJIjp7Ik4iOiI5NSJ9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIlN0Ijp7IlMiOiJhIHN0cmluZyJ9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3RXQyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GMCJ1PSQ790QRC384NL51AS2INVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6e4becf4ffc310ed", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "210" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJFeHByZXNzaW9uQXR0cmlidXRlTmFtZXMiOnsiIzAiOiJzdCIsIiMxIjoibSIsIiMyIjoiYSIsIiMzIjoibmFtZSJ9LCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0V0MifX1dLCJQcm9qZWN0aW9uRXhwcmVzc2lvbiI6IiMwLCAjMS4jMiwgIzMifX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "89" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2845408016" + ], + "X-Amzn-Requestid": [ + "SBQVAOEDAE20QIT6A3J7E929PVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0V0MifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "0a4991c4fa810c64", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "99" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJkb2VzTm90RXhpc3QifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "V8OSSPI2AI46VPJS0UMSETI5TNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/GetQuery.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/GetQuery.replay new file mode 100644 index 000000000..941c8598b --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/GetQuery.replay @@ -0,0 +1,2684 @@ +{ + "Initial": "AQAAAA7gDLPHIPZsUgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b9774beaab9959ed", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1609" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3233200316" + ], + "X-Amzn-Requestid": [ + "SOJT0AENKQEOQAGG558PLPKGI7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIkF0dHJpYnV0ZVR5cGUiOiJTIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJBdHRyaWJ1dGVUeXBlIjoiTiJ9LHsiQXR0cmlidXRlTmFtZSI6IlRpbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwODA2OTVFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkdsb2JhbFNlY29uZGFyeUluZGV4ZXMiOlt7IkluZGV4QXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMi9pbmRleC9nbG9iYWwiLCJJbmRleE5hbWUiOiJnbG9iYWwiLCJJbmRleFNpemVCeXRlcyI6MTA3LCJJbmRleFN0YXR1cyI6IkFDVElWRSIsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiUGxheWVyIiwiS2V5VHlwZSI6IkhBU0gifSx7IkF0dHJpYnV0ZU5hbWUiOiJUaW1lIiwiS2V5VHlwZSI6IlJBTkdFIn1dLCJQcm9qZWN0aW9uIjp7IlByb2plY3Rpb25UeXBlIjoiQUxMIn0sIlByb3Zpc2lvbmVkVGhyb3VnaHB1dCI6eyJOdW1iZXJPZkRlY3JlYXNlc1RvZGF5IjowLCJSZWFkQ2FwYWNpdHlVbml0cyI6NSwiV3JpdGVDYXBhY2l0eVVuaXRzIjo1fSwiV2FybVRocm91Z2hwdXQiOnsiUmVhZFVuaXRzUGVyU2Vjb25kIjo1LCJTdGF0dXMiOiJBQ1RJVkUiLCJXcml0ZVVuaXRzUGVyU2Vjb25kIjo1fX1dLCJJdGVtQ291bnQiOjEsIktleVNjaGVtYSI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJLZXlUeXBlIjoiSEFTSCJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIktleVR5cGUiOiJSQU5HRSJ9XSwiTG9jYWxTZWNvbmRhcnlJbmRleGVzIjpbeyJJbmRleEFybiI6ImFybjphd3M6ZHluYW1vZGI6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3Njp0YWJsZS9kb2NzdG9yZS10ZXN0LTIvaW5kZXgvbG9jYWwiLCJJbmRleE5hbWUiOiJsb2NhbCIsIkluZGV4U2l6ZUJ5dGVzIjoxMDcsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiR2FtZSIsIktleVR5cGUiOiJIQVNIIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJLZXlUeXBlIjoiUkFOR0UifV0sIlByb2plY3Rpb24iOnsiUHJvamVjdGlvblR5cGUiOiJBTEwifX1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMiIsIlRhYmxlSWQiOiIwZDRmOTk4My1kOGE5LTRhZjEtYTY0NC05YmE3M2NlMGYyMjciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIiLCJUYWJsZVNpemVCeXRlcyI6MTA3LCJUYWJsZVN0YXR1cyI6IkFDVElWRSIsIldhcm1UaHJvdWdocHV0Ijp7IlJlYWRVbml0c1BlclNlY29uZCI6NSwiU3RhdHVzIjoiQUNUSVZFIiwiV3JpdGVVbml0c1BlclNlY29uZCI6NX19fQ==" + } + }, + { + "ID": "e21da002ee16bb96", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4281140959" + ], + "X-Amzn-Requestid": [ + "63ORFM8JM09N83TG502MJM4H1RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiN2ZiOGU4Y2ItMTFhMi00M2Q5LTg5ZjgtYmFhZDE4OTFlYjIyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiMDIzM2RhMy1kZjExLTRlOTYtYjhiZi0zZDI3MzE1OGNjMzIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMGIwYTExNDktNjBiMy00ZjZlLTk1Y2UtNmRkZDNhMDE3MTllIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImViYjM0OTRkLTgwZjktNDI5My1hNmU5LWNlNTI1NDY5MDMyNCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZTdmYzdlYzYtNjA2OS00ODY3LTgxZWEtOTFlZjYyYzhhMWMwIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzgzZjUwNy1iMzA1LTRhZmMtYjkxMy1iMmRkNzgyMDc2MzAifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiN2ZlZWUyZWItOTdlNi00MmFmLThiNzMtNDMyZTMwNjgzN2Y1In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjkyYzk0N2ZkLWE5ODQtNGI1NS1hMGFiLThmODgyZDIxZWVkOSJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "7452a5df00697733", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "260" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOTJjOTQ3ZmQtYTk4NC00YjU1LWEwYWItOGY4ODJkMjFlZWQ5In19LCJLZXkiOnsiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "881TPOMBK5C98VU5TAD7J0TK9RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ed8353d7b2b2a063", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMGIwYTExNDktNjBiMy00ZjZlLTk1Y2UtNmRkZDNhMDE3MTllIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KD705HCO3HH4CTVGPVD7D8FST7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3f94e5a8a4128493", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "261" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOGM4M2Y1MDctYjMwNS00YWZjLWI5MTMtYjJkZDc4MjA3NjMwIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJQbGF5ZXIiOnsiUyI6ImZyYW4ifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "U65FRM8JPDGKM4R2TA1ET8EN5BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b4a6b0c3f62ed5d6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "261" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZTdmYzdlYzYtNjA2OS00ODY3LTgxZWEtOTFlZjYyYzhhMWMwIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V8JK9R3CBAFIQ07MJ881OJM5DJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "487c216283cc67ae", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYjAyMzNkYTMtZGYxMS00ZTk2LWI4YmYtM2QyNzMxNThjYzMyIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJQbGF5ZXIiOnsiUyI6ImZyYW4ifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SFEFLO7JODRVMVQS47KJG34VFJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f4c8a53b09e0716f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZWJiMzQ5NGQtODBmOS00MjkzLWE2ZTktY2U1MjU0NjkwMzI0In19LCJLZXkiOnsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "302H5NIC7TI6O44BF7OO6Q2933VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3b9d184b8c58523e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "260" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiN2ZlZWUyZWItOTdlNi00MmFmLThiNzMtNDMyZTMwNjgzN2Y1In19LCJLZXkiOnsiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "75OL3JILV4OUSAJSP6HPJUQHSJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "dfe9e5efd095321b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiN2ZiOGU4Y2ItMTFhMi00M2Q5LTg5ZjgtYmFhZDE4OTFlYjIyIn19LCJLZXkiOnsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PS80K5UOT2A38P53QPTCO3BV8BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "471ea669dcd74915", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "238" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiYmViMjM2LTdkZWItNGU4Ni1iMjhlLWNkZjhjNDYzYTMyMyJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlBsYXllciI6eyJTIjoiYmlsbGllIn0sIlNjb3JlIjp7Ik4iOiIxMTEifSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "Q7ELBIJPS74MTKDF5C0A7U2BTJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2d14ad7c990cfebb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTEzVDAwOjAwOjAwWiJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VUTHI0S6ON3TJ6VSPH2MB98R1JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d6e1214c3fa7c066", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjYzMTgzYzYzLTU5OTEtNDY0Ni1hZTA1LWVmOTlmZmNiOWVlYyJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiI2MCJ9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DJSIQJB97BC92SRLVO5HTIGBFRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7f71d35c85e369de", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiIxMjAifSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VBCKC5FO893KIFDNPS6E10T8URVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "50a75bbb39525595", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "244" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjllZmJmZDcxLTg2ZWEtNGUxOC1hOThhLWYwNmYzNmUzOTBjYSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlBsYXllciI6eyJTIjoiYW5keSJ9LCJTY29yZSI6eyJOIjoiODEifSwiVGltZSI6eyJTIjoiMjAxOS0wMi0wMVQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "K5RP0L1I9K8AM97V23QQIT9PARVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a1a9df3a875f6581", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "244" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjdlODc2NDdjLTRiYTctNDY2NC04MTc2LTlkZTNmY2NhMmVmNSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiVGltZSI6eyJTIjoiMjAxOS0wMy0xOVQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LF7B5DNC7KC6MMEPS5T04UNB3FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "088491458fb507e2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImFjZWM3OGYwLWI4MWYtNGE5NS04ODU2LWU3YzRkMDAwOTE5MiJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiIxOTAifSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xOFQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "J1P0GBE5OB2R3GTBKUPFOOATLJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3cd3d49898c5a996", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "235" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImVlYWYxNjAxLTAxZjQtNDBjYi05Y2MxLTgwYjk2N2IyMGI0YyJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiVGltZSI6eyJTIjoiMjAxOS0wMy0yMFQwMDowMDowMFoifSwiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "1TKN8JK4DILO627TFOQJSHTMVRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ebf4b5272c2b673d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "O2S2VU1135OE2OQGE83TG3B15FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "3f18eebafdcda2ae", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "184" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiWm9tYmllIERNViJ9fSwiS2V5Q29uZGl0aW9uRXhwcmVzc2lvbiI6IiMwID0gOjAiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "827" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "407519888" + ], + "X-Amzn-Requestid": [ + "DQNPKFA984258A4DJH5ORDB0J3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fV0sIlNjYW5uZWRDb3VudCI6NH0=" + } + }, + { + "ID": "460e863b96e3563b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "172" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IlNjb3JlIn0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiTiI6IjEwMCJ9fSwiRmlsdGVyRXhwcmVzc2lvbiI6IiMwID4gOjAiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "630" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1547493626" + ], + "X-Amzn-Requestid": [ + "15CMLDCHB5RJ78SNVEP0LDUR6JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xOFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjE5MCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImFjZWM3OGYwLWI4MWYtNGE5NS04ODU2LWU3YzRkMDAwOTE5MiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6dHJ1ZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMDFUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiIxMjAifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmMGI1NjhmZi0wYWM0LTQ4NGQtYTYwZS1mZGI3ZjcwMjM3YTYifX1dLCJTY2FubmVkQ291bnQiOjh9" + } + }, + { + "ID": "18adbee8490d2984", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "203" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IlBsYXllciJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJiaWxsaWUifX0sIkluZGV4TmFtZSI6Imdsb2JhbCIsIktleUNvbmRpdGlvbkV4cHJlc3Npb24iOiIjMCA9IDowIiwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "238" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3476953120" + ], + "X-Amzn-Requestid": [ + "R9P994FKP5BHF30UN1V27ROJ6FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IlBsYXllciI6eyJTIjoiYmlsbGllIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19XSwiU2Nhbm5lZENvdW50IjoxfQ==" + } + }, + { + "ID": "8f4ae6106a10213b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "241" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IlBsYXllciIsIiMxIjoiR2FtZSJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJhbmR5In0sIjoxIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn19LCJLZXlDb25kaXRpb25FeHByZXNzaW9uIjoiKCMwID0gOjApIEFORCAoIzEgPSA6MSkiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "244" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4063941634" + ], + "X-Amzn-Requestid": [ + "2GSJMH2SP7746PN2JQ13M8I8HFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19XSwiU2Nhbm5lZENvdW50IjoxfQ==" + } + }, + { + "ID": "2ba614f46294a09f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "259" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IlNjb3JlIiwiIzEiOiJQbGF5ZXIifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJOIjoiMTAwIn0sIjoxIjp7IlMiOiJwYXQifX0sIkZpbHRlckV4cHJlc3Npb24iOiIjMCA8IDowIiwiSW5kZXhOYW1lIjoiZ2xvYmFsIiwiS2V5Q29uZGl0aW9uRXhwcmVzc2lvbiI6IiMxID0gOjEiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "243" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "932361122" + ], + "X-Amzn-Requestid": [ + "JM058HLANAJ07SQ17UN6NAFMD3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IlBsYXllciI6eyJTIjoicGF0In0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTEzVDAwOjAwOjAwWiJ9LCJTY29yZSI6eyJOIjoiNDkifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiYWUxMmY4NC04MTcxLTQwMDktOGIwNi03YTNhODJjMWJmMDgifX1dLCJTY2FubmVkQ291bnQiOjJ9" + } + }, + { + "ID": "5851a6df5d87bf7e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "259" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUiLCIjMSI6IlNjb3JlIn0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiOjEiOnsiTiI6IjUwIn19LCJJbmRleE5hbWUiOiJsb2NhbCIsIktleUNvbmRpdGlvbkV4cHJlc3Npb24iOiIoIzAgPSA6MCkgQU5EICgjMSA+PSA6MSkiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "449" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3879197873" + ], + "X-Amzn-Requestid": [ + "EAI1NGUA74R0AG4UOV0CGQSQ67VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlNjb3JlIjp7Ik4iOiI2MCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2MzE4M2M2My01OTkxLTQ2NDYtYWUwNS1lZjk5ZmZjYjllZWMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiUGxheWVyIjp7IlMiOiJhbmR5In0sIlRpbWUiOnsiUyI6IjIwMTktMDItMDFUMDA6MDA6MDBaIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjllZmJmZDcxLTg2ZWEtNGUxOC1hOThhLWYwNmYzNmUzOTBjYSJ9fV0sIlNjYW5uZWRDb3VudCI6Mn0=" + } + }, + { + "ID": "073ba81aa672cee7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "262" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IlBsYXllciIsIiMxIjoiVGltZSJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJtZWwifSwiOjEiOnsiUyI6IjIwMTktMDQtMDFUMDA6MDA6MDBaIn19LCJJbmRleE5hbWUiOiJnbG9iYWwiLCJLZXlDb25kaXRpb25FeHByZXNzaW9uIjoiKCMwID0gOjApIEFORCAoIzEgPiA6MSkiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "439" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3892929952" + ], + "X-Amzn-Requestid": [ + "S8QJTJ3SP683SF4JEOJ13HHIARVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7IlBsYXllciI6eyJTIjoibWVsIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJTY29yZSI6eyJOIjoiNjAifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2MzE4M2M2My01OTkxLTQ2NDYtYWUwNS1lZjk5ZmZjYjllZWMifX0seyJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19XSwiU2Nhbm5lZENvdW50IjoyfQ==" + } + }, + { + "ID": "ded0eb99183acc5e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IlNjb3JlIiwiIzEiOiJUaW1lIn0sIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXMiOnsiOjAiOnsiTiI6IjUwIn0sIjoxIjp7IlMiOiIyMDE5LTA0LTAxVDAwOjAwOjAwWiJ9fSwiRmlsdGVyRXhwcmVzc2lvbiI6IigjMCA+PSA6MCkgQU5EICgjMSA+IDoxKSIsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "639" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2069315016" + ], + "X-Amzn-Requestid": [ + "7HRIJO3QCH8MOJVC5ETLJLT5LBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xOFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjE5MCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImFjZWM3OGYwLWI4MWYtNGE5NS04ODU2LWU3YzRkMDAwOTE5MiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiNjAifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2MzE4M2M2My01OTkxLTQ2NDYtYWUwNS1lZjk5ZmZjYjllZWMifX1dLCJTY2FubmVkQ291bnQiOjh9" + } + }, + { + "ID": "5b5ef5c0496f9455", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "200" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IlBsYXllciJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJwYXQifSwiOjEiOnsiUyI6ImJpbGxpZSJ9fSwiRmlsdGVyRXhwcmVzc2lvbiI6IiMwIElOICg6MCwgOjEpIiwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "639" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2104643946" + ], + "X-Amzn-Requestid": [ + "C7OHUBN9G3HI29P5ARCUGSKTFFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTEzVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9LCJTY29yZSI6eyJOIjoiNDkifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiYWUxMmY4NC04MTcxLTQwMDktOGIwNi03YTNhODJjMWJmMDgifX1dLCJTY2FubmVkQ291bnQiOjh9" + } + }, + { + "ID": "664b49fdfb0e0dfc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "206" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IlBsYXllciJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJwYXQifSwiOjEiOnsiUyI6ImJpbGxpZSJ9fSwiRmlsdGVyRXhwcmVzc2lvbiI6Ik5PVCAoIzAgSU4gKDowLCA6MSkpIiwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1048" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4293966089" + ], + "X-Amzn-Requestid": [ + "77F6QIF2MPMBHTPN8AP80MAVRBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTIwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImZyYW4ifSwiU2NvcmUiOnsiTiI6IjMzIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWVhZjE2MDEtMDFmNC00MGNiLTljYzEtODBiOTY3YjIwYjRjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xOFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjE5MCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImFjZWM3OGYwLWI4MWYtNGE5NS04ODU2LWU3YzRkMDAwOTE5MiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19XSwiU2Nhbm5lZENvdW50Ijo4fQ==" + } + }, + { + "ID": "46b7638b5cd9a9e0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "179" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IldpdGhHbGl0Y2gifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJCT09MIjp0cnVlfX0sIkZpbHRlckV4cHJlc3Npb24iOiIjMCA9IDowIiwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "430" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4278210054" + ], + "X-Amzn-Requestid": [ + "42BIPFAPFA9ADF0JKVFM2N8U8RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6dHJ1ZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMThUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiIxOTAifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhY2VjNzhmMC1iODFmLTRhOTUtODg1Ni1lN2M0ZDAwMDkxOTIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9LCJTY29yZSI6eyJOIjoiMTIwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZjBiNTY4ZmYtMGFjNC00ODRkLWE2MGUtZmRiN2Y3MDIzN2E2In19XSwiU2Nhbm5lZENvdW50Ijo4fQ==" + } + }, + { + "ID": "4e9a7f4692a4d1ff", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "182" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IldpdGhHbGl0Y2gifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJCT09MIjp0cnVlfX0sIkZpbHRlckV4cHJlc3Npb24iOiIjMCBJTiAoOjApIiwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "430" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4278210054" + ], + "X-Amzn-Requestid": [ + "CLPU42JLVIJQ96LQ22V8CC2PK7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6dHJ1ZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMThUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiIxOTAifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhY2VjNzhmMC1iODFmLTRhOTUtODg1Ni1lN2M0ZDAwMDkxOTIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9LCJTY29yZSI6eyJOIjoiMTIwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZjBiNTY4ZmYtMGFjNC00ODRkLWE2MGUtZmRiN2Y3MDIzN2E2In19XSwiU2Nhbm5lZENvdW50Ijo4fQ==" + } + }, + { + "ID": "dbef6c8b9a1a7c57", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "188" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IldpdGhHbGl0Y2gifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJCT09MIjp0cnVlfX0sIkZpbHRlckV4cHJlc3Npb24iOiJOT1QgKCMwIElOICg6MCkpIiwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1257" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "105402933" + ], + "X-Amzn-Requestid": [ + "K23NSQBVDL6RH6IOP9EP70KURJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NiwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wMi0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJhbmR5In0sIlNjb3JlIjp7Ik4iOiI4MSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjllZmJmZDcxLTg2ZWEtNGUxOC1hOThhLWYwNmYzNmUzOTBjYSJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTE5VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImZyYW4ifSwiU2NvcmUiOnsiTiI6IjMzIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiN2U4NzY0N2MtNGJhNy00NjY0LTgxNzYtOWRlM2ZjY2EyZWY1In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMTBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiI2MCJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjYzMTgzYzYzLTU5OTEtNDY0Ni1hZTA1LWVmOTlmZmNiOWVlYyJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTEzVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9LCJTY29yZSI6eyJOIjoiNDkifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiYWUxMmY4NC04MTcxLTQwMDktOGIwNi03YTNhODJjMWJmMDgifX1dLCJTY2FubmVkQ291bnQiOjh9" + } + }, + { + "ID": "ce50fa6cfc9b2e5c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "N5GBI9EFO7SO81OLPHMQSI415FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "10a1040fa7f689ba", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "KI9LML204NRSQQHD0OO47EQT2FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "df7269f276ef876d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "238" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUiLCIjMSI6IlBsYXllciJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIjoxIjp7IlMiOiIuIn19LCJLZXlDb25kaXRpb25FeHByZXNzaW9uIjoiKCMwID0gOjApIEFORCAoIzEgPiA6MSkiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "860" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2482836965" + ], + "X-Amzn-Requestid": [ + "U0D92A8I23UE1PVAKPC51C09IBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6NH0=" + } + }, + { + "ID": "9dd130df4a6eb40a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "263" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUiLCIjMSI6IlBsYXllciJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIjoxIjp7IlMiOiIuIn19LCJLZXlDb25kaXRpb25FeHByZXNzaW9uIjoiKCMwID0gOjApIEFORCAoIzEgPiA6MSkiLCJTY2FuSW5kZXhGb3J3YXJkIjpmYWxzZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "860" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1147095823" + ], + "X-Amzn-Requestid": [ + "N458FNGSISOHPA201J8T1P1OP7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTEzVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9LCJTY29yZSI6eyJOIjoiNDkifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiYWUxMmY4NC04MTcxLTQwMDktOGIwNi03YTNhODJjMWJmMDgifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wMi0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJhbmR5In0sIlNjb3JlIjp7Ik4iOiI4MSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjllZmJmZDcxLTg2ZWEtNGUxOC1hOThhLWYwNmYzNmUzOTBjYSJ9fV0sIlNjYW5uZWRDb3VudCI6NH0=" + } + }, + { + "ID": "c4e0d0b5688f057b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "169" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUiLCIjMSI6IlBsYXllciIsIiMyIjoiRG9jc3RvcmVSZXZpc2lvbiJ9LCJQcm9qZWN0aW9uRXhwcmVzc2lvbiI6IiMwLCAjMSwgIzIiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "984" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3080042027" + ], + "X-Amzn-Requestid": [ + "FNMB5S0SCOC0M2HS8EBV5HGI6NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn0sIlBsYXllciI6eyJTIjoiYmlsbGllIn19LHsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifSwiUGxheWVyIjp7IlMiOiJmcmFuIn19LHsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhY2VjNzhmMC1iODFmLTRhOTUtODg1Ni1lN2M0ZDAwMDkxOTIifSwiUGxheWVyIjp7IlMiOiJtZWwifX0seyJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9fSx7IkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn0sIlBsYXllciI6eyJTIjoiYW5keSJ9fSx7IkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiN2U4NzY0N2MtNGJhNy00NjY0LTgxNzYtOWRlM2ZjY2EyZWY1In0sIlBsYXllciI6eyJTIjoiZnJhbiJ9fSx7IkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn0sIlBsYXllciI6eyJTIjoibWVsIn19LHsiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiYWUxMmY4NC04MTcxLTQwMDktOGIwNi03YTNhODJjMWJmMDgifSwiUGxheWVyIjp7IlMiOiJwYXQifX1dLCJTY2FubmVkQ291bnQiOjh9" + } + }, + { + "ID": "e83af4dd2b62e30e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "208" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUiLCIjMSI6IlBsYXllciIsIiMyIjoiU2NvcmUiLCIjMyI6IldpdGhHbGl0Y2giLCIjNCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiUHJvamVjdGlvbkV4cHJlc3Npb24iOiIjMCwgIzEsICMyLCAjMywgIzQiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1361" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "324124003" + ], + "X-Amzn-Requestid": [ + "I0KB4T46Q5A437VFVLEL5QJLEFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IlBsYXllciI6eyJTIjoiYmlsbGllIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlNjb3JlIjp7Ik4iOiIxMTEifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiUGxheWVyIjp7IlMiOiJmcmFuIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlNjb3JlIjp7Ik4iOiIzMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlNjb3JlIjp7Ik4iOiIxOTAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiUGxheWVyIjp7IlMiOiJwYXQifSwiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJTY29yZSI6eyJOIjoiMTIwIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IlBsYXllciI6eyJTIjoiYW5keSJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJTY29yZSI6eyJOIjoiODEifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiUGxheWVyIjp7IlMiOiJmcmFuIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlNjb3JlIjp7Ik4iOiIzMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJTY29yZSI6eyJOIjoiNjAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiUGxheWVyIjp7IlMiOiJwYXQifSwiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiU2NvcmUiOnsiTiI6IjQ5In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "5ef2ca838471eecb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "5JC9FOQQ5K9EALHQ6AT6M76M5VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "65a90aa4bd608b0d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "SQ2AJ043UPJOST8JVCKL2PV4AVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "9ff8dffd334c2fdc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "UDO82H4E8GP13A6GH5RSD6UU0RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "574614494578b718", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "14CM8E8FV1TK1GULGCK5UIORANVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "96055385a5261556", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "08FDUKJ2VCME85LPU81LI6GHN7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "28b12c8e4b617e25", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "IK66QUOGT6BT3P67B8349CNMCFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "db218b65b95482e9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "UPUONC07PERNN4GM6H1FFEU7ABVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "d64c03395ae613d4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "2JP0JFE2BOJSNAE2G6P17RVK1FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "133d299c0304e190", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "FADGEO23B3287O8SCVRR8L4RAFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "9638e91184aad2c9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "188240982" + ], + "X-Amzn-Requestid": [ + "MSS6I767A945RLHNB4EMJ0V8HVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmJiZWIyMzYtN2RlYi00ZTg2LWIyOGUtY2RmOGM0NjNhMzIzIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZWFmMTYwMS0wMWY0LTQwY2ItOWNjMS04MGI5NjdiMjBiNGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWNlYzc4ZjAtYjgxZi00YTk1LTg4NTYtZTdjNGQwMDA5MTkyIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImYwYjU2OGZmLTBhYzQtNDg0ZC1hNjBlLWZkYjdmNzAyMzdhNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWVmYmZkNzEtODZlYS00ZTE4LWE5OGEtZjA2ZjM2ZTM5MGNhIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZTg3NjQ3Yy00YmE3LTQ2NjQtODE3Ni05ZGUzZmNjYTJlZjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjMxODNjNjMtNTk5MS00NjQ2LWFlMDUtZWY5OWZmY2I5ZWVjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImJhZTEyZjg0LTgxNzEtNDAwOS04YjA2LTdhM2E4MmMxYmYwOCJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/GetQueryKeyField.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/GetQueryKeyField.replay new file mode 100644 index 000000000..a2c8cc1cf --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/GetQueryKeyField.replay @@ -0,0 +1,1309 @@ +{ + "Initial": "AQAAAA7gDLPEF1OMFAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "215cd555fc34bc04", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "0BLN2OJUP6I54BSATP8M23H13NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "6b3e29f04a09f4dc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "699" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2058760560" + ], + "X-Amzn-Requestid": [ + "I4K26EG25SC5C0EP6JE0DHNJ8FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NiwiSXRlbXMiOlt7IkV0YWciOnsiUyI6ImIxMGZiODBkLTAxZGEtNDM1ZS04ZDAxLTdiZGRjYzZhMWI1YiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifSwicyI6eyJTIjoiMyJ9fSx7IkV0YWciOnsiUyI6IjliNzFkOTE3LWMzNWYtNDI1Yi1hM2JiLTBjOThlZTQ2MzgzOSJ9LCJzIjp7IlMiOiI4In0sIm4iOnsiTiI6Ii0xIn0sIm5hbWUiOnsiUyI6InRlc3RVbm9yZGVyZWRBY3Rpb25zOCJ9fSx7IkV0YWciOnsiUyI6IjQ0ODRmYmM5LTEzYzMtNDQ0Ni1hNzg2LWFkMWU5NWYzZGM5MSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczQifSwicyI6eyJTIjoiNCJ9fSx7IkV0YWciOnsiUyI6IjA5MzM2N2YyLTc4NjQtNGU0NS1iYmFlLWNhMjFkMDRjMmU5ZCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczcifSwicyI6eyJTIjoiNycifX0seyJFdGFnIjp7IlMiOiI1NzA3M2RhZi1mNThmLTQ4NGUtYjVkNS0zOGM2NjZkZTg3Y2MifSwicyI6eyJTIjoiNicifSwibiI6eyJOIjoiMSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczYifX0seyJFdGFnIjp7IlMiOiI5ZjI1MDM2OC01OGU3LTRjMWItYjllOC1lNGUyYTUyM2I0MGMifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM1In0sInMiOnsiUyI6IjUifX1dLCJTY2FubmVkQ291bnQiOjZ9" + } + }, + { + "ID": "00a8c190e7804879", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM1In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "59GR3TDR87D1U6TG989DF7G5NNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8ec2750865715261", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DT250M58SUSCDI6HQGBQT35B87VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "75424ad2f057fbee", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM4In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MI9BS7ASJ127QG0610T6OEF07JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cbccab7411a1fe36", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM3In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M5TTPNV91RPNEPOF6G7TKT1OE3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3204583a7104cc60", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMzIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SMS8VOILD691RIA3E8UKJ8EQCBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "02b1af0dbcdf605f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM2In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "12TAT7OKBS2G7GS580HILEHCMBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7b5a0c3d67502ef0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "140" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjMxNDVlZDI1LTg4NWEtNDcxYy04Nzk0LWM4MzlkYjk1MzM4NyJ9LCJhIjp7IlMiOiJvbmUifSwibmFtZSI6eyJTIjoicWtmMSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "BM0MUI4C7K2OU4VMLV7ED3851VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5eb6a19e9d1a3873", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "140" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjIyZWVjMzE1LTRjNzktNDEyMS05NDU3LTdmNWJmMzEwZGQ0OSJ9LCJhIjp7IlMiOiJ0d28ifSwibmFtZSI6eyJTIjoicWtmMiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "559J4AI9FE349A8UTE9GA0526RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "304fedc0a226cc60", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "142" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjRhMTkxMDI3LTJmMGItNDhmOC1hMGM2LWY1Y2M1ZWVmNTljMCJ9LCJhIjp7IlMiOiJ0aHJlZSJ9LCJuYW1lIjp7IlMiOiJxa2YzIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9AOO9NH1OPAIB3UDUD0RV02G2BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "042b6cae3e369fe7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJxa2YzIn19LCJGaWx0ZXJFeHByZXNzaW9uIjoiIzAgPCA6MCIsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "242" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1237852492" + ], + "X-Amzn-Requestid": [ + "0S86GJ4J21THU81H21CUJNBD2FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJuYW1lIjp7IlMiOiJxa2YxIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjMxNDVlZDI1LTg4NWEtNDcxYy04Nzk0LWM4MzlkYjk1MzM4NyJ9fSx7ImEiOnsiUyI6InR3byJ9LCJuYW1lIjp7IlMiOiJxa2YyIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjIyZWVjMzE1LTRjNzktNDEyMS05NDU3LTdmNWJmMzEwZGQ0OSJ9fV0sIlNjYW5uZWRDb3VudCI6M30=" + } + }, + { + "ID": "106368e3071271a5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoiYSIsIiMxIjoiRG9jc3RvcmVSZXZpc2lvbiIsIiMyIjoibmFtZSJ9LCJQcm9qZWN0aW9uRXhwcmVzc2lvbiI6IiMwLCAjMSwgIzIiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "346" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3108631221" + ], + "X-Amzn-Requestid": [ + "FMPL5HNR8DJ1FUHBMV2T24DDOVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIzMTQ1ZWQyNS04ODVhLTQ3MWMtODc5NC1jODM5ZGI5NTMzODcifSwibmFtZSI6eyJTIjoicWtmMSJ9fSx7ImEiOnsiUyI6InRocmVlIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjRhMTkxMDI3LTJmMGItNDhmOC1hMGM2LWY1Y2M1ZWVmNTljMCJ9LCJuYW1lIjp7IlMiOiJxa2YzIn19LHsiYSI6eyJTIjoidHdvIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjIyZWVjMzE1LTRjNzktNDEyMS05NDU3LTdmNWJmMzEwZGQ0OSJ9LCJuYW1lIjp7IlMiOiJxa2YyIn19XSwiU2Nhbm5lZENvdW50IjozfQ==" + } + }, + { + "ID": "c80b5c63b851b24a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "TSAHSEARNTDJ9COPP8SS81O8SJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "54d7c0d1ccf2b8f4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "346" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1279062108" + ], + "X-Amzn-Requestid": [ + "OV1OU4USMORRKE2TS9CIR2QIQ3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJuYW1lIjp7IlMiOiJxa2YxIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjMxNDVlZDI1LTg4NWEtNDcxYy04Nzk0LWM4MzlkYjk1MzM4NyJ9fSx7ImEiOnsiUyI6InRocmVlIn0sIm5hbWUiOnsiUyI6InFrZjMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNGExOTEwMjctMmYwYi00OGY4LWEwYzYtZjVjYzVlZWY1OWMwIn19LHsiYSI6eyJTIjoidHdvIn0sIm5hbWUiOnsiUyI6InFrZjIifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMjJlZWMzMTUtNGM3OS00MTIxLTk0NTctN2Y1YmYzMTBkZDQ5In19XSwiU2Nhbm5lZENvdW50IjozfQ==" + } + }, + { + "ID": "7f9f6562a5a383f6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoicWtmMSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VHQ3RHHOQME10S4VQMONLB0GTJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6b1ff712bb132b6e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoicWtmMiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "52KBE8QU29KJG55CK3ISKN0IPJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c87d60de60cb8ed9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoicWtmMyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "Q5U23S4VPARAQBBIMDBETAR0O3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "367c61805ba6c938", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "128" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6ImVhNWMxNGIwLTQzNDgtNGY5ZC1hYzg1LTM1MDI3NGUwYmI3NCJ9LCJhIjp7IlMiOiJ0d28ifSwibmFtZSI6eyJTIjoicWtmMiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KCNL9AACGDVPGND2GH55FOLCFVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a8a23e10b9c18a8c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "130" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6ImNlNzlkMzcyLTVmYmUtNDU1ZC1hMDYyLTgzN2QyYjU2M2U5OCJ9LCJhIjp7IlMiOiJ0aHJlZSJ9LCJuYW1lIjp7IlMiOiJxa2YzIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8J4DF3T6KVJQ1D0A8NOJEL317FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fd844e1428452659", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "128" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6IjkxNDZhOTRkLTU4ZjctNDA2My1iODI4LTVhZDMwZTk0ZmM3ZiJ9LCJhIjp7IlMiOiJvbmUifSwibmFtZSI6eyJTIjoicWtmMSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GU1QV5368DO7EV4JMCTR1A6BQVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9cd09aaa8cf30346", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJxa2YzIn19LCJGaWx0ZXJFeHByZXNzaW9uIjoiIzAgPCA6MCIsIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "218" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4060115118" + ], + "X-Amzn-Requestid": [ + "IMNEKSJFQJA1GDS5K5K1C1CLPBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJFdGFnIjp7IlMiOiI5MTQ2YTk0ZC01OGY3LTQwNjMtYjgyOC01YWQzMGU5NGZjN2YifSwibmFtZSI6eyJTIjoicWtmMSJ9fSx7ImEiOnsiUyI6InR3byJ9LCJFdGFnIjp7IlMiOiJlYTVjMTRiMC00MzQ4LTRmOWQtYWM4NS0zNTAyNzRlMGJiNzQifSwibmFtZSI6eyJTIjoicWtmMiJ9fV0sIlNjYW5uZWRDb3VudCI6M30=" + } + }, + { + "ID": "ae179c5f150e7691", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "151" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoiYSIsIiMxIjoiRXRhZyIsIiMyIjoibmFtZSJ9LCJQcm9qZWN0aW9uRXhwcmVzc2lvbiI6IiMwLCAjMSwgIzIiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "310" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3738458997" + ], + "X-Amzn-Requestid": [ + "8VEUV7E2AAD9ICE69E8A7KIGHNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJFdGFnIjp7IlMiOiI5MTQ2YTk0ZC01OGY3LTQwNjMtYjgyOC01YWQzMGU5NGZjN2YifSwibmFtZSI6eyJTIjoicWtmMSJ9fSx7ImEiOnsiUyI6InRocmVlIn0sIkV0YWciOnsiUyI6ImNlNzlkMzcyLTVmYmUtNDU1ZC1hMDYyLTgzN2QyYjU2M2U5OCJ9LCJuYW1lIjp7IlMiOiJxa2YzIn19LHsiYSI6eyJTIjoidHdvIn0sIkV0YWciOnsiUyI6ImVhNWMxNGIwLTQzNDgtNGY5ZC1hYzg1LTM1MDI3NGUwYmI3NCJ9LCJuYW1lIjp7IlMiOiJxa2YyIn19XSwiU2Nhbm5lZENvdW50IjozfQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/MultipleActions.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/MultipleActions.replay new file mode 100644 index 000000000..28a1f5851 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/MultipleActions.replay @@ -0,0 +1,3619 @@ +{ + "Initial": "AQAAAA7gDLPCCjXIFAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "c9268475b9c07807", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "9EKBV8POFNI10PQDLNDI1OEHPBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "5fa9d5b1cb125ca5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "174" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "115259572" + ], + "X-Amzn-Requestid": [ + "DL40FCV70VNVG0J7C7QA0SOV6RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IlB0clRvUHJvdG8iOnsiQiI6IkNDcz0ifSwibmFtZSI6eyJTIjoidGVzdGluZyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmMzZlOGE4Yi03ZDAzLTRmNzAtYmYyZC04OWMzMDljMmQwM2EifSwiUHJvdG8iOnsiQiI6IkNDbz0ifX1dLCJTY2FubmVkQ291bnQiOjF9" + } + }, + { + "ID": "d758f722c3465aec", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "227" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZjM2ZThhOGItN2QwMy00ZjcwLWJmMmQtODljMzA5YzJkMDNhIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdGluZyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0J43SRA3QK9EPSLV105MRE5P8RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a1ca4d7fd6dd6460", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiZjFjZmE0MS1hMTE5LTQ2MGEtODVlOS1jNmZkMGNmNWY0MjQifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM1In0sInMiOnsiUyI6IjUifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "31P9834HNBKV3Q5LI3P0636MI3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "72b1ad77057adfed", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIyOWZiNzRiNC1hMmM3LTQwOGYtYTAyMy1jMWJjODUxNGY1ZTQifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM0In0sInMiOnsiUyI6IjQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UDH3N7BD5TQEV3C0TINO51QPORVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5fce7fe5d3a5d495", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIzN2I4MGNjMS1hMmUxLTQ4MjEtYmVhNi03ZGM2NjNmMDIxZTQifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMzIn0sInMiOnsiUyI6IjMifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TCSHSDK4PS8PM74K0FG0D3S257VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "478298ddab39aa20", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIwYmJmYTIxMi1iMDcxLTQ2MDEtOWY4OC0yNjIwMGU3MzM0M2IifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMxIn0sInMiOnsiUyI6IjEifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LSQ3G46JF7JKD071C9SL5FDF4NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0cfa102567059bc4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJjZWU4YmQwZi0wZTE0LTQ5ZDktOGIzYy1hYjkzNWZiMDBkMjgifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMyIn0sInMiOnsiUyI6IjIifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JVDCMFGP8OCS9DV47L390L7UUFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9c45230cc496f904", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI0MTNjZjgwNS0wMDQ5LTRkYjktYjQ3ZS03NjIzNTI4ODYxMWQifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMwIn0sInMiOnsiUyI6IjAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8KKGI3DG1RAD1IG3VBH7GBAKMBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "77c46aa084d51828", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjEwZjM4MDRhLWQ3MWItNGFiYy05NzNkLWEwOWQ0ZjBkMDVlMiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczgifSwicyI6eyJTIjoiOCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5VD6KB8DNSBG63PCHGQLA97LA7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bf8d35428a1f86d8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "320" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMzdiODBjYzEtYTJlMS00ODIxLWJlYTYtN2RjNjYzZjAyMWU0In19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImIxNzQzMzAyLWQyZjMtNDQ1NC1hMTllLWM2YzQwZTljMTJiYiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifSwicyI6eyJTIjoiMyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "994SKLBT109MVAIMMDILOK224JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d7eb95af9fc25dfa", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "320" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYmYxY2ZhNDEtYTExOS00NjBhLTg1ZTktYzZmZDBjZjVmNDI0In19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImZlM2NmODkzLWY3OWYtNDI5Ny1iNjMzLThjZjY5NDczNDI4OCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifSwicyI6eyJTIjoiNSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KRVRI78SI7Q3P6SUFE5234J6NNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f054e92e82c25e70", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjAwNDFiNGE3LTVjNzYtNDlhYi1hYzk5LTI2Yzg0YjM0NjIwMCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczcifSwicyI6eyJTIjoiNyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0930PFGGBPOG79FMOO9HFMUG1VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "48c166b5191c2cbf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjU4MWNmN2YzLTg1ZDAtNDllNi1hYzNjLWEzNDliN2FhNDg5NyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczYifSwicyI6eyJTIjoiNiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CM3R424AKLCQTONHALQFLQUQ33VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "44b5514a932c3d76", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "321" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMGJiZmEyMTItYjA3MS00NjAxLTlmODgtMjYyMDBlNzMzNDNiIn19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijc5ZTZkMWQ3LWRiZDYtNDA1Mi1iY2FjLTYyNTk0OWRjYjI2MiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczEifSwicyI6eyJTIjoiMScifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CNTDJ4MRN8J3JB91E6O46FMD23VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "141fd01fe9599e78", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "320" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMjlmYjc0YjQtYTJjNy00MDhmLWEwMjMtYzFiYzg1MTRmNWU0In19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijc2YWJlNzIyLWU3OGQtNDUwNi1hMjE2LWVlYjE5MTRkODhlYyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczQifSwicyI6eyJTIjoiNCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9ISEB0OCLHS5STU8CJ85LR3NHJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7897c1cf11e66dc3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "321" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiY2VlOGJkMGYtMGUxNC00OWQ5LThiM2MtYWI5MzVmYjAwZDI4In19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjMyNGU0Nzk5LTk3MjAtNDY3ZC05YWRiLTA3ZTc3ZGQ4ZTIxNyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczIifSwicyI6eyJTIjoiMicifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "P370UNKRNV2V8S1P89P1CD02EFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ee41f603d5ba8c91", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "321" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNDEzY2Y4MDUtMDA0OS00ZGI5LWI0N2UtNzYyMzUyODg2MTFkIn19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjQ2NDRiMDc1LTAwZTAtNDQ1NC04MjM2LWUzY2Q4Mjk5NWY3MyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczAifSwicyI6eyJTIjoiMCcifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QP48JM9DTUQER1PFOO0LBROJ73VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5090da622ec16065", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "186" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczQifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "407" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2492195921" + ], + "X-Amzn-Requestid": [ + "LD4M2JTJINGF4L0VRRRTFD8UUJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZmUzY2Y4OTMtZjc5Zi00Mjk3LWI2MzMtOGNmNjk0NzM0Mjg4In0sInMiOnsiUyI6IjUifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczQifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNzZhYmU3MjItZTc4ZC00NTA2LWEyMTYtZWViMTkxNGQ4OGVjIn0sInMiOnsiUyI6IjQifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYjE3NDMzMDItZDJmMy00NDU0LWExOWUtYzZjNDBlOWMxMmJiIn0sInMiOnsiUyI6IjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "e205911f7c205a04", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "362" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24iLCIjMSI6Im4ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMTBmMzgwNGEtZDcxYi00YWJjLTk3M2QtYTA5ZDRmMGQwNWUyIn0sIjoxIjp7Ik4iOiItMSJ9LCI6MiI6eyJTIjoiZGNlMTA0MDgtODRmOS00MjI5LTllMjQtOWQ4YzFiNTM2MTI5In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM4In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiQUREICMxIDoxXG5TRVQgIzAgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "IRPVE4FECBVB3S2GPCT500942BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bd42dbac32b67d30", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "241" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNDY0NGIwNzUtMDBlMC00NDU0LTgyMzYtZTNjZDgyOTk1ZjczIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "168SCKGO0B0P11S9N1CSETAQGBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "eadb5fc291279b06", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "360" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24iLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMDA0MWI0YTctNWM3Ni00OWFiLWFjOTktMjZjODRiMzQ2MjAwIn0sIjoxIjp7IlMiOiI3JyJ9LCI6MiI6eyJTIjoiYWQ0MTk5MDgtNjkwNC00ZGI3LWI1YTktZmRkNWQ1MDllYjA0In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM3In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiU0VUICMxID0gOjEsICMwID0gOjJcbiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "IJNUF0BNGN27P9PIK1H86HS1BBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3856b759e058a529", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "241" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMzI0ZTQ3OTktOTcyMC00NjdkLTlhZGItMDdlNzdkZDhlMjE3In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMyIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8SPOJQMR458UPDPK995S8ANAIJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "17927a891461d2d8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "241" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNzllNmQxZDctZGJkNi00MDUyLWJjYWMtNjI1OTQ5ZGNiMjYyIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMxIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LL4G95JGGPBO361Q7KE8MGVVCVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "198575a98eac096a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "395" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24iLCIjMSI6Im4iLCIjMiI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNTgxY2Y3ZjMtODVkMC00OWU2LWFjM2MtYTM0OWI3YWE0ODk3In0sIjoxIjp7Ik4iOiIxIn0sIjoyIjp7IlMiOiI2JyJ9LCI6MyI6eyJTIjoiNTA2ZmY3NDUtNTJiMy00M2Q1LThlMWItNmEyNzgxMjU5MjQyIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM2In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiQUREICMxIDoxXG5TRVQgIzIgPSA6MiwgIzAgPSA6M1xuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8R3SPNJU2K06RCBB6MUFO3F643VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "64dd0361179205fa", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "108" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczAifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "KTTANVU0R2NBRHQ0BT03P79K9VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "c052e4442246a431", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0AS3DJP4AAPRVACJ53LJHDIG17VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5d0230b32f87a107", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "186" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczEifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczIifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "173" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3755655802" + ], + "X-Amzn-Requestid": [ + "NQ06OQD9SA0B1AE12D1DG2F733VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYjE3NDMzMDItZDJmMy00NDU0LWExOWUtYzZjNDBlOWMxMmJiIn0sInMiOnsiUyI6IjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "a6282a08c7d521d1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "320" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZmUzY2Y4OTMtZjc5Zi00Mjk3LWI2MzMtOGNmNjk0NzM0Mjg4In19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjNjNzRlNTlhLTMzODgtNDcxMC1hODcyLWU5ZTk0NDAyZjFlZCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifSwicyI6eyJTIjoiNSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TVPDSJQS3PEQHH99PVAJN64A7FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1c83454d07906af2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmZjE0YTE0MC1iOWQzLTQ2NDAtOGE5NC1mMWMyMWYyYTQ0ZGUifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM0In0sInMiOnsiUyI6IjQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "RTM3RJTUORG04N398O53EDS6F7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "ccc5f391be7c333a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "H682D2D9VUE7G53T9NSVOKK7OFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "a5807f7e16eb764f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "771" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2088285022" + ], + "X-Amzn-Requestid": [ + "0S9PGKGH34BU9E56FJNDDCVM0RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NiwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3RVbm9yZGVyZWRBY3Rpb25zMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiMTc0MzMwMi1kMmYzLTQ0NTQtYTE5ZS1jNmM0MGU5YzEyYmIifSwicyI6eyJTIjoiMyJ9fSx7InMiOnsiUyI6IjgifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZGNlMTA0MDgtODRmOS00MjI5LTllMjQtOWQ4YzFiNTM2MTI5In0sIm4iOnsiTiI6Ii0xIn0sIm5hbWUiOnsiUyI6InRlc3RVbm9yZGVyZWRBY3Rpb25zOCJ9fSx7Im5hbWUiOnsiUyI6InRlc3RVbm9yZGVyZWRBY3Rpb25zNCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3NmFiZTcyMi1lNzhkLTQ1MDYtYTIxNi1lZWIxOTE0ZDg4ZWMifSwicyI6eyJTIjoiNCJ9fSx7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImFkNDE5OTA4LTY5MDQtNGRiNy1iNWE5LWZkZDVkNTA5ZWIwNCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczcifSwicyI6eyJTIjoiNycifX0seyJzIjp7IlMiOiI2JyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI1MDZmZjc0NS01MmIzLTQzZDUtOGUxYi02YTI3ODEyNTkyNDIifSwibiI6eyJOIjoiMSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczYifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M3NGU1OWEtMzM4OC00NzEwLWE4NzItZTllOTQ0MDJmMWVkIn0sInMiOnsiUyI6IjUifX1dLCJTY2FubmVkQ291bnQiOjZ9" + } + }, + { + "ID": "b83abb309496acbe", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM1In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "24O91N9RO9UFKS5TQ46QRA81RVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e6b259b8f8e9b51e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MIG62SP6K4KRL89ELQKAQB5OQ3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7a03cf0e63ce7038", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM4In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "4FJP8J4OS13HHG92R3VUV28BARVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b3b31af9c1518cd8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMzIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "ERQ90T6GK0O7A20BL1O1DQDOKFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ec79c783f050e37d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM3In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "26770OCLQ3UJBAFG6OE8GJE3QFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4e8ef55e1802b5c8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM2In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0J3L6CPMA38UHVADJ3OVCAJ71FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "62065f278fbf44c4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiIzMGViYWQyMy1lZGE5LTQyYjAtODg0Yy00NjA5ZDgzMjgxNGIifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM1In0sInMiOnsiUyI6IjUifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SH8MTALOM88B3Q3S5GV3VOGRA3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1b512653fd1950a6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiIxNmY3NzQ2My00NWI3LTQzNjQtOTI3OC04NjA3NGI3MTU0NWYifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMwIn0sInMiOnsiUyI6IjAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KM08VRTQHC4HDDCO57RMO7MND3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8c20616bc9aa0f41", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiJhYTM3ZDRlZi0zODNhLTQwNzItOGY4My03N2I0NDcxNWZlNzUifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMxIn0sInMiOnsiUyI6IjEifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "D56MK5MRS5MTU350M4UQ8I2B37VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "28d4d5814d5fc7cc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiI5NTAwOWYwZC1kYWRjLTRhNjQtYTYxYS0xYTNiMWNkNWU4YWUifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMyIn0sInMiOnsiUyI6IjIifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6DATE92P8FTQG0BJ0374IP5O0RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4496c84c4dc1f508", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiJmMjU2NWI5Yi03NDY3LTQ3YTYtYTkyMi1kMjNiZDhmMjE1ZDEifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMzIn0sInMiOnsiUyI6IjMifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PSMV4CBVK4B9U194HIMGTAI5E7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "29446139fe89322e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiJhNDQwNWJkZi0wY2MxLTQ1OGUtYjdiYi03YTgzOGU3ZTIyOGQifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM0In0sInMiOnsiUyI6IjQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GH50CBONID36EKVV733BP06A77VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "49c90533795061c2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "297" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYWEzN2Q0ZWYtMzgzYS00MDcyLThmODMtNzdiNDQ3MTVmZTc1In19LCJJdGVtIjp7IkV0YWciOnsiUyI6IjQ1NzllMjZlLWIwZWMtNDY5OS05M2MxLTQzYjE5NjYyMTc0NCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczEifSwicyI6eyJTIjoiMScifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KOH9QL54JRGE58F5VD5KTNU7C3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "734b65f9793bb76a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "143" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6ImRlMDI1MTQ5LTliMmQtNGRhZS05NjZlLTU1Y2IwYzYyOGNjYyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczgifSwicyI6eyJTIjoiOCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6FRQG5O23KU8TQENF6LN9B9O5VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "85821ceac7e648f5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "297" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOTUwMDlmMGQtZGFkYy00YTY0LWE2MWEtMWEzYjFjZDVlOGFlIn19LCJJdGVtIjp7IkV0YWciOnsiUyI6ImY3MmE0OTBlLTUwZjUtNDUyNi04ODRjLTlkNjVhZWQ5NzQ1YiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczIifSwicyI6eyJTIjoiMicifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "093J7SRHEABV2FKHBCPLFD94IVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fefbed2cbfd351d3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "143" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6IjFlMWI5MzcwLTgxNzYtNDEwMi1iZjk5LTczZjc0ODE1YjViMCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczcifSwicyI6eyJTIjoiNyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FIQ6HLFKL5FRTD234OBOS40GOJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7440b678594b9d72", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "296" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMzBlYmFkMjMtZWRhOS00MmIwLTg4NGMtNDYwOWQ4MzI4MTRiIn19LCJJdGVtIjp7IkV0YWciOnsiUyI6IjY0YjUzMDViLTIzMzMtNDZiNC1hODFjLWQ0MWZiMzY2ZmY4ZCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifSwicyI6eyJTIjoiNSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "10IBN59BGAH419VK4JJ8PGRL1NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1d0f8eaccbb10de1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "297" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMTZmNzc0NjMtNDViNy00MzY0LTkyNzgtODYwNzRiNzE1NDVmIn19LCJJdGVtIjp7IkV0YWciOnsiUyI6IjQ3Y2FlZDBkLWNmNzMtNDUwMS04OTIwLWJhNzY3OTk0ZGEwNCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczAifSwicyI6eyJTIjoiMCcifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "C0PPLT1O4CSCME2QRAJF2R60MNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "994734702172e48d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "143" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6IjYzNjc3M2UxLWIxNTMtNGVjNC1hMzk4LTllMmE0YTQ1ZDc2OSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczYifSwicyI6eyJTIjoiNiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "ROQEGF548VS36KTF9C9UQMI8KNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f7873f9ce41e6127", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "296" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZjI1NjViOWItNzQ2Ny00N2E2LWE5MjItZDIzYmQ4ZjIxNWQxIn19LCJJdGVtIjp7IkV0YWciOnsiUyI6ImIxMGZiODBkLTAxZGEtNDM1ZS04ZDAxLTdiZGRjYzZhMWI1YiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifSwicyI6eyJTIjoiMyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SQ1JQSDSLAGP62RS5DAD6AQK6JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9890bf95710f98a1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "296" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYTQ0MDViZGYtMGNjMS00NThlLWI3YmItN2E4MzhlN2UyMjhkIn19LCJJdGVtIjp7IkV0YWciOnsiUyI6IjQ0ODRmYmM5LTEzYzMtNDQ0Ni1hNzg2LWFkMWU5NWYzZGM5MSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczQifSwicyI6eyJTIjoiNCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VJIJ7DQJAIPKP3U384UD44RC1VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "34beea5bbacb6452", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "186" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczQifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "371" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "872246973" + ], + "X-Amzn-Requestid": [ + "HV2RFHOLPRBTROASN544K2CD9RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiJiMTBmYjgwZC0wMWRhLTQzNWUtOGQwMS03YmRkY2M2YTFiNWIifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMzIn0sInMiOnsiUyI6IjMifX0seyJFdGFnIjp7IlMiOiI0NDg0ZmJjOS0xM2MzLTQ0NDYtYTc4Ni1hZDFlOTVmM2RjOTEifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM0In0sInMiOnsiUyI6IjQifX0seyJFdGFnIjp7IlMiOiI2NGI1MzA1Yi0yMzMzLTQ2YjQtYTgxYy1kNDFmYjM2NmZmOGQifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM1In0sInMiOnsiUyI6IjUifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "8bc2fb3456980bff", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "350" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWciLCIjMSI6Im4ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZGUwMjUxNDktOWIyZC00ZGFlLTk2NmUtNTVjYjBjNjI4Y2NjIn0sIjoxIjp7Ik4iOiItMSJ9LCI6MiI6eyJTIjoiOWI3MWQ5MTctYzM1Zi00MjViLWEzYmItMGM5OGVlNDYzODM5In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM4In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiQUREICMxIDoxXG5TRVQgIzAgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QIF748QN5J2BMANPMM1KTD56PFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "43d746373eeebe79", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "229" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNDdjYWVkMGQtY2Y3My00NTAxLTg5MjAtYmE3Njc5OTRkYTA0In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6IAQ4MFS51PP0AHFUH3APIJ2IRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "04f72f53bc87d479", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "229" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNDU3OWUyNmUtYjBlYy00Njk5LTkzYzEtNDNiMTk2NjIxNzQ0In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMxIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6RR4KPCB1E4S6125DM2M68JJMNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a0fcbbce7da8f8ab", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "229" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZjcyYTQ5MGUtNTBmNS00NTI2LTg4NGMtOWQ2NWFlZDk3NDViIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMyIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V1MG3LTG9APHPU5TGRH0HEKFI7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8f15596574d82af9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "348" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWciLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMWUxYjkzNzAtODE3Ni00MTAyLWJmOTktNzNmNzQ4MTViNWIwIn0sIjoxIjp7IlMiOiI3JyJ9LCI6MiI6eyJTIjoiMDkzMzY3ZjItNzg2NC00ZTQ1LWJiYWUtY2EyMWQwNGMyZTlkIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM3In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiU0VUICMxID0gOjEsICMwID0gOjJcbiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "2JDU0VABBU2VQDAABI8CEHKJG7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1be62e9960644f18", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "383" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWciLCIjMSI6Im4iLCIjMiI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNjM2NzczZTEtYjE1My00ZWM0LWEzOTgtOWUyYTRhNDVkNzY5In0sIjoxIjp7Ik4iOiIxIn0sIjoyIjp7IlMiOiI2JyJ9LCI6MyI6eyJTIjoiNTcwNzNkYWYtZjU4Zi00ODRlLWI1ZDUtMzhjNjY2ZGU4N2NjIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM2In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiQUREICMxIDoxXG5TRVQgIzIgPSA6MiwgIzAgPSA6M1xuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VFP5FR6IUOIP2KEUI0PIJS55EVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9a5fbaf753b77828", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "108" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczAifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "558779IENF176794HFIJ1MP2O7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "ff314b68e4c99dad", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "186" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczEifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczIifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "161" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "620125902" + ], + "X-Amzn-Requestid": [ + "NQ50RSQ1B2AQ7VU1QS69LRQ9HBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiJiMTBmYjgwZC0wMWRhLTQzNWUtOGQwMS03YmRkY2M2YTFiNWIifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMzIn0sInMiOnsiUyI6IjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "5792a9c1c0530961", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJFdGFnIjp7IlMiOiIzYjUzYjQwOC1kMWFiLTQwZTAtYTI2NS01ZDlmNjQyMWM2MGEifSwibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnM0In0sInMiOnsiUyI6IjQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "JC3H2RT7M6MR4QKBAD24G519GRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "1bab81c4eac3cd58", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "296" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNjRiNTMwNWItMjMzMy00NmI0LWE4MWMtZDQxZmIzNjZmZjhkIn19LCJJdGVtIjp7IkV0YWciOnsiUyI6IjlmMjUwMzY4LTU4ZTctNGMxYi1iOWU4LWU0ZTJhNTIzYjQwYyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifSwicyI6eyJTIjoiNSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PGTMT26Q33N7QEJS6N0S2TNTOFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8053eeb4c285df34", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVub3JkZXJlZEFjdGlvbnMwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VKT353TK86O9TP9GJB39IHBJ3NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Proto.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Proto.replay new file mode 100644 index 000000000..1594e698b --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Proto.replay @@ -0,0 +1,319 @@ +{ + "Initial": "AQAAAA7gDLPBH/U65wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "3b4defbb5447c82c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "J2KV92ERMAM9SEAEBGM6J86VD3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "9cf63c3ecad4ebf1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "83" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1006067942" + ], + "X-Amzn-Requestid": [ + "FDIU62H34KQ1K1JH9BL5UEMK9NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJCIjoiQUFFQyJ9fV0sIlNjYW5uZWRDb3VudCI6MX0=" + } + }, + { + "ID": "175f6a3809cdce7f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "63" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERhdGEifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "59JL0I6UUF3N9AVID6UM2FHGA7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3998fe259b99a519", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "265" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmMzZlOGE4Yi03ZDAzLTRmNzAtYmYyZC04OWMzMDljMmQwM2EifSwiUHJvdG8iOnsiQiI6IkNDbz0ifSwiUHRyVG9Qcm90byI6eyJCIjoiQ0NzPSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0aW5nIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6OKD47M5JO2S92JQDFG2M18AQRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "57408965e08cc2ff", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "174" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "115259572" + ], + "X-Amzn-Requestid": [ + "6CRN279EPH13CGAJHEJSM65CBVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IlB0clRvUHJvdG8iOnsiQiI6IkNDcz0ifSwibmFtZSI6eyJTIjoidGVzdGluZyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmMzZlOGE4Yi03ZDAzLTRmNzAtYmYyZC04OWMzMDljMmQwM2EifSwiUHJvdG8iOnsiQiI6IkNDbz0ifX1dLCJTY2FubmVkQ291bnQiOjF9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Put.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Put.replay new file mode 100644 index 000000000..ed7b0b8b6 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Put.replay @@ -0,0 +1,2739 @@ +{ + "Initial": "AQAAAA7gDLOyGL8yBgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "32dc8a20f13f3f1c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "LTEHC3Q27F9J8P6UCR5VA04I07VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "6160ac2fb5c73cf5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "543" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3061206667" + ], + "X-Amzn-Requestid": [ + "PV1SVF53Q72K52VC88HGFVO063VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7IkV0YWciOnsiUyI6IjFkMjgzYWQ0LWZkYTktNDRmYi1iN2JiLTE1NWMxMjdmN2I5ZCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9LCJzIjp7IlMiOiI3In19LHsiRXRhZyI6eyJTIjoiMzVmNWY5NjgtMzFmYy00Njk3LWExMzgtYjI3OWI2MGU4OTgxIn0sIm5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In0sInMiOnsiUyI6IjQifX0seyJFdGFnIjp7IlMiOiJhMDQ2YjllNi1jNjEyLTRkNmMtYTE5ZS1hZDBmMWI3OGQyODcifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwicyI6eyJTIjoiNSJ9fSx7IkV0YWciOnsiUyI6IjU5YzNkMjQyLThhZDgtNDZmMi1iZThhLTVmMzY0Yzc5ODk1NCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9LCJzIjp7IlMiOiIzIn19LHsiRXRhZyI6eyJTIjoiNmM0ZDA1MTItNDQyZi00MTViLWIwODUtOWM0ZDE4NjNhMGM3In0sIm5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM2In0sInMiOnsiUyI6IjYifX1dLCJTY2FubmVkQ291bnQiOjV9" + } + }, + { + "ID": "8849e825ad1c436a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QOHUSN4N4R1UM1BGQIANAOG6VRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "578a1115fb6e42ee", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "EF9AV910RMD5QTHV4K7O42VJHRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3bbd66c0c6bf0381", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HENJPI91JO2K27HBKPSUP305GVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4dfa169a1f8d1ef4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JETB2M2HD7E1OMMSKLQR4P7EU3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "747fbb638e7c878a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "2TQ92HD2B7B7P13ELQ5OG4S9FBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c96feb5e890d79be", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "148" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjkxNTEwYjJlLWExOTAtNGFjZi04NjljLTk1MDlhZGJjZTNhYSJ9LCJiIjp7IkJPT0wiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LOCBH087MIAKQ4E277D1M1O60RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2b3acb64dc565444", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "166" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4187329478" + ], + "X-Amzn-Requestid": [ + "B3SF45S5U6AOVA16VHQUKDHHSVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjkxNTEwYjJlLWExOTAtNGFjZi04NjljLTk1MDlhZGJjZTNhYSJ9LCJiIjp7IkJPT0wiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "0cc586a408210aef", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImE3NGY3ZjlhLWYwMTItNGFlZS05OGQ4LTQ5MzgzNGYzY2RkZSJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiTSI6eyJOVUxMIjp0cnVlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFB1dFN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FB4AMSNCMLK710UDU1E717M9S7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fa521e04da804968", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0U3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "269" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2741838452" + ], + "X-Amzn-Requestid": [ + "0OAED8GP2SLC3TN2KUATG7PK7VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFB1dFN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhNzRmN2Y5YS1mMDEyLTRhZWUtOThkOC00OTM4MzRmM2NkZGUifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "6af6dd0593c3fa60", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "149" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijc3NWJmNGJhLTRiZmYtNGM4ZS05Y2VjLWI3YjFjNGJjZDgyMyJ9LCJiIjp7IkJPT0wiOmZhbHNlfSwibmFtZSI6eyJTIjoidGVzdFB1dE1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CJRP4V4KV52M2PKE4ANHUK9OUFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "675628c9b2e53b52", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "167" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3127654589" + ], + "X-Amzn-Requestid": [ + "CP2OBQ21GD2LET7M58GILT0ROVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijc3NWJmNGJhLTRiZmYtNGM4ZS05Y2VjLWI3YjFjNGJjZDgyMyJ9LCJiIjp7IkJPT0wiOmZhbHNlfX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "71e59b513f39a641", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhMmNiMTVmNy0wNGNhLTQxMWQtYTIwOS02ZjNlNzM0NmVjZjIifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RQdXRTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6T26B9I96469N2LSNAU8I64LTFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "39ae91bd962d3166", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0U3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "270" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1982965030" + ], + "X-Amzn-Requestid": [ + "T4LUJOBELHEDFOQDKET7AV7LDJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RQdXRTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYTJjYjE1ZjctMDRjYS00MTFkLWEyMDktNmYzZTczNDZlY2YyIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "5f891b74870c4ce8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "296" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNzc1YmY0YmEtNGJmZi00YzhlLTljZWMtYjdiMWM0YmNkODIzIn19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImNiNzlhMzMwLWY4ZDQtNDk1MS04ZWExLTA0YjdhODIwNWQyMyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwMiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "VLCVLL9T5G9UDUPD29CQO4N0A3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "dcc0916ac40d6682", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "449" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYTJjYjE1ZjctMDRjYS00MTFkLWEyMDktNmYzZTczNDZlY2YyIn19LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiOTgxYmFkOC0zMmViLTRjMjMtOTZmZS00NWE4YzUyOGU1YjEifSwiRXRhZyI6eyJTIjoiYTJjYjE1ZjctMDRjYS00MTFkLWEyMDktNmYzZTczNDZlY2YyIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0U3RydWN0MiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "8MN2V2PCO18RMULF4EQ2FUGA23VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "9e12f7c3c65d85be", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "149" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjZhYTUyOGJiLWZhZGEtNDg3ZS1iMDE0LTBiODJiMzY5MzBiYiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8AMEK0FQ5RCGRTISHS7D3GE6VBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e6cea4019ea3b17a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "167" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "223201936" + ], + "X-Amzn-Requestid": [ + "LH33GJI11EAJHA2LBBFCTKK75FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNmFhNTI4YmItZmFkYS00ODdlLWIwMTQtMGI4MmIzNjkzMGJiIn0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "628d748d3a89be8d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "314" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNmFhNTI4YmItZmFkYS00ODdlLWIwMTQtMGI4MmIzNjkzMGJiIn19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImMwNWM1NDI1LWMzNzMtNDYxMS04MjliLTI4NDVhNzJlMTYxOSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3SHDAJVDE7LV83TUMM51O4TRVJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "887d2174880432cf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "314" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNmFhNTI4YmItZmFkYS00ODdlLWIwMTQtMGI4MmIzNjkzMGJiIn19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImQ3ZDNiYzczLWE2YTktNDU4OC05MzFjLThhMWZjMjc4Y2FjZiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "SO9HCSBBFC0C6542IIEGHOHBM3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "832ce65a3294bf87", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJjM2U5NDc5Yi0wNDcwLTRhMTEtOTg0Yy1iYTNjZTBmMWNkNTAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MVQ78504FS9QVDPQUNTG30GCT7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "86775c440aa0d5e2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1735439765" + ], + "X-Amzn-Requestid": [ + "GIUPSHBFI7JCE99BPLMU7DGO9NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImMzZTk0NzliLTA0NzAtNGExMS05ODRjLWJhM2NlMGYxY2Q1MCJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "a7f7cbcb1cef3b51", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "418" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYzNlOTQ3OWItMDQ3MC00YTExLTk4NGMtYmEzY2UwZjFjZDUwIn19LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIwZTlhOWJlMC00OTIwLTQxYjgtYmE1My0zYWU3YjgwZjU3ODQifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8SI46MB33NG4V41TKCOKGJG3BRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4f636e6c86728719", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "418" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiYzNlOTQ3OWItMDQ3MC00YTExLTk4NGMtYmEzY2UwZjFjZDUwIn19LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI1OGI2YTkxOC1mZmEwLTRhMjItYjk2OS01NTQxY2Y1YjM3Y2QifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "CBBIVPFSMV8O3S1OL2GGLIU0KFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "d749b1d6267d4787", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "RJ6K2NBAI4E1P3U5KVR5BT66SBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "09b8cffa198d5fcd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "689" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2033327916" + ], + "X-Amzn-Requestid": [ + "34IAGAV4P5E0AR1KRO7876ATVJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3RSZXZpc2lvbk1hcCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJjMDVjNTQyNS1jMzczLTQ2MTEtODI5Yi0yODQ1YTcyZTE2MTkifSwicyI6eyJTIjoiYSJ9fSx7Im5hbWUiOnsiUyI6InRlc3RQdXRNYXAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNzc1YmY0YmEtNGJmZi00YzhlLTljZWMtYjdiMWM0YmNkODIzIn0sImIiOnsiQk9PTCI6ZmFsc2V9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMGU5YTliZTAtNDkyMC00MWI4LWJhNTMtM2FlN2I4MGY1Nzg0In19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0U3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImEyY2IxNWY3LTA0Y2EtNDExZC1hMjA5LTZmM2U3MzQ2ZWNmMiJ9fV0sIlNjYW5uZWRDb3VudCI6NH0=" + } + }, + { + "ID": "dcc026d5910a0e8a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFB1dFN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UQMCTON3LBAB92LUPDV1GAA3CFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "95fe223a5a35867f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFB1dE1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QO47TOUNO8GH7IOT64F5BS4M2RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "03f12cd1b8d86012", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "L6DIAFKEQNC79EVV3EDR6PMEB3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f9b692df5bda5ceb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "AH6GOBN7EV1N1EGI84BL14SS3VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "11791cf34f47fbde", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "136" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6ImZmZDRiZjEyLTc1NzItNGIwOS1hNjc4LTliYjNjZWZkYTAwMyJ9LCJiIjp7IkJPT0wiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "RJU5ITK2QF6221C0MI24JLL7UFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2d25dbe573b5df29", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "154" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2285172600" + ], + "X-Amzn-Requestid": [ + "QQ0EMNSQMMUDHTPQGC86SFQPPVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiJmZmQ0YmYxMi03NTcyLTRiMDktYTY3OC05YmIzY2VmZGEwMDMifSwibmFtZSI6eyJTIjoidGVzdFB1dE1hcCJ9LCJiIjp7IkJPT0wiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "753870c5fb76aa96", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX0sIkV0YWciOnsiUyI6ImJhNDJjNTEyLTU5NjMtNDg2Zi04ZDgxLTNjZDBiYzMxYzY2MyJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiTSI6eyJOVUxMIjp0cnVlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFB1dFN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "41IKSO0VJT70GVB2RE8CJRFGBJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "501b118e170b9c2d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0U3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "269" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "14483074" + ], + "X-Amzn-Requestid": [ + "708NL7NEMM30J7LOT1F1KONI57VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiYmE0MmM1MTItNTk2My00ODZmLThkODEtM2NkMGJjMzFjNjYzIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RQdXRTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJOVUxMIjp0cnVlfX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "4890eb066f6bb7e5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "137" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6ImY0MzhkNmEzLWZmZmQtNDllNi05ZDIyLTJkNDNhMDA5ZWYzNyJ9LCJiIjp7IkJPT0wiOmZhbHNlfSwibmFtZSI6eyJTIjoidGVzdFB1dE1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5Q5T14LDFRIB27HGML4KVEDVNBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0dc24145d5ab4c63", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "155" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3074282370" + ], + "X-Amzn-Requestid": [ + "FSHGS5J2VND454NHFBLVQKOOL3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiJmNDM4ZDZhMy1mZmZkLTQ5ZTYtOWQyMi0yZDQzYTAwOWVmMzcifSwibmFtZSI6eyJTIjoidGVzdFB1dE1hcCJ9LCJiIjp7IkJPT0wiOmZhbHNlfX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "3fed6a4b657f96e3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiI0OWFkMTZhZS0wOTJhLTQ1NjUtYWRkYi1kMWM4MGE5ZjdiOWYifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RQdXRTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "I2EBF8B98M5MMMVB1GPO5FGO8BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6c82eece8431e865", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0U3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "270" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3560997626" + ], + "X-Amzn-Requestid": [ + "UK67L8K965UFM9JIFLBRTORIDNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiUyI6IjQ5YWQxNmFlLTA5MmEtNDU2NS1hZGRiLWQxYzgwYTlmN2I5ZiJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0U3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "4e1241c78d6d1cf7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "272" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZjQzOGQ2YTMtZmZmZC00OWU2LTlkMjItMmQ0M2EwMDllZjM3In19LCJJdGVtIjp7IkV0YWciOnsiUyI6ImU1ZTI0ZDMzLWQ1MDAtNDZlNi1hZDA4LTU4ODA3OGM2ZGM0MSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwMiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "KITBMOUJP4D64DNPD3R04K4HLJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "921351a45cbf5b20", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "437" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNDlhZDE2YWUtMDkyYS00NTY1LWFkZGItZDFjODBhOWY3YjlmIn19LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI0OWFkMTZhZS0wOTJhLTQ1NjUtYWRkYi1kMWM4MGE5ZjdiOWYifSwiRXRhZyI6eyJTIjoiYjk0M2IxOWUtM2M5MS00ZjAxLTljZGQtOWUzMjJhMTAxNjI0In0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0U3RydWN0MiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "Q833QHSJDVEK7TTECB78P1HTDBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "6647330d051ce1c3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "137" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6Ijk0ZTUyNDBiLWVmMDgtNGIwNC05NzAxLWMyYjcxZGFhZTIxNSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "207A4HD14278URDNMAFTA3B6MRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "01abc2ce506b02fc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "155" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "664299842" + ], + "X-Amzn-Requestid": [ + "OGDNE431I1NBRFUSIHU0UU7E8BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI5NGU1MjQwYi1lZjA4LTRiMDQtOTcwMS1jMmI3MWRhYWUyMTUifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "b92beca6e70b7d4e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "290" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOTRlNTI0MGItZWYwOC00YjA0LTk3MDEtYzJiNzFkYWFlMjE1In19LCJJdGVtIjp7IkV0YWciOnsiUyI6IjQ0NzNiNzNjLTczNWItNDI1OS1iN2NjLTE4NjQ5MzkyY2IzYSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HIE5AFLU0DH8BB59DFRM0JKS0NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8bd1fb10ab176596", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "290" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOTRlNTI0MGItZWYwOC00YjA0LTk3MDEtYzJiNzFkYWFlMjE1In19LCJJdGVtIjp7IkV0YWciOnsiUyI6IjhhODA0NTYyLWYzNjAtNDhkOS1hZTNlLWY0YzUxZGZmZDYyMyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "HO69IIOJH3JQU76DLE3BMTS5A3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "8cb33c7748d66087", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiIyMzk4YWIwZS0wYmJkLTQwNzctODhhNS1lYjc4ZmJmNWViNzAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "AE2GDVU5GFG15ROE4N1VCL0V5VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "11fbd19b3862dc2a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1720535685" + ], + "X-Amzn-Requestid": [ + "KM5SV7VJTVSGNNB83BQ7TETB1JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiMjM5OGFiMGUtMGJiZC00MDc3LTg4YTUtZWI3OGZiZjVlYjcwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvblN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "9105b199cd849ddb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "406" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMjM5OGFiMGUtMGJiZC00MDc3LTg4YTUtZWI3OGZiZjVlYjcwIn19LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiI5MDNiY2MxNC01Njg4LTQ5OGItOTE4Ni0xNDMyMGE5OWIxZWYifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CV38IK6F9E3452RJIT6FK60U1NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5d8baa91f41c4dc7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "406" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMjM5OGFiMGUtMGJiZC00MDc3LTg4YTUtZWI3OGZiZjVlYjcwIn19LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiIzOGM3ZTY4Yy1kZmM0LTQ0NjgtOTAwOC1lMzYyMGE5MGU4M2UifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "14HDA7CK1NCJJ8K7CB325RVRL3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Replace.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Replace.replay new file mode 100644 index 000000000..1951a225a --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Replace.replay @@ -0,0 +1,2354 @@ +{ + "Initial": "AQAAAA7gDLO1DF1SRQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "f0178c302bc7e0f4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "GHVI226FFIGKLT0DE27RKRGJTFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "b4c26bd0594e5bf0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "665" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4249982765" + ], + "X-Amzn-Requestid": [ + "AUBV27MV2NDB0J4ORNKAAHD12NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7IkV0YWciOnsiUyI6IjQ0NzNiNzNjLTczNWItNDI1OS1iN2NjLTE4NjQ5MzkyY2IzYSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSx7IkV0YWciOnsiUyI6ImY0MzhkNmEzLWZmZmQtNDllNi05ZDIyLTJkNDNhMDA5ZWYzNyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn0sImIiOnsiQk9PTCI6ZmFsc2V9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiI5MDNiY2MxNC01Njg4LTQ5OGItOTE4Ni0xNDMyMGE5OWIxZWYifSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiI0OWFkMTZhZS0wOTJhLTQ1NjUtYWRkYi1kMWM4MGE5ZjdiOWYifSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFB1dFN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV0sIlNjYW5uZWRDb3VudCI6NH0=" + } + }, + { + "ID": "06a885ce3e657da8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFB1dFN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PC61KV1MVAAC5IGK6PVKDPGLMFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9b7706496eb5b780", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "I4M3FGGPB1DALB24O1PNAOVMAFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1ce4661012d5dc9c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFB1dE1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "O5J8KSM07F2TA2K5U80Q0J8K17VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d79da625aa18603f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CQD55T8N3G1BEVNLPLFV5MHDMBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6029a0d1d5f41dad", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "148" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImUwNWIzZGZiLWNmYTctNDQ4Yi1iMTkxLWU4ZjA1ODE0Y2VlMyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZU1hcCJ9LCJzIjp7IlMiOiJhIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "37GANVHG39G1KD50DVGQGMO9URVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5ecce9b11140cd12", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "235" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSJ9LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijc4OWJmMDFiLWMyY2QtNDAxOC04MGQ1LTJhYzA2NDM3ZjUzMyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZU1hcCJ9LCJzIjp7IlMiOiJiIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "BL6TL4D1GHC9KVMHCP97JP16RBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cc6e93ba54c77f47", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "101" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZU1hcCJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "166" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "876626440" + ], + "X-Amzn-Requestid": [ + "7T6J5HCAPIC8H7LFPHGVPLSDC3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZU1hcCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ODliZjAxYi1jMmNkLTQwMTgtODBkNS0yYWMwNjQzN2Y1MzMifSwicyI6eyJTIjoiYiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "4fafe897404c1de7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZTAwNTMwMS01ZmQ2LTRiOWEtODczMy00NTE1NGZlNzA1OWYifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "10S9Q4SFIJ23JAF7A2IGVA91GJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "03a2ee4645eb86cf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "339" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSJ9LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiNzE1Mjc2Yi0zZDk2LTQ5NWEtODhhMC1lNDNiZmI5MTFiYTYifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJiIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3UJG4BVD3L08GCVNJAIDSM7VHRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f6676cfe55372ab6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZVN0cnVjdCJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "270" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2455076689" + ], + "X-Amzn-Requestid": [ + "JIBBD14RVQ91G2E4FJDB8O68QJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImIifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYjcxNTI3NmItM2Q5Ni00OTVhLTg4YTAtZTQzYmZiOTExYmE2In19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "849a46e9d0c57731", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSJ9LCJJdGVtIjp7Im5hbWUiOnsiUyI6ImRvZXNOb3RFeGlzdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "7HRLR7AK5J0GE5MTLJFC0GVF37VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "d4264357a304229b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "149" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImUyOGM3MDUwLTEwNjctNDY1Yy05YWE3LWZmYmViMWY1ZjIxNCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HP34SMSD2MPQUV2LU71126FCOBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3410619dff4aea39", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "167" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2814536464" + ], + "X-Amzn-Requestid": [ + "RFTC5RMCL9VGAISM7TFUNHDE73VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZTI4YzcwNTAtMTA2Ny00NjVjLTlhYTctZmZiZWIxZjVmMjE0In0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "c7923f2b12fc1fe8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "314" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZTI4YzcwNTAtMTA2Ny00NjVjLTlhYTctZmZiZWIxZjVmMjE0In19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImQwMTQ0YTYyLWQ1NTEtNDk1Yy1hMTIwLTY4ZmY5ZDUyNDBiYyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "T9H71H20FB128OOD66PLEIBMV3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1d0ce6a4b3ce055e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "314" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZTI4YzcwNTAtMTA2Ny00NjVjLTlhYTctZmZiZWIxZjVmMjE0In19LCJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImI3MjZhMTAzLTk0MjAtNDQyNi1iMjcyLTA0Y2NkMGMyMjhlZiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "FQVGM1DESP8G841OBI2L99NH3JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "099bd321f44e60aa", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI5Y2FjZjVkOC03NjY4LTRmYmMtOGFmZS1jMTE0YWY2MzA5MTkifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "O2VV432684ITVKG71PC4CFEU7VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8df7373cd5135a38", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1666143977" + ], + "X-Amzn-Requestid": [ + "B0H1IPLAT7CAVAC23M0AQAHPUBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjljYWNmNWQ4LTc2NjgtNGZiYy04YWZlLWMxMTRhZjYzMDkxOSJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "c7ed9fe0c78ed7ae", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "418" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOWNhY2Y1ZDgtNzY2OC00ZmJjLThhZmUtYzExNGFmNjMwOTE5In19LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJkYWE5NzhiNy00MWYzLTQ0MTctOWFmNy01MzU5MTZhNDkyOTkifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UB7IE6GJNTKTBLIRR6IGRMH49BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0a3929146e926c7c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "418" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOWNhY2Y1ZDgtNzY2OC00ZmJjLThhZmUtYzExNGFmNjMwOTE5In19LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJhZjBiMTEwYy00ZWM3LTQwNGUtOGY4YS1kZWIxZWY0ZWRjNDkifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "KJGBNVD99JMHGBBHT7PGL0CA03VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "bef6273a02705617", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "LB4TNU360HFMDLF0NLS65COAI3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "83ac6474499dedb3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "688" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "417417255" + ], + "X-Amzn-Requestid": [ + "H5KPB21RSLNHREOJPJI56BOAVNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3RSZXBsYWNlTWFwIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijc4OWJmMDFiLWMyY2QtNDAxOC04MGQ1LTJhYzA2NDM3ZjUzMyJ9LCJzIjp7IlMiOiJiIn19LHsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImQwMTQ0YTYyLWQ1NTEtNDk1Yy1hMTIwLTY4ZmY5ZDUyNDBiYyJ9LCJzIjp7IlMiOiJhIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJiIn0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RSZXBsYWNlU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImI3MTUyNzZiLTNkOTYtNDk1YS04OGEwLWU0M2JmYjkxMWJhNiJ9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZGFhOTc4YjctNDFmMy00NDE3LTlhZjctNTM1OTE2YTQ5Mjk5In19XSwiU2Nhbm5lZENvdW50Ijo0fQ==" + } + }, + { + "ID": "58fc40de23bc14ee", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8JCC99S41HD87GFB2EV8ICMKS7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c71e3ee57369cfa7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VNYXAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "65HQDDEET1CVSG48MB7EIF5B97VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1e15550c923cfb7c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MP1RSUOLLFUQLOQQMH9R43S93FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "965cc54e93a1d7a1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "L5TEAGU9N0446NNR5Q61NNUC2JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cbb2b94ec2805791", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "136" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6ImY2NjExMTIwLWY3NzctNDJkNC05YjA3LWViMjBkZjI5OWM2NSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZU1hcCJ9LCJzIjp7IlMiOiJhIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V094GBD3IFTUFQBV0L4EPLCT3BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bf6148bbade04636", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "223" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSJ9LCJJdGVtIjp7IkV0YWciOnsiUyI6IjkxYjJkOTMzLTM4NGEtNDlhNy04NGVhLTMzZmYzZWVhMzQ4OCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZU1hcCJ9LCJzIjp7IlMiOiJiIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CJC81M9ERAEPMG5FHI8B74OM0JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b908d04fe99248d4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "101" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZU1hcCJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "154" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1177511180" + ], + "X-Amzn-Requestid": [ + "F2G1JVI994RIAT4UHE1UUCPQG7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI5MWIyZDkzMy0zODRhLTQ5YTctODRlYS0zM2ZmM2VlYTM0ODgifSwibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VNYXAifSwicyI6eyJTIjoiYiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "4525b6010cf1ed51", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiI5ODUwNTQ4MC01OGYzLTRmYTQtYmEzOS0yMzdjMzAzMmQ0MmMifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "N8AG8FA4QRBCU2CJEIUG7RUKQFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2e53a375fce9964f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "339" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSJ9LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiI1NDY5MGRlMS0yZWVhLTQ4YjMtYjk4My04Y2IyMDgyNTQxOWQifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJiIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VTdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "T78GJ155QH4TEHQKTGEO0C0G8JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b453805a7a7e097b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZVN0cnVjdCJ9fV19fX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "270" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2722312635" + ], + "X-Amzn-Requestid": [ + "INVD60O201C6SC605BN195OJJ7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImIifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiNTQ2OTBkZTEtMmVlYS00OGIzLWI5ODMtOGNiMjA4MjU0MTlkIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RSZXBsYWNlU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "32aaa41efd6dd947", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSJ9LCJJdGVtIjp7Im5hbWUiOnsiUyI6ImRvZXNOb3RFeGlzdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "QT7APRSRAH42KATR1JRB552IFNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "541e7a008d80ee55", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "137" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6IjljMzcxMjMxLTU1ZWItNGUyYy04ZTUyLTQ3MjY5YmE2NWM3MiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HIQQMUPJVV16CNRNL4593QG1S7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7bd0bb2a9a274458", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "155" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "539827604" + ], + "X-Amzn-Requestid": [ + "ECGS5PU65QRQRDAH0PEBO4FFV7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI5YzM3MTIzMS01NWViLTRlMmMtOGU1Mi00NzI2OWJhNjVjNzIifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "022e206732de087f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "290" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOWMzNzEyMzEtNTVlYi00ZTJjLThlNTItNDcyNjliYTY1YzcyIn19LCJJdGVtIjp7IkV0YWciOnsiUyI6ImU2NTJmZmU2LTQ2MjktNGY2Yy1hMGRkLTU2ODY4YjY5MjdiNCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V9PTHIVSCDGB4ETVNT8HTMK30JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "84c7abeb2ce90148", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "290" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOWMzNzEyMzEtNTVlYi00ZTJjLThlNTItNDcyNjliYTY1YzcyIn19LCJJdGVtIjp7IkV0YWciOnsiUyI6ImIyMGZjYjk3LTlmYTEtNDUwMS1hZTdiLWY2YmJjNmZhODk2MCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "0KVMM529MCUDT9AQHQ3ORD7C13VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "172d6a6669415d91", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiI5OWEwNGJlYi04MjA3LTQzNzgtYTYyZC1lZjAwM2M5ZWJiZTkifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TJTCSOUTSL4D13G6CV3IEMLL53VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "28244a5eff759068", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3131024219" + ], + "X-Amzn-Requestid": [ + "NOE4NOD304L4NH9OP5K5LR779NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiOTlhMDRiZWItODIwNy00Mzc4LWE2MmQtZWYwMDNjOWViYmU5In0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvblN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "7fa3b3be5c6a0d4d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "406" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOTlhMDRiZWItODIwNy00Mzc4LWE2MmQtZWYwMDNjOWViYmU5In19LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiJjODE3MGM3Mi1mYjcwLTRhNDctYTMxMS1lZmE2YmVkNTYxYjkifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "R91ORO3E67Q261P7K0A4SJBRIVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "29d99f3ecde911a0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "406" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiOTlhMDRiZWItODIwNy00Mzc4LWE2MmQtZWYwMDNjOWViYmU5In19LCJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiIxZjViN2UyZS0wOGUyLTQ5ZWEtYjU0MS04YTVmYzJiODM5YzUifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "HKJGMBTGP3ACE3NCNO0GDBQ53VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/SerializeRevision.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/SerializeRevision.replay new file mode 100644 index 000000000..f2ce97064 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/SerializeRevision.replay @@ -0,0 +1,374 @@ +{ + "Initial": "AQAAAA7gDLPFH0zh4wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "bf91c91867804359", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "8935U6G06F6B648GCG6I4PRLM7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "4fca52af000351b6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "310" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3738458997" + ], + "X-Amzn-Requestid": [ + "AFF8J3KM010MDI6QHUOR1P3927VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJFdGFnIjp7IlMiOiI5MTQ2YTk0ZC01OGY3LTQwNjMtYjgyOC01YWQzMGU5NGZjN2YifSwibmFtZSI6eyJTIjoicWtmMSJ9fSx7ImEiOnsiUyI6InRocmVlIn0sIkV0YWciOnsiUyI6ImNlNzlkMzcyLTVmYmUtNDU1ZC1hMDYyLTgzN2QyYjU2M2U5OCJ9LCJuYW1lIjp7IlMiOiJxa2YzIn19LHsiYSI6eyJTIjoidHdvIn0sIkV0YWciOnsiUyI6ImVhNWMxNGIwLTQzNDgtNGY5ZC1hYzg1LTM1MDI3NGUwYmI3NCJ9LCJuYW1lIjp7IlMiOiJxa2YyIn19XSwiU2Nhbm5lZENvdW50IjozfQ==" + } + }, + { + "ID": "9927e6daa0c27797", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoicWtmMiJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "IUP0G47BO9BMONLFB5A5QK6L7BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2b51cbb6bc5e1b88", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoicWtmMSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5CPVHKRB99M99VR55GMQ55M3LFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ef11ec85596a24f3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoicWtmMyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "B7C2S9BIRT3DSVMA50E5NRU9BVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e4c6dfe0d7d64d77", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX25vdF9leGlzdHMgKCMwKSIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6Im5hbWUifSwiSXRlbSI6eyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmMDc2MjMxNC04MjM1LTQ3MDYtYmY3Ny0zOGU3MWU5NWZhMDMifSwibmFtZSI6eyJTIjoidGVzdFNlcmlhbGl6ZVJldmlzaW9uIn0sIngiOnsiTiI6IjEifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DQRMJP8ORT8BDFAOFAIP1V5LMVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Update.replay b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Update.replay new file mode 100644 index 000000000..0aa028dac --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestConformance/Update.replay @@ -0,0 +1,3784 @@ +{ + "Initial": "AQAAAA7gDLO7JLOJPgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "f853ec743d0fe001", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "71MR55M6HCHKRFT5L4ND56TPHJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "adcbfe345d809881", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "355" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3090212510" + ], + "X-Amzn-Requestid": [ + "0NVG92GBA53S5R7RUTCHHK2TNVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7IkV0YWciOnsiUyI6IjcxODZiZWYwLTM2ZDQtNDcxZS1hYmUxLWJiNTI3MzJhZDVlMiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0RGVsZXRlTWFwIn0sImIiOnsiQk9PTCI6dHJ1ZX19LHsiQiI6eyJCT09MIjp0cnVlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiUyI6ImUyNWZiYzViLTU1YWMtNGQxNy1hMTc1LTc3M2FlMDhhNzNiZSJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0RGVsZXRlU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19XSwiU2Nhbm5lZENvdW50IjoyfQ==" + } + }, + { + "ID": "c278858bac85123c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OR9Q3TFRQ7BT22K7JRT5DS1C0VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c9ad69095d8c0b5d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdERlbGV0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "01IAUEA2STM32RGEQ7S9CTPSQVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "32f42c5fa0850b6b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "191" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImZhMzg5MzRiLTk4NmQtNDIyOS1iNTRiLWM1ODg3OGI4ZGJiOCJ9LCJhIjp7IlMiOiJBIn0sImIiOnsiUyI6IkIifSwiaSI6eyJOIjoiMSJ9LCJuIjp7Ik4iOiIzLjUifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "A1ENOETE272T8N1F59AAAGP9NVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3c7b8d11449f5ae7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "462" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoibiIsIiMyIjoiYiIsIiMzIjoiaSIsIiM0IjoiYSIsIiM1IjoiYyIsIiM2IjoibSIsIiM3IjoiRG9jc3RvcmVSZXZpc2lvbiJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7Ik4iOiItMSJ9LCI6MSI6eyJTIjoiWCJ9LCI6MiI6eyJTIjoiQyJ9LCI6MyI6eyJOIjoiMyJ9LCI6NCI6eyJTIjoiMmE2YjYwMzQtYmNkNC00YjNkLTk3MGYtYWYyMzhiYTE2YzQyIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIiwiVXBkYXRlRXhwcmVzc2lvbiI6IkFERCAjMSA6MFxuUkVNT1ZFICMyLCAjM1xuU0VUICM0ID0gOjEsICM1ID0gOjIsICM2ID0gOjMsICM3ID0gOjRcbiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "S39MOD3BJ1PD3V5OHHSCSJ6UQNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5d17848cf4a53769", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "209" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2329015532" + ], + "X-Amzn-Requestid": [ + "VU26J0SV5KJIAUP85AUGSM15FBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJYIn0sImMiOnsiUyI6IkMifSwibSI6eyJOIjoiMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIyYTZiNjAzNC1iY2Q0LTRiM2QtOTcwZi1hZjIzOGJhMTZjNDIifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXAifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "a2020569312521c6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "150" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjcxODNmZTAzLTRkODMtNDNjYy1iNjhhLTljZjhiZmYwMmFmZCJ9LCJhIjp7IlMiOiJBIn0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBXcnQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6OOA926E0SMVVHF79SS0PKIOEVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "688698bfed0ffd8a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "383" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiYiIsIiMyIjoiYSIsIiMzIjoibSIsIiM0IjoiRG9jc3RvcmVSZXZpc2lvbiJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJYIn0sIjoxIjp7Ik4iOiIzIn0sIjoyIjp7IlMiOiIwNWQzMjlkNS0xMDM3LTRiNzEtOGU2Ni1jNDYwMDg5NDEyMGYifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwV3J0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiUkVNT1ZFICMxXG5TRVQgIzIgPSA6MCwgIzMgPSA6MSwgIzQgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "T0I8KGLR32K52V0FO0KM19FJ43VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e2fd9e920e48c47d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwV3J0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "182" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "130887947" + ], + "X-Amzn-Requestid": [ + "1U94CKMSQTCRO9KB27CE36NSSFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJYIn0sIm0iOnsiTiI6IjMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDVkMzI5ZDUtMTAzNy00YjcxLThlNjYtYzQ2MDA4OTQxMjBmIn0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBXcnQifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "9621d225f552f858", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "180" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjhkOTljNzg3LWQ4MTMtNGJhMC04NTY3LTA3MjNlNTZjODQ1MiJ9LCJhIjp7IlMiOiJBIn0sImkiOnsiTiI6IjEifSwibiI6eyJOIjoiMy41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBJbmMifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "G2VOPI81EFMPQLB59R9P8NH1FJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "63509bd0c60ef1f0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "397" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiaSIsIiMyIjoibSIsIiMzIjoibiIsIiM0IjoiRG9jc3RvcmVSZXZpc2lvbiJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7Ik4iOiIyLjUifSwiOjEiOnsiTiI6IjMifSwiOjIiOnsiTiI6Ii0xIn0sIjozIjp7IlMiOiIzYzk1N2M5NS1mM2I3LTRlZjAtOWNhMS0yY2FlYmY5MDY4ZDcifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwSW5jIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiQUREICMxIDowLCAjMiA6MSwgIzMgOjJcblNFVCAjNCA9IDozXG4ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FPTJ8PKOQO1KNGFCT0S51J72IVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b287957cc5fcec22", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwSW5jIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "214" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1115714380" + ], + "X-Amzn-Requestid": [ + "6BT7EKOAPBB4902UDLBCAGFF3JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJBIn0sImkiOnsiTiI6IjMuNSJ9LCJtIjp7Ik4iOiIzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjNjOTU3Yzk1LWYzYjctNGVmMC05Y2ExLTJjYWViZjkwNjhkNyJ9LCJuIjp7Ik4iOiIyLjUifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcEluYyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "913919fd8c7dae4b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmZjdlZTMwMi0zYjgzLTQxMTYtODhkZS00N2U2Yjg2Mjg2NzQifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMy41In0sIkkiOnsiTiI6IjEifSwiTSI6eyJOVUxMIjp0cnVlfSwiU3QiOnsiUyI6InN0In0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "R7BSQ7T3TTUUJO0GEMEH0TMH2FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b4b552bb765abe37", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "422" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiRiIsIiMyIjoiSSIsIiMzIjoiU3QiLCIjNCI6IlUiLCIjNSI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJOIjoiLTMifSwiOjEiOnsiUyI6InN0ciJ9LCI6MiI6eyJOIjoiNCJ9LCI6MyI6eyJTIjoiMDZjMjNlMWYtODNlYS00ZmRjLWIyODAtODIxYTcxMmYxNDNjIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIiwiVXBkYXRlRXhwcmVzc2lvbiI6IkFERCAjMSA6MFxuUkVNT1ZFICMyXG5TRVQgIzMgPSA6MSwgIzQgPSA6MiwgIzUgPSA6M1xuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QN3FNJD8HE7FLB698AC5DJHRMJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "57597246cb3b62f0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "259" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3747086926" + ], + "X-Amzn-Requestid": [ + "OKOOIB84P6VEGI2G67QVIAELJRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0ciJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAuNSJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIwNmMyM2UxZi04M2VhLTRmZGMtYjI4MC04MjFhNzEyZjE0M2MifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdCJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "2fc4f39d918fae3e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "255" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiOTcxMDIwNy04MzkwLTQ0OTItOWU1YS1iMzg0ZWIzODMwZWMifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIxIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJzdCJ9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVTdHJ1Y3RXcnQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FQ24AMGV9987GRIJDMR6B7GTIBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "631541113bb5b7bf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "389" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiSSIsIiMyIjoiU3QiLCIjMyI6IlUiLCIjNCI6IkRvY3N0b3JlUmV2aXNpb24ifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoic3RyIn0sIjoxIjp7Ik4iOiI0In0sIjoyIjp7IlMiOiI5OTdkYjNjOS1lMDkxLTRmZjktYWU2Yi02OGMxNTEzOTc3NGEifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0V3J0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiUkVNT1ZFICMxXG5TRVQgIzIgPSA6MCwgIzMgPSA6MSwgIzQgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PBA7JDA3J4KTTA2BTJP4D564BJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "db2b0c8034552122", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "106" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0V3J0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "260" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2969215739" + ], + "X-Amzn-Requestid": [ + "BBAR71MJ5428BM1KOKLO56EIA3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0ciJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOTk3ZGIzYzktZTA5MS00ZmY5LWFlNmItNjhjMTUxMzk3NzRhIn0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVTdHJ1Y3RXcnQifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "ad0829d28cf9e8e0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "257" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI1OWQwZTA0NS1hZTU1LTQwYjktODU5OC1lODYyYzkxNzZiMGIifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMy41In0sIkkiOnsiTiI6IjEifSwiTSI6eyJOVUxMIjp0cnVlfSwiU3QiOnsiUyI6InN0In0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdEluYyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KA94APV8V4L8JLFN48MQNN737JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ebbcd79f63488f85", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "367" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiRiIsIiMyIjoiVSIsIiMzIjoiRG9jc3RvcmVSZXZpc2lvbiJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7Ik4iOiItMyJ9LCI6MSI6eyJOIjoiNCJ9LCI6MiI6eyJTIjoiNTI2ZWZjMWMtNDc3MS00YzJkLWFmMTItMTVkMjA3NTE2MjZmIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdEluYyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIiwiVXBkYXRlRXhwcmVzc2lvbiI6IkFERCAjMSA6MCwgIzIgOjFcblNFVCAjMyA9IDoyXG4ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "REJBQ1A392NOS6L2EKPK64NUCRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "19eeca1695a7dfd7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "106" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0SW5jIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "275" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3477595012" + ], + "X-Amzn-Requestid": [ + "P5A5M2DNGPLC68HHJSS2BGFQCBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0In0sIlUiOnsiTiI6IjQifSwiRiI6eyJOIjoiMC41In0sIkkiOnsiTiI6IjEifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNTI2ZWZjMWMtNDc3MS00YzJkLWFmMTItMTVkMjA3NTE2MjZmIn0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVTdHJ1Y3RJbmMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "474934fa177da5e3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoieCJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJ5In19LCJLZXkiOnsibmFtZSI6eyJTIjoiZG9lc05vdEV4aXN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiU0VUICMxID0gOjBcbiJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "LKKEPJ7BLNIO7VSG0U9CO2RTTRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "0140b5fdaf608f9d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "149" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjEyMjAzMmI5LWE1NmUtNGUxNS1hMGNkLTQ0NTFmZTcxZGUzMSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "709LSS2GVS6NL3PI2L7049B6T7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a6444ca198e6db5a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "167" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "924860172" + ], + "X-Amzn-Requestid": [ + "I34CRA4383G6SJ8I19PU23QBKRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTIyMDMyYjktYTU2ZS00ZTE1LWEwY2QtNDQ1MWZlNzFkZTMxIn0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "9d68d383bd3ab705", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "353" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24iLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMTIyMDMyYjktYTU2ZS00ZTE1LWEwY2QtNDQ1MWZlNzFkZTMxIn0sIjoxIjp7IlMiOiJjIn0sIjoyIjp7IlMiOiIzYTBkMzI3NC02MjBlLTQyNjAtODlkYi0yNmQ3YjZlYjgyNTcifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "RU02IPGF2SV55PGM5VT5SRPMQRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a811f9f22e9fde2b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "353" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24iLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMTIyMDMyYjktYTU2ZS00ZTE1LWEwY2QtNDQ1MWZlNzFkZTMxIn0sIjoxIjp7IlMiOiJjIn0sIjoyIjp7IlMiOiI1ZDVmZGMzZC02ZjBmLTQ1NTMtYWExYi00MDAwZjhlNzE3ZWMifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "84GG5U043QORR66N7DIG13099NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "ff2532f150e24ee8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIwZWJhZGEzYi03NTA0LTRhZDItOWQyMC01Nzk2YTBjODlkM2QifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TTRRBR21FMUVVO4HUK8FHPGM1BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0c0da0c7bcc754eb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1349363457" + ], + "X-Amzn-Requestid": [ + "8RH25FSADOQLHHS09OKOPSSOHNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjBlYmFkYTNiLTc1MDQtNGFkMi05ZDIwLTU3OTZhMGM4OWQzZCJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "b7fad92221dd9df5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "356" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24iLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMGViYWRhM2ItNzUwNC00YWQyLTlkMjAtNTc5NmEwYzg5ZDNkIn0sIjoxIjp7IlMiOiJjIn0sIjoyIjp7IlMiOiI5YTA2ZmRjYi00NDA4LTQ2YzItOTMzZS00ODE4ZDk3OTFkNDcifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "1E55UN47OEKHCV628FQ8GCQHK7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b05488bf7d7fe283", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "356" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkRvY3N0b3JlUmV2aXNpb24iLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiMGViYWRhM2ItNzUwNC00YWQyLTlkMjAtNTc5NmEwYzg5ZDNkIn0sIjoxIjp7IlMiOiJjIn0sIjoyIjp7IlMiOiI3ZGExMzNjYy00OTdiLTRmYmEtOWNlYy02ODZhN2NjNmU3ZmEifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "ESH7J6481E1T690JAGS5EBKRERVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "ab1abb3410b110b3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "1OOPCVIIGOQV836S5P67K9RN2VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "2e472901319326ea", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6dHJ1ZSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1441" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2910906906" + ], + "X-Amzn-Requestid": [ + "L638SI4OSBBJBE29HLB4RA9SQJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoic3RyIn0sIlUiOnsiTiI6IjQifSwiRiI6eyJOIjoiMC41In0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjA2YzIzZTFmLTgzZWEtNGZkYy1iMjgwLTgyMWE3MTJmMTQzYyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0In19LHsiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2EwZDMyNzQtNjIwZS00MjYwLTg5ZGItMjZkN2I2ZWI4MjU3In0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvbk1hcCJ9LCJzIjp7IlMiOiJjIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJzdHIifSwiVSI6eyJOIjoiNCJ9LCJGIjp7Ik4iOiIwIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijk5N2RiM2M5LWUwOTEtNGZmOS1hZTZiLTY4YzE1MTM5Nzc0YSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0V3J0In19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJzdCJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAuNSJ9LCJJIjp7Ik4iOiIxIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjUyNmVmYzFjLTQ3NzEtNGMyZC1hZjEyLTE1ZDIwNzUxNjI2ZiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0SW5jIn19LHsiYSI6eyJTIjoiQSJ9LCJpIjp7Ik4iOiIzLjUifSwibSI6eyJOIjoiMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIzYzk1N2M5NS1mM2I3LTRlZjAtOWNhMS0yY2FlYmY5MDY4ZDcifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBJbmMifX0seyJhIjp7IlMiOiJYIn0sImMiOnsiUyI6IkMifSwibSI6eyJOIjoiMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIyYTZiNjAzNC1iY2Q0LTRiM2QtOTcwZi1hZjIzOGJhMTZjNDIifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXAifX0seyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwicyI6eyJTIjoiYyJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI5YTA2ZmRjYi00NDA4LTQ2YzItOTMzZS00ODE4ZDk3OTFkNDcifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LHsiYSI6eyJTIjoiWCJ9LCJtIjp7Ik4iOiIzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjA1ZDMyOWQ1LTEwMzctNGI3MS04ZTY2LWM0NjAwODk0MTIwZiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwV3J0In19XSwiU2Nhbm5lZENvdW50Ijo4fQ==" + } + }, + { + "ID": "0d052ded7ad4b8a6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcFdydCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "F2P2QCSCB6E4AOAHD54SIF0MNVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "451218d7e3ccd4b6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9MM38DO3HFG6SMQGHPDG9C7UM7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5fb44ba731f71e0c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "74" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdEluYyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DRU6THBNGEB5J08ADMT54TJM6JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d6b4e8e5a339cdce", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcEluYyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V5OCQLHKCPLJ89IGMATRQ9GTKNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f9ef2ad0292461b7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "NTU2D0GCCI9Q5ASRSE67BB8H1RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "67fe8ec75573ec6e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "A3VOU45P7AGEHUSNVKGAL6CPNNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1a62c9dbb2e7ff1f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "74" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdFdydCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OH184UNLT0I2FLE141M9VC88OBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e27b2bdd107e2d60", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "A6RM5D0V95NR48N59U33HMJK2JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "636546910b7cb3f1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "179" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6IjY4OTU1NGEwLWViM2ItNGI2NS05MDhlLWFiYmYyYzA2NDc4MyJ9LCJhIjp7IlMiOiJBIn0sImIiOnsiUyI6IkIifSwiaSI6eyJOIjoiMSJ9LCJuIjp7Ik4iOiIzLjUifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CTCSNNV0LGTBE838LT1J5LDH77VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "331b1e5bd8a47010", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "450" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoibiIsIiMyIjoiYiIsIiMzIjoiaSIsIiM0IjoiYSIsIiM1IjoiYyIsIiM2IjoibSIsIiM3IjoiRXRhZyJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7Ik4iOiItMSJ9LCI6MSI6eyJTIjoiWCJ9LCI6MiI6eyJTIjoiQyJ9LCI6MyI6eyJOIjoiMyJ9LCI6NCI6eyJTIjoiN2MwNGZmMDktZDdhNS00NzdjLWFmNTYtMjQ0YTM2MzI4NTE2In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIiwiVXBkYXRlRXhwcmVzc2lvbiI6IkFERCAjMSA6MFxuUkVNT1ZFICMyLCAjM1xuU0VUICM0ID0gOjEsICM1ID0gOjIsICM2ID0gOjMsICM3ID0gOjRcbiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "58TSCUIC8L0NILH8C06RMPSRJBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ee8f53830fe550a1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "197" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3786651208" + ], + "X-Amzn-Requestid": [ + "FI6NH86778USU8221J007AO0CVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJYIn0sIkV0YWciOnsiUyI6IjdjMDRmZjA5LWQ3YTUtNDc3Yy1hZjU2LTI0NGEzNjMyODUxNiJ9LCJjIjp7IlMiOiJDIn0sIm0iOnsiTiI6IjMifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXAifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "d541bd447db1ab01", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "138" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6IjBiZTYwNWY4LWYxYTAtNDkwOS1iODgwLWMyYTZiNTA1ODU4MSJ9LCJhIjp7IlMiOiJBIn0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBXcnQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FOM1SJRRBCB0G74FDRKIC6CSJFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fdb8888518d6064c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "371" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiYiIsIiMyIjoiYSIsIiMzIjoibSIsIiM0IjoiRXRhZyJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJYIn0sIjoxIjp7Ik4iOiIzIn0sIjoyIjp7IlMiOiJhODgwYWI5Zi04NTVmLTRhZDctOTZmNS1hMjlmOTgwOGQ5MTEifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwV3J0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiUkVNT1ZFICMxXG5TRVQgIzIgPSA6MCwgIzMgPSA6MSwgIzQgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "K9OPUAPKE0BEP8CIF2DPAS1HTNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "704b9fa834934d59", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwV3J0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "170" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "843188336" + ], + "X-Amzn-Requestid": [ + "0135D3JPHHTG41PQR02MCNP637VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJYIn0sIkV0YWciOnsiUyI6ImE4ODBhYjlmLTg1NWYtNGFkNy05NmY1LWEyOWY5ODA4ZDkxMSJ9LCJtIjp7Ik4iOiIzIn0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBXcnQifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "58b7e727881ef3d0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6IjQ2ZDRiMTc5LTA3OWQtNGVhZC04MzU5LWExNDg0ZDM1NWUwZiJ9LCJhIjp7IlMiOiJBIn0sImkiOnsiTiI6IjEifSwibiI6eyJOIjoiMy41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBJbmMifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KNKTQS9G7A2VME440GBRAA4KHNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3c8666e74382785e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "385" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiaSIsIiMyIjoibSIsIiMzIjoibiIsIiM0IjoiRXRhZyJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7Ik4iOiIyLjUifSwiOjEiOnsiTiI6IjMifSwiOjIiOnsiTiI6Ii0xIn0sIjozIjp7IlMiOiI3YmQzZjdmMi00MjU0LTQxMGQtOTNkYS03MWFkNjQ5NDI1MzUifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwSW5jIn19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiQUREICMxIDowLCAjMiA6MSwgIzMgOjJcblNFVCAjNCA9IDozXG4ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9CRDU9JL75F3U04FR0D0URSM2JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2d58de7265ae678b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwSW5jIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "202" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4235853636" + ], + "X-Amzn-Requestid": [ + "1VE005FIQKLF27E0GBDE2Q743NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJBIn0sImkiOnsiTiI6IjMuNSJ9LCJFdGFnIjp7IlMiOiI3YmQzZjdmMi00MjU0LTQxMGQtOTNkYS03MWFkNjQ5NDI1MzUifSwibSI6eyJOIjoiMyJ9LCJuIjp7Ik4iOiIyLjUifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcEluYyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "4fd7fa0e957a6eae", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiI2YjNlY2RkZS1jNGE5LTQ3N2UtOTE4My1iNmMxMzlkNDM2MmYifSwiRiI6eyJOIjoiMy41In0sIkkiOnsiTiI6IjEifSwiTSI6eyJOVUxMIjp0cnVlfSwiU3QiOnsiUyI6InN0In0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "K8ON7JJ0G12H40BVG7I900CO33VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "551471ab84cf06f0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "410" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiRiIsIiMyIjoiSSIsIiMzIjoiU3QiLCIjNCI6IlUiLCIjNSI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJOIjoiLTMifSwiOjEiOnsiUyI6InN0ciJ9LCI6MiI6eyJOIjoiNCJ9LCI6MyI6eyJTIjoiYWI3YzcxMzQtMWMwZS00YjY1LTkxZWUtMDU3YmM4NWY1Zjc4In19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdCJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIiwiVXBkYXRlRXhwcmVzc2lvbiI6IkFERCAjMSA6MFxuUkVNT1ZFICMyXG5TRVQgIzMgPSA6MSwgIzQgPSA6MiwgIzUgPSA6M1xuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "79SRJU22I53TM4R899A0023EIBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "79880fd499fdf300", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "259" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4263819541" + ], + "X-Amzn-Requestid": [ + "DE9C6A808C46QR93299N1MAF1RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0ciJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAuNSJ9LCJFdGFnIjp7IlMiOiJhYjdjNzEzNC0xYzBlLTRiNjUtOTFlZS0wNTdiYzg1ZjVmNzgifSwiTSI6eyJOVUxMIjp0cnVlfSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdCJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "c4c1d01ac20ae0d1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "255" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiJhMGI5ZjZmZS1lNjk0LTQ4ODEtOWUwOS1kN2IzYWJiZWE4N2UifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIxIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJzdCJ9LCJVIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVTdHJ1Y3RXcnQifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JBAM5I67QSSL0LDFO0Q1E468E7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "857626af7b37f01e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "377" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiSSIsIiMyIjoiU3QiLCIjMyI6IlUiLCIjNCI6IkV0YWcifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoic3RyIn0sIjoxIjp7Ik4iOiI0In0sIjoyIjp7IlMiOiJhNjA0ZTczOC01NzJkLTQ5MjctYWIyOC00YmM1YWUzN2YwYzQifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0V3J0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiUkVNT1ZFICMxXG5TRVQgIzIgPSA6MCwgIzMgPSA6MSwgIzQgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "B2QS8FK02N5SL77HUNIG4H8N5NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2305e5fd8e049302", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "106" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0V3J0In19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "260" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2842131554" + ], + "X-Amzn-Requestid": [ + "LBECQUEQUFB0HFV9I6C81SK0OVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0ciJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiYTYwNGU3MzgtNTcyZC00OTI3LWFiMjgtNGJjNWFlMzdmMGM0In0sIk0iOnsiTlVMTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVTdHJ1Y3RXcnQifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "5aea6ac8304bd5bd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "257" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiJkY2JhY2FhOS1iNDdhLTQ5ZTQtOGI4Ny04NGUyMTM1ZjI1N2UifSwiRiI6eyJOIjoiMy41In0sIkkiOnsiTiI6IjEifSwiTSI6eyJOVUxMIjp0cnVlfSwiU3QiOnsiUyI6InN0In0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdEluYyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "U6CN0M0SIMDPEJOOTP59VPA833VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1995dd6745c853df", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "355" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoiRiIsIiMyIjoiVSIsIiMzIjoiRXRhZyJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7Ik4iOiItMyJ9LCI6MSI6eyJOIjoiNCJ9LCI6MiI6eyJTIjoiMDQ3MjIzNTItNmE3Yy00MWM0LWJhZmQtOTNjOTdhMWVhMjFjIn19LCJLZXkiOnsibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdEluYyJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIiwiVXBkYXRlRXhwcmVzc2lvbiI6IkFERCAjMSA6MCwgIzIgOjFcblNFVCAjMyA9IDoyXG4ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VEV5HS3UMCLD8JS3IFR527O09RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b52c0f19df7eaa28", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "106" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0SW5jIn19XX19fQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "275" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1088073327" + ], + "X-Amzn-Requestid": [ + "9H2EA3VVS8SU6N48F975S14B9NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0In0sIlUiOnsiTiI6IjQifSwiRiI6eyJOIjoiMC41In0sIkkiOnsiTiI6IjEifSwiRXRhZyI6eyJTIjoiMDQ3MjIzNTItNmE3Yy00MWM0LWJhZmQtOTNjOTdhMWVhMjFjIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVTdHJ1Y3RJbmMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "313dacb806405a36", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiYXR0cmlidXRlX2V4aXN0cyAoIzApIiwiRXhwcmVzc2lvbkF0dHJpYnV0ZU5hbWVzIjp7IiMwIjoibmFtZSIsIiMxIjoieCJ9LCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzIjp7IjowIjp7IlMiOiJ5In19LCJLZXkiOnsibmFtZSI6eyJTIjoiZG9lc05vdEV4aXN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJVcGRhdGVFeHByZXNzaW9uIjoiU0VUICMxID0gOjBcbiJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "KGNKQ260FBUS87AN7DKERLJFENVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "00f2284d495fe2c4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "137" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkV0YWciOnsiUyI6IjU4ZTllYzRiLWE2MmYtNGE3Ny1iZTQ3LWM0MjMyMjM5ZDIzOCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSwiVGFibGVOYW1lIjoiZG9jc3RvcmUtdGVzdC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GBTQE26I71B5DUSMOOS2UPQ62BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8917ae17e28e864c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "155" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1282249496" + ], + "X-Amzn-Requestid": [ + "LQGKRTF1FF0B6QT7IRHCK98O6NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI1OGU5ZWM0Yi1hNjJmLTRhNzctYmU0Ny1jNDIzMjIzOWQyMzgifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "0f6c75b1a7a9bcef", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "341" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWciLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNThlOWVjNGItYTYyZi00YTc3LWJlNDctYzQyMzIyMzlkMjM4In0sIjoxIjp7IlMiOiJjIn0sIjoyIjp7IlMiOiIzZTkwNWFhMy01MzZkLTQzZjktOTY2My00ZWUyNDRmYzRhYjkifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "G961HIHK58PEU42ORMKNVRJ1LVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "136cab6a357aeb8a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "341" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWciLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiNThlOWVjNGItYTYyZi00YTc3LWJlNDctYzQyMzIyMzlkMjM4In0sIjoxIjp7IlMiOiJjIn0sIjoyIjp7IlMiOiI3MzdjYzA1ZS0wM2ExLTQwMmYtYTViNS01YTAxZTIwYzQ4NTQifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "Q5R8EIFI4FIANP6S8AGHO5A9MJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "e2a50ee307879697", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJJdGVtIjp7IkIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJFdGFnIjp7IlMiOiJmODk3NDg0My1jODg1LTQ0MTYtYjFlYi1mM2RlZDdmMDkzOWUifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIlN0Ijp7IlMiOiJhIn0sIlUiOnsiTiI6IjAifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5OT0NNQ3C60ALDA022P2N1SPB3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d49280f93293bc12", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJSZXF1ZXN0SXRlbXMiOnsiZG9jc3RvcmUtdGVzdC0xIjp7IkNvbnNpc3RlbnRSZWFkIjp0cnVlLCJLZXlzIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifX1dfX19" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1838041525" + ], + "X-Amzn-Requestid": [ + "JUMD6S6J9Q7L7N0A3ORKJQJOIVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiZjg5NzQ4NDMtYzg4NS00NDE2LWIxZWItZjNkZWQ3ZjA5MzllIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvblN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "5352d445c0cc201c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "344" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWciLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZjg5NzQ4NDMtYzg4NS00NDE2LWIxZWItZjNkZWQ3ZjA5MzllIn0sIjoxIjp7IlMiOiJjIn0sIjoyIjp7IlMiOiIxZWRjMTQ1Zi0xZWE3LTQ5NmUtOTY4My1iZDVjNzYxYzI2ZTgifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VE6NGTP2EHE452E29706L60NMRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8c503ac4a1d694f4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "344" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25kaXRpb25FeHByZXNzaW9uIjoiIzAgPSA6MCIsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkV0YWciLCIjMSI6InMifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJTIjoiZjg5NzQ4NDMtYzg4NS00NDE2LWIxZWItZjNkZWQ3ZjA5MzllIn0sIjoxIjp7IlMiOiJjIn0sIjoyIjp7IlMiOiIxODkyMTgwMC05NjU2LTRlZDItOThlYS0yYjMxYWJjYzUxYWMifX0sIktleSI6eyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifX0sIlRhYmxlTmFtZSI6ImRvY3N0b3JlLXRlc3QtMSIsIlVwZGF0ZUV4cHJlc3Npb24iOiJTRVQgIzEgPSA6MSwgIzAgPSA6MlxuIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "JIK0S54IICJNG9NHR7H41IAGTFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/testdata/TestQueryErrors.replay b/go-cloud/docstore/awsdynamodb/testdata/TestQueryErrors.replay new file mode 100644 index 000000000..1e30bc2b7 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/testdata/TestQueryErrors.replay @@ -0,0 +1,154 @@ +{ + "Initial": "AQAAAA7gDLPMOFcSLgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "10156f64a7a52518", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1609" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3233200316" + ], + "X-Amzn-Requestid": [ + "Q89Q0G65ON11IHM6C1DEMF72IJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIkF0dHJpYnV0ZVR5cGUiOiJTIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJBdHRyaWJ1dGVUeXBlIjoiTiJ9LHsiQXR0cmlidXRlTmFtZSI6IlRpbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwODA2OTVFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkdsb2JhbFNlY29uZGFyeUluZGV4ZXMiOlt7IkluZGV4QXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMi9pbmRleC9nbG9iYWwiLCJJbmRleE5hbWUiOiJnbG9iYWwiLCJJbmRleFNpemVCeXRlcyI6MTA3LCJJbmRleFN0YXR1cyI6IkFDVElWRSIsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiUGxheWVyIiwiS2V5VHlwZSI6IkhBU0gifSx7IkF0dHJpYnV0ZU5hbWUiOiJUaW1lIiwiS2V5VHlwZSI6IlJBTkdFIn1dLCJQcm9qZWN0aW9uIjp7IlByb2plY3Rpb25UeXBlIjoiQUxMIn0sIlByb3Zpc2lvbmVkVGhyb3VnaHB1dCI6eyJOdW1iZXJPZkRlY3JlYXNlc1RvZGF5IjowLCJSZWFkQ2FwYWNpdHlVbml0cyI6NSwiV3JpdGVDYXBhY2l0eVVuaXRzIjo1fSwiV2FybVRocm91Z2hwdXQiOnsiUmVhZFVuaXRzUGVyU2Vjb25kIjo1LCJTdGF0dXMiOiJBQ1RJVkUiLCJXcml0ZVVuaXRzUGVyU2Vjb25kIjo1fX1dLCJJdGVtQ291bnQiOjEsIktleVNjaGVtYSI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJLZXlUeXBlIjoiSEFTSCJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIktleVR5cGUiOiJSQU5HRSJ9XSwiTG9jYWxTZWNvbmRhcnlJbmRleGVzIjpbeyJJbmRleEFybiI6ImFybjphd3M6ZHluYW1vZGI6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3Njp0YWJsZS9kb2NzdG9yZS10ZXN0LTIvaW5kZXgvbG9jYWwiLCJJbmRleE5hbWUiOiJsb2NhbCIsIkluZGV4U2l6ZUJ5dGVzIjoxMDcsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiR2FtZSIsIktleVR5cGUiOiJIQVNIIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJLZXlUeXBlIjoiUkFOR0UifV0sIlByb2plY3Rpb24iOnsiUHJvamVjdGlvblR5cGUiOiJBTEwifX1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMiIsIlRhYmxlSWQiOiIwZDRmOTk4My1kOGE5LTRhZjEtYTY0NC05YmE3M2NlMGYyMjciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIiLCJUYWJsZVNpemVCeXRlcyI6MTA3LCJUYWJsZVN0YXR1cyI6IkFDVElWRSIsIldhcm1UaHJvdWdocHV0Ijp7IlJlYWRVbml0c1BlclNlY29uZCI6NSwiU3RhdHVzIjoiQUNUSVZFIiwiV3JpdGVVbml0c1BlclNlY29uZCI6NX19fQ==" + } + }, + { + "ID": "947906fd73c9205c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Content-Length": [ + "175" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJDb25zaXN0ZW50UmVhZCI6ZmFsc2UsIkV4cHJlc3Npb25BdHRyaWJ1dGVOYW1lcyI6eyIjMCI6IkdhbWUifSwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlcyI6eyI6MCI6eyJOIjoiMSJ9fSwiS2V5Q29uZGl0aW9uRXhwcmVzc2lvbiI6IiMwID0gOjAiLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "165" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:29:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1880536678" + ], + "X-Amzn-Requestid": [ + "TGISTBGCOL40DS72395GJLCGJBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uLmNvcmFsLnZhbGlkYXRlI1ZhbGlkYXRpb25FeGNlcHRpb24iLCJtZXNzYWdlIjoiT25lIG9yIG1vcmUgcGFyYW1ldGVyIHZhbHVlcyB3ZXJlIGludmFsaWQ6IENvbmRpdGlvbiBwYXJhbWV0ZXIgdHlwZSBkb2VzIG5vdCBtYXRjaCBzY2hlbWEgdHlwZSJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/urls.go b/go-cloud/docstore/awsdynamodb/urls.go new file mode 100644 index 000000000..d899b6823 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/urls.go @@ -0,0 +1,139 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "context" + "errors" + "fmt" + "net/url" + "sync" + + "github.com/aws/aws-sdk-go/aws/client" + dyn "github.com/aws/aws-sdk-go/service/dynamodb" + gcaws "github.com/DataDog/iceberg-go/go-cloud/aws" + "github.com/DataDog/iceberg-go/go-cloud/docstore" +) + +func init() { + docstore.DefaultURLMux().RegisterCollection(Scheme, new(lazySessionOpener)) +} + +type lazySessionOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazySessionOpener) OpenCollectionURL(ctx context.Context, u *url.URL) (*docstore.Collection, error) { + o.init.Do(func() { + sess, err := gcaws.NewDefaultSession() + if err != nil { + o.err = err + return + } + o.opener = &URLOpener{ + ConfigProvider: sess, + } + }) + if o.err != nil { + return nil, fmt.Errorf("open collection %s: %v", u, o.err) + } + return o.opener.OpenCollectionURL(ctx, u) +} + +// Scheme is the URL scheme dynamodb registers its URLOpener under on +// docstore.DefaultMux. +const Scheme = "dynamodb" + +// URLOpener opens dynamodb URLs like +// "dynamodb://mytable?partition_key=partkey&sort_key=sortkey". +// +// The URL Host is used as the table name. See +// https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html +// for more details. +// +// The following query parameters are supported: +// +// - partition_key (required): the path to the partition key of a table or an index. +// - sort_key: the path to the sort key of a table or an index. +// - allow_scans: if "true", allow table scans to be used for queries +// - consistent_read: if "true", a strongly consistent read is used whenever possible. +// +// See https://godoc.org/gocloud.dev/aws#ConfigFromURLParams for supported query +// parameters for overriding the aws.Session from the URL. +type URLOpener struct { + // ConfigProvider must be set to a non-nil value. + ConfigProvider client.ConfigProvider +} + +// OpenCollectionURL opens the collection at the URL's path. See the package doc for more details. +func (o *URLOpener) OpenCollectionURL(_ context.Context, u *url.URL) (*docstore.Collection, error) { + db, tableName, partitionKey, sortKey, opts, err := o.processURL(u) + if err != nil { + return nil, err + } + return OpenCollection(db, tableName, partitionKey, sortKey, opts) +} + +func (o *URLOpener) processURL(u *url.URL) (db *dyn.DynamoDB, tableName, partitionKey, sortKey string, opts *Options, err error) { + q := u.Query() + + partitionKey = q.Get("partition_key") + if partitionKey == "" { + return nil, "", "", "", nil, fmt.Errorf("open collection %s: partition_key is required to open a table", u) + } + q.Del("partition_key") + sortKey = q.Get("sort_key") + q.Del("sort_key") + opts = &Options{ + AllowScans: q.Get("allow_scans") == "true", + RevisionField: q.Get("revision_field"), + ConsistentRead: q.Get("consistent_read") == "true", + } + q.Del("allow_scans") + q.Del("revision_field") + q.Del("consistent_read") + + tableName = u.Host + if tableName == "" { + return nil, "", "", "", nil, fmt.Errorf("open collection %s: URL's host cannot be empty (the table name)", u) + } + if u.Path != "" { + return nil, "", "", "", nil, fmt.Errorf("open collection %s: URL path must be empty, only the host is needed", u) + } + + configProvider := &gcaws.ConfigOverrider{ + Base: o.ConfigProvider, + } + overrideCfg, err := gcaws.ConfigFromURLParams(q) + if err != nil { + return nil, "", "", "", nil, fmt.Errorf("open collection %s: %v", u, err) + } + configProvider.Configs = append(configProvider.Configs, overrideCfg) + db, err = Dial(configProvider) + if err != nil { + return nil, "", "", "", nil, fmt.Errorf("open collection %s: %v", u, err) + } + return db, tableName, partitionKey, sortKey, opts, nil +} + +// Dial gets an AWS DynamoDB service client. +func Dial(p client.ConfigProvider) (*dyn.DynamoDB, error) { + if p == nil { + return nil, errors.New("getting Dynamo service: no AWS session provided") + } + return dyn.New(p), nil +} diff --git a/go-cloud/docstore/awsdynamodb/urls_test.go b/go-cloud/docstore/awsdynamodb/urls_test.go new file mode 100644 index 000000000..1ad6f08b4 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/urls_test.go @@ -0,0 +1,64 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "net/url" + "testing" + + gcaws "github.com/DataDog/iceberg-go/go-cloud/aws" +) + +func TestProcessURL(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"dynamodb://docstore-test?partition_key=_kind", false}, + // OK. + {"dynamodb://docstore-test?partition_key=_kind&sort_key=_id", false}, + // OK, overriding region. + {"dynamodb://docstore-test?partition_key=_kind®ion=" + region, false}, + // OK, allow_scans. + {"dynamodb://docstore-test?partition_key=_kind&allow_scans=true" + region, false}, + // Passing revision field. + {"dynamodb://docstore-test?partition_key=_kind&revision_field=123", false}, + // Passing consistent read field. + {"dynamodb://docstore-test?partition_key=_kind&consistent_read=true", false}, + // Unknown parameter. + {"dynamodb://docstore-test?partition_key=_kind¶m=value", true}, + // With path. + {"dynamodb://docstore-test/subcoll?partition_key=_kind", true}, + // Missing partition_key. + {"dynamodb://docstore-test?sort_key=_id", true}, + } + + sess, err := gcaws.NewDefaultSession() + if err != nil { + t.Fatal(err) + } + o := &URLOpener{ConfigProvider: sess} + for _, test := range tests { + u, err := url.Parse(test.URL) + if err != nil { + t.Fatal(err) + } + _, _, _, _, _, err = o.processURL(u) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + } +} diff --git a/go-cloud/docstore/awsdynamodb/v2/benchmark_test.go b/go-cloud/docstore/awsdynamodb/v2/benchmark_test.go new file mode 100644 index 000000000..684958d64 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/benchmark_test.go @@ -0,0 +1,137 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "context" + "fmt" + "strconv" + "testing" + + awsv2cfg "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression" + "github.com/aws/aws-sdk-go-v2/service/dynamodb" + dyn2Types "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" +) + +var benchmarkTableName = collectionName3 + +func BenchmarkPutVSTransact(b *testing.B) { + // This benchmark compares two ways to replace N items and retrieve their previous values. + // The first way makes N calls to PutItem with ReturnValues set to ALL_OLD. + // The second way calls BatchGetItem followed by TransactWriteItem. + // + // The results show that separate PutItems are faster for up to two items. + cfg, err := awsv2cfg.LoadDefaultConfig(context.Background()) + if err != nil { + b.Fatal("Error initializing aws session for benchmark: ", err) + } + db := dynamodb.NewFromConfig(cfg) + + for nItems := 1; nItems <= 5; nItems++ { + b.Run(fmt.Sprintf("%d-Items", nItems), func(b *testing.B) { + var items []map[string]dyn2Types.AttributeValue + for i := 0; i < nItems; i++ { + items = append(items, map[string]dyn2Types.AttributeValue{ + "name": &dyn2Types.AttributeValueMemberS{Value: fmt.Sprintf("pt-vs-transact-%d", i)}, + "x": &dyn2Types.AttributeValueMemberN{Value: strconv.Itoa(i)}, + "rev": &dyn2Types.AttributeValueMemberN{Value: "1"}, + }) + } + for _, item := range items { + _, err := db.PutItem(context.Background(), &dynamodb.PutItemInput{ + TableName: &benchmarkTableName, + Item: item, + }) + if err != nil { + b.Fatal(err) + } + } + b.Run("PutItem", func(b *testing.B) { + for n := 0; n < b.N; n++ { + putItems(b, db, items) + } + }) + b.Run("TransactWrite", func(b *testing.B) { + for n := 0; n < b.N; n++ { + batchGetTransactWrite(b, db, items) + } + }) + }) + } +} + +func putItems(b *testing.B, db *dynamodb.Client, items []map[string]dyn2Types.AttributeValue) { + b.Helper() + + for i, item := range items { + item["x"] = &dyn2Types.AttributeValueMemberN{Value: strconv.Itoa(i + 1)} + in := &dynamodb.PutItemInput{ + TableName: &benchmarkTableName, + Item: item, + ReturnValues: dyn2Types.ReturnValueAllOld, + } + ce, err := expression.NewBuilder(). + WithCondition(expression.Name("rev").Equal(expression.Value(1))). + Build() + if err != nil { + b.Fatal(err) + } + in.ExpressionAttributeNames = ce.Names() + in.ExpressionAttributeValues = ce.Values() + in.ConditionExpression = ce.Condition() + out, err := db.PutItem(context.Background(), in) + if err != nil { + b.Fatal(err) + } + if got, want := len(out.Attributes), 3; got != want { + b.Fatalf("got %d attributes, want %d", got, want) + } + } +} + +func batchGetTransactWrite(b *testing.B, db *dynamodb.Client, items []map[string]dyn2Types.AttributeValue) { + b.Helper() + + keys := make([]map[string]dyn2Types.AttributeValue, len(items)) + tws := make([]dyn2Types.TransactWriteItem, len(items)) + for i, item := range items { + keys[i] = map[string]dyn2Types.AttributeValue{"name": items[i]["name"]} + item["x"] = &dyn2Types.AttributeValueMemberN{Value: strconv.Itoa(i + 2)} + put := &dyn2Types.Put{TableName: &benchmarkTableName, Item: items[i]} + ce, err := expression.NewBuilder(). + WithCondition(expression.Name("rev").Equal(expression.Value(1))). + Build() + if err != nil { + b.Fatal(err) + } + put.ExpressionAttributeNames = ce.Names() + put.ExpressionAttributeValues = ce.Values() + put.ConditionExpression = ce.Condition() + tws[i] = dyn2Types.TransactWriteItem{Put: put} + } + _, err := db.BatchGetItem(context.Background(), &dynamodb.BatchGetItemInput{ + RequestItems: map[string]dyn2Types.KeysAndAttributes{ + benchmarkTableName: {Keys: keys}, + }, + }) + if err != nil { + b.Fatal(err) + } + _, err = db.TransactWriteItems(context.Background(), &dynamodb.TransactWriteItemsInput{TransactItems: tws}) + if err != nil { + b.Fatal(err) + } +} diff --git a/go-cloud/docstore/awsdynamodb/v2/codec.go b/go-cloud/docstore/awsdynamodb/v2/codec.go new file mode 100644 index 000000000..00509d212 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/codec.go @@ -0,0 +1,384 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "errors" + "fmt" + "reflect" + "strconv" + "time" + + dyn2Types "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" +) + +var nullValue = &dyn2Types.AttributeValueMemberNULL{Value: true} + +type encoder struct { + av dyn2Types.AttributeValue +} + +func (e *encoder) EncodeNil() { e.av = nullValue } +func (e *encoder) EncodeBool(x bool) { e.av = &dyn2Types.AttributeValueMemberBOOL{Value: x} } +func (e *encoder) EncodeInt(x int64) { + e.av = &dyn2Types.AttributeValueMemberN{Value: strconv.FormatInt(x, 10)} +} +func (e *encoder) EncodeUint(x uint64) { + e.av = &dyn2Types.AttributeValueMemberN{Value: strconv.FormatUint(x, 10)} +} +func (e *encoder) EncodeBytes(x []byte) { e.av = &dyn2Types.AttributeValueMemberB{Value: x} } +func (e *encoder) EncodeFloat(x float64) { e.av = encodeFloat(x) } + +func (e *encoder) ListIndex(int) { panic("impossible") } +func (e *encoder) MapKey(string) { panic("impossible") } + +func (e *encoder) EncodeString(x string) { + if len(x) == 0 { + e.av = nullValue + } else { + e.av = &dyn2Types.AttributeValueMemberS{Value: x} + } +} + +func (e *encoder) EncodeComplex(x complex128) { + e.av = &dyn2Types.AttributeValueMemberL{Value: []dyn2Types.AttributeValue{encodeFloat(real(x)), encodeFloat(imag(x))}} +} + +func (e *encoder) EncodeList(n int) driver.Encoder { + s := make([]dyn2Types.AttributeValue, n) + e.av = &dyn2Types.AttributeValueMemberL{Value: s} + return &listEncoder{s: s} +} + +func (e *encoder) EncodeMap(n int) driver.Encoder { + m := make(map[string]dyn2Types.AttributeValue, n) + e.av = &dyn2Types.AttributeValueMemberM{Value: m} + return &mapEncoder{m: m} +} + +var typeOfGoTime = reflect.TypeOf(time.Time{}) + +// EncodeSpecial encodes time.Time specially. +func (e *encoder) EncodeSpecial(v reflect.Value) (bool, error) { + switch v.Type() { + case typeOfGoTime: + ts := v.Interface().(time.Time).Format(time.RFC3339Nano) + e.EncodeString(ts) + default: + return false, nil + } + return true, nil +} + +type listEncoder struct { + s []dyn2Types.AttributeValue + encoder +} + +func (e *listEncoder) ListIndex(i int) { e.s[i] = e.av } + +type mapEncoder struct { + m map[string]dyn2Types.AttributeValue + encoder +} + +func (e *mapEncoder) MapKey(k string) { e.m[k] = e.av } + +func encodeDoc(doc driver.Document) (dyn2Types.AttributeValue, error) { + var e encoder + if err := doc.Encode(&e); err != nil { + return nil, err + } + return e.av, nil +} + +// Encode the key fields of the given document into a map AttributeValue. +// pkey and skey are the names of the partition key field and the sort key field. +// pkey must always be non-empty, but skey may be empty if the collection has no sort key. +func encodeDocKeyFields(doc driver.Document, pkey, skey string) (*dyn2Types.AttributeValueMemberM, error) { + m := map[string]dyn2Types.AttributeValue{} + + set := func(fieldName string) error { + fieldVal, err := doc.GetField(fieldName) + if err != nil { + return err + } + attrVal, err := encodeValue(fieldVal) + if err != nil { + return err + } + m[fieldName] = attrVal + return nil + } + + if err := set(pkey); err != nil { + return nil, err + } + if skey != "" { + if err := set(skey); err != nil { + return nil, err + } + } + return &dyn2Types.AttributeValueMemberM{Value: m}, nil +} + +func encodeValue(v interface{}) (dyn2Types.AttributeValue, error) { + var e encoder + if err := driver.Encode(reflect.ValueOf(v), &e); err != nil { + return nil, err + } + return e.av, nil +} + +func encodeFloat(f float64) dyn2Types.AttributeValue { + return &dyn2Types.AttributeValueMemberN{Value: strconv.FormatFloat(f, 'f', -1, 64)} +} + +//////////////////////////////////////////////////////////////// + +func decodeDoc(item dyn2Types.AttributeValue, doc driver.Document) error { + return doc.Decode(decoder{av: item}) +} + +type decoder struct { + av dyn2Types.AttributeValue +} + +func (d decoder) String() string { + if s, ok := d.av.(fmt.Stringer); ok { + return s.String() + } + return fmt.Sprint(d.av) +} + +func (d decoder) AsBool() (bool, bool) { + i, ok := d.av.(*dyn2Types.AttributeValueMemberBOOL) + if !ok { + return false, false + } + return i.Value, true +} + +func (d decoder) AsNull() bool { + i, ok := d.av.(*dyn2Types.AttributeValueMemberNULL) + if !ok { + return false + } + return i.Value +} + +func (d decoder) AsString() (string, bool) { + // Empty string is represented by NULL. + _, ok := d.av.(*dyn2Types.AttributeValueMemberNULL) + if ok { + return "", true + } + i, ok := d.av.(*dyn2Types.AttributeValueMemberS) + if !ok { + return "", false + } + return i.Value, true +} + +func (d decoder) AsInt() (int64, bool) { + i, ok := d.av.(*dyn2Types.AttributeValueMemberN) + if !ok { + return 0, false + } + v, err := strconv.ParseInt(i.Value, 10, 64) + if err != nil { + return 0, false + } + return v, true +} + +func (d decoder) AsUint() (uint64, bool) { + i, ok := d.av.(*dyn2Types.AttributeValueMemberN) + if !ok { + return 0, false + } + v, err := strconv.ParseUint(i.Value, 10, 64) + if err != nil { + return 0, false + } + return v, true +} + +func (d decoder) AsFloat() (float64, bool) { + i, ok := d.av.(*dyn2Types.AttributeValueMemberN) + if !ok { + return 0, false + } + v, err := strconv.ParseFloat(i.Value, 64) + if err != nil { + return 0, false + } + return v, true +} + +func (d decoder) AsComplex() (complex128, bool) { + iface, ok := d.av.(*dyn2Types.AttributeValueMemberL) + if !ok { + return 0, false + } + if len(iface.Value) != 2 { + return 0, false + } + r, ok := decoder{iface.Value[0]}.AsFloat() + if !ok { + return 0, false + } + i, ok := decoder{iface.Value[1]}.AsFloat() + if !ok { + return 0, false + } + return complex(r, i), true +} + +func (d decoder) AsBytes() ([]byte, bool) { + i, ok := d.av.(*dyn2Types.AttributeValueMemberB) + if !ok { + return nil, false + } + return i.Value, true +} + +func (d decoder) ListLen() (int, bool) { + i, ok := d.av.(*dyn2Types.AttributeValueMemberL) + if !ok { + return 0, false + } + return len(i.Value), true +} + +func (d decoder) DecodeList(f func(i int, vd driver.Decoder) bool) { + iface, ok := d.av.(*dyn2Types.AttributeValueMemberL) + if !ok { + // V1 behavior treated this as indistinct from an empty list, + // which this return replicates. + // Should this be explicitly handled in some way? + return + } + for i, el := range iface.Value { + if !f(i, decoder{el}) { + break + } + } +} + +func (d decoder) MapLen() (int, bool) { + i, ok := d.av.(*dyn2Types.AttributeValueMemberM) + if !ok { + return 0, false + } + return len(i.Value), true +} + +func (d decoder) DecodeMap(f func(key string, vd driver.Decoder, exactMatch bool) bool) { + i, ok := d.av.(*dyn2Types.AttributeValueMemberM) + if !ok { + // V1 behavior treated this as indistinct from an empty map, + // which this return replicates. + // Should this be explicitly handled in some way? + return + } + for k, av := range i.Value { + if !f(k, decoder{av}, true) { + break + } + } +} + +func (d decoder) AsInterface() (interface{}, error) { + return toGoValue(d.av) +} + +func toGoValue(av dyn2Types.AttributeValue) (interface{}, error) { + switch v := av.(type) { + case *dyn2Types.AttributeValueMemberNULL: + return nil, nil + case *dyn2Types.AttributeValueMemberBOOL: + return v.Value, nil + case *dyn2Types.AttributeValueMemberN: + f, err := strconv.ParseFloat(v.Value, 64) + if err != nil { + return nil, err + } + i := int64(f) + if float64(i) == f { + return i, nil + } + u := uint64(f) + if float64(u) == f { + return u, nil + } + return f, nil + + case *dyn2Types.AttributeValueMemberB: + return v.Value, nil + case *dyn2Types.AttributeValueMemberS: + return v.Value, nil + + case *dyn2Types.AttributeValueMemberL: + s := make([]interface{}, len(v.Value)) + for i, v := range v.Value { + x, err := toGoValue(v) + if err != nil { + return nil, err + } + s[i] = x + } + return s, nil + + case *dyn2Types.AttributeValueMemberM: + m := make(map[string]interface{}, len(v.Value)) + for k, v := range v.Value { + x, err := toGoValue(v) + if err != nil { + return nil, err + } + m[k] = x + } + return m, nil + + default: + return nil, fmt.Errorf("awsdynamodb: AttributeValue %s not supported", av) + } +} + +func (d decoder) AsSpecial(v reflect.Value) (bool, interface{}, error) { + unsupportedTypes := `unsupported type, the docstore driver for DynamoDB does + not decode DynamoDB set types, such as string set, number set and binary set` + switch d.av.(type) { + case *dyn2Types.AttributeValueMemberSS: + return true, nil, errors.New(unsupportedTypes) + case *dyn2Types.AttributeValueMemberNS: + return true, nil, errors.New(unsupportedTypes) + case *dyn2Types.AttributeValueMemberBS: + return true, nil, errors.New(unsupportedTypes) + } + + switch v.Type() { + case typeOfGoTime: + i, ok := d.av.(*dyn2Types.AttributeValueMemberS) + if !ok { + return false, nil, errors.New("expected string field for time.Time") + } + t, err := time.Parse(time.RFC3339Nano, i.Value) + return true, t, err + } + return false, nil, nil +} diff --git a/go-cloud/docstore/awsdynamodb/v2/codec_test.go b/go-cloud/docstore/awsdynamodb/v2/codec_test.go new file mode 100644 index 000000000..d4128ebf3 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/codec_test.go @@ -0,0 +1,196 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "reflect" + "testing" + + dynattr "github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue" + dyn2Types "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" +) + +var compareIgnoreAttributeUnexported = cmpopts.IgnoreUnexported( + dyn2Types.AttributeValueMemberB{}, + dyn2Types.AttributeValueMemberBOOL{}, + dyn2Types.AttributeValueMemberBS{}, + dyn2Types.AttributeValueMemberL{}, + dyn2Types.AttributeValueMemberM{}, + dyn2Types.AttributeValueMemberN{}, + dyn2Types.AttributeValueMemberNS{}, + dyn2Types.AttributeValueMemberNULL{}, + dyn2Types.AttributeValueMemberS{}, + dyn2Types.AttributeValueMemberSS{}, +) + +func TestEncodeValue(t *testing.T) { + avn := func(s string) dyn2Types.AttributeValue { return &dyn2Types.AttributeValueMemberN{Value: s} } + avl := func(avs ...dyn2Types.AttributeValue) dyn2Types.AttributeValue { + return &dyn2Types.AttributeValueMemberL{Value: avs} + } + + var seven int32 = 7 + var nullptr *int + + for _, test := range []struct { + in interface{} + want dyn2Types.AttributeValue + }{ + // null + {nil, nullValue}, + {nullptr, nullValue}, + // number + {0, avn("0")}, + {uint64(999), avn("999")}, + {3.5, avn("3.5")}, + {seven, avn("7")}, + {&seven, avn("7")}, + // string + {"", nullValue}, + {"x", &dyn2Types.AttributeValueMemberS{Value: "x"}}, + {"abc123", &dyn2Types.AttributeValueMemberS{Value: "abc123"}}, + {"abc 123", &dyn2Types.AttributeValueMemberS{Value: "abc 123"}}, + // bool + {true, &dyn2Types.AttributeValueMemberBOOL{Value: true}}, + {false, &dyn2Types.AttributeValueMemberBOOL{Value: false}}, + // list + {[]int(nil), nullValue}, + {[]int{}, &dyn2Types.AttributeValueMemberL{Value: []dyn2Types.AttributeValue{}}}, + {[]int{1, 2}, avl(avn("1"), avn("2"))}, + {[...]int{1, 2}, avl(avn("1"), avn("2"))}, + {[]interface{}{nil, false}, avl(nullValue, &dyn2Types.AttributeValueMemberBOOL{Value: false})}, + // map + {map[string]int(nil), nullValue}, + {map[string]int{}, &dyn2Types.AttributeValueMemberM{Value: map[string]dyn2Types.AttributeValue{}}}, + { + map[string]int{"a": 1, "b": 2}, + &dyn2Types.AttributeValueMemberM{Value: map[string]dyn2Types.AttributeValue{ + "a": avn("1"), + "b": avn("2"), + }}, + }, + } { + var e encoder + if err := driver.Encode(reflect.ValueOf(test.in), &e); err != nil { + t.Fatal(err) + } + got := e.av + if !cmp.Equal(got, test.want, compareIgnoreAttributeUnexported) { + t.Errorf("%#v: got %#v, want %#v", test.in, got, test.want) + } + } +} + +func TestDecodeValue(t *testing.T) { + avn := func(s string) dyn2Types.AttributeValue { return &dyn2Types.AttributeValueMemberN{Value: s} } + avl := func(vals ...dyn2Types.AttributeValue) dyn2Types.AttributeValue { + return &dyn2Types.AttributeValueMemberL{Value: vals} + } + + for _, test := range []struct { + in dyn2Types.AttributeValue + want interface{} + }{ + // null + // {nullValue, nil}, // cant reflect new, how best to test? + // bool + {&dyn2Types.AttributeValueMemberBOOL{Value: false}, false}, + {&dyn2Types.AttributeValueMemberBOOL{Value: true}, true}, + // string + {&dyn2Types.AttributeValueMemberS{Value: "x"}, "x"}, + // int64 + {avn("7"), int64(7)}, + {avn("-7"), int64(-7)}, + {avn("0"), int64(0)}, + // uint64 + {avn("7"), uint64(7)}, + {avn("0"), uint64(0)}, + // float64 + {avn("7"), float64(7)}, + {avn("0"), float64(0)}, + {avn("3.1415"), float64(3.1415)}, + // []byte + {&dyn2Types.AttributeValueMemberB{Value: []byte(`123`)}, []byte(`123`)}, + // List + {avl(avn("12"), avn("37")), []int64{12, 37}}, + {avl(avn("12"), avn("37")), []uint64{12, 37}}, + {avl(avn("12.8"), avn("37.1")), []float64{12.8, 37.1}}, + // Map + { + &dyn2Types.AttributeValueMemberM{Value: map[string]dyn2Types.AttributeValue{}}, + map[string]int{}, + }, + { + &dyn2Types.AttributeValueMemberM{Value: map[string]dyn2Types.AttributeValue{"a": avn("1"), "b": avn("2")}}, + map[string]int{"a": 1, "b": 2}, + }, + } { + var ( + target = reflect.New(reflect.TypeOf(test.want)) + ) + + dec := decoder{av: test.in} + if err := driver.Decode(target.Elem(), dec); err != nil { + t.Errorf(" error decoding value %#v, got error: %#v", test.in, err) + continue + } + + if !cmp.Equal(target.Elem().Interface(), test.want, compareIgnoreAttributeUnexported) { + t.Errorf(" %#v: got %#v, want %#v", test.in, target.Elem().Interface(), test.want) + } + } +} + +func TestDecodeErrorOnUnsupported(t *testing.T) { + for _, tc := range []struct { + in dyn2Types.AttributeValue + out interface{} + }{ + {&dyn2Types.AttributeValueMemberSS{Value: []string{"foo", "bar"}}, []string{}}, + {&dyn2Types.AttributeValueMemberNS{Value: []string{"1.1", "-2.2", "3.3"}}, []float64{}}, + {&dyn2Types.AttributeValueMemberBS{Value: [][]byte{{4}, {5}, {6}}}, [][]byte{}}, + } { + d := decoder{av: tc.in} + if err := driver.Decode(reflect.ValueOf(tc.out), &d); err == nil { + t.Error("got nil error, want unsupported error") + } + } +} + +type codecTester struct{} + +func (ct *codecTester) UnsupportedTypes() []drivertest.UnsupportedType { + return []drivertest.UnsupportedType{drivertest.BinarySet} +} + +func (ct *codecTester) NativeEncode(obj interface{}) (interface{}, error) { + return dynattr.Marshal(obj) +} + +func (ct *codecTester) NativeDecode(value, dest interface{}) error { + return dynattr.Unmarshal(value.(dyn2Types.AttributeValue), dest) +} + +func (ct *codecTester) DocstoreEncode(obj interface{}) (interface{}, error) { + return encodeDoc(drivertest.MustDocument(obj)) +} + +func (ct *codecTester) DocstoreDecode(value, dest interface{}) error { + return decodeDoc(value.(dyn2Types.AttributeValue), drivertest.MustDocument(dest)) +} diff --git a/go-cloud/docstore/awsdynamodb/v2/create_tables.sh b/go-cloud/docstore/awsdynamodb/v2/create_tables.sh new file mode 100644 index 000000000..db5f6f42c --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/create_tables.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Creates the DynamoDB tables needed for tests. +# +# If a table already exists, this script will fail. To re-create the table, run +# aws dynamodb delete-table --table-name ... +# and wait until the deletion completes. + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +# except we want to keep going if there is a failure. +set -uxo pipefail + +# The docstore-test-1 table has a single partition key called "name". + + +aws dynamodb create-table \ + --region us-east-2 \ + --table-name docstore-test-1 \ + --attribute-definitions AttributeName=name,AttributeType=S \ + --key-schema AttributeName=name,KeyType=HASH \ + --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 + + +# The docstore-test-2 table has both a partition and a sort key, and two indexes. + +aws dynamodb create-table \ + --region us-east-2 \ + --table-name docstore-test-2 \ + --attribute-definitions \ + AttributeName=Game,AttributeType=S \ + AttributeName=Player,AttributeType=S \ + AttributeName=Score,AttributeType=N \ + AttributeName=Time,AttributeType=S \ + --key-schema AttributeName=Game,KeyType=HASH AttributeName=Player,KeyType=RANGE \ + --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \ + --local-secondary-indexes \ + 'IndexName=local,KeySchema=[{AttributeName=Game,KeyType=HASH},{AttributeName=Score,KeyType=RANGE}],Projection={ProjectionType=ALL}' \ + --global-secondary-indexes \ + 'IndexName=global,KeySchema=[{AttributeName=Player,KeyType=HASH},{AttributeName=Time,KeyType=RANGE}],Projection={ProjectionType=ALL},ProvisionedThroughput={ReadCapacityUnits=5,WriteCapacityUnits=5}' + + diff --git a/go-cloud/docstore/awsdynamodb/v2/dynamo.go b/go-cloud/docstore/awsdynamodb/v2/dynamo.go new file mode 100644 index 000000000..1f6377295 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/dynamo.go @@ -0,0 +1,796 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb provides a docstore implementation backed by Amazon +// DynamoDB. +// Use OpenCollection to construct a *docstore.Collection. +// +// # URLs +// +// For docstore.OpenCollection, awsdynamodb registers for the scheme +// "dynamodb". The default URL opener will use an AWS session with the default +// credentials and configuration; see +// https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/configure-gosdk.html for more details. +// To customize the URL opener, or for more details on the URL format, see +// URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// awsdynamodb exposes the following types for As: +// - Collection.As: *dynamodb.DynamoDB +// - ActionList.BeforeDo: *dynamodb.BatchGetItemInput or *dynamodb.PutItemInput or *dynamodb.DeleteItemInput +// or *dynamodb.UpdateItemInput +// - Query.BeforeQuery: *dynamodb.QueryInput or *dynamodb.ScanInput +// - DocumentIterator: *dynamodb.QueryOutput or *dynamodb.ScanOutput +// - ErrorAs: smithy.OperationError +package awsdynamodb + +import ( + "context" + "errors" + "fmt" + "reflect" + "strings" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression" + dyn "github.com/aws/aws-sdk-go-v2/service/dynamodb" + dyn2Types "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" + "github.com/aws/smithy-go" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + wire.Struct(new(URLOpener), "ConfigProvider"), +) + +type collection struct { + db *dyn.Client + table string // DynamoDB table name + partitionKey string + sortKey string + description *dyn2Types.TableDescription + opts *Options +} + +// FallbackFunc is a function for executing queries that cannot be run by the built-in +// awsdynamodb logic. See Options.RunQueryFunc for details. +type FallbackFunc func(context.Context, *driver.Query, RunQueryFunc) (driver.DocumentIterator, error) + +// Options holds various options. +type Options struct { + // If false, queries that can only be executed by scanning the entire table + // return an error instead (with the exception of a query with no filters). + AllowScans bool + + // The name of the field holding the document revision. + // Defaults to docstore.DefaultRevisionField. + RevisionField string + + // If set, call this function on queries that we cannot execute at all (for + // example, a query with an OrderBy clause that lacks an equality filter on a + // partition key). The function should execute the query however it wishes, and + // return an iterator over the results. It can use the RunQueryFunc passed as its + // third argument to have the DynamoDB driver run a query, for instance a + // modified version of the original query. + // + // If RunQueryFallback is nil, queries that cannot be executed will fail with a + // error that has code Unimplemented. + RunQueryFallback FallbackFunc + + // The maximum number of concurrent goroutines started for a single call to + // ActionList.Do. If less than 1, there is no limit. + MaxOutstandingActionRPCs int + + // If true, a strongly consistent read is used whenever possible, including + // get, query, scan, etc.; default to false, where an eventually consistent + // read is used. + // + // Not all read operations support this mode however, such as querying against + // a global secondary index, the operation will return an InvalidArgument error + // in such case, please check the official DynamoDB documentation for more + // details. + // + // The native client for DynamoDB uses this option in a per-action basis, if + // you need the flexibility to run both modes on the same collection, create + // two collections with different mode. + ConsistentRead bool +} + +// RunQueryFunc is the type of the function passed to RunQueryFallback. +type RunQueryFunc func(context.Context, *driver.Query) (driver.DocumentIterator, error) + +// OpenCollection creates a *docstore.Collection representing a DynamoDB collection. +func OpenCollection(db *dyn.Client, tableName, partitionKey, sortKey string, opts *Options) (*docstore.Collection, error) { + c, err := newCollection(db, tableName, partitionKey, sortKey, opts) + if err != nil { + return nil, err + } + return docstore.NewCollection(c), nil +} + +func newCollection(db *dyn.Client, tableName, partitionKey, sortKey string, opts *Options) (*collection, error) { + out, err := db.DescribeTable(context.Background(), &dyn.DescribeTableInput{TableName: &tableName}) + if err != nil { + return nil, err + } + if opts == nil { + opts = &Options{} + } + if opts.RevisionField == "" { + opts.RevisionField = docstore.DefaultRevisionField + } + return &collection{ + db: db, + table: tableName, + partitionKey: partitionKey, + sortKey: sortKey, + description: out.Table, + opts: opts, + }, nil +} + +// Key returns a two-element array with the partition key and sort key, if any. +func (c *collection) Key(doc driver.Document) (interface{}, error) { + pkey, err := doc.GetField(c.partitionKey) + if err != nil || pkey == nil || driver.IsEmptyValue(reflect.ValueOf(pkey)) { + return nil, nil // missing key is not an error + } + keys := [2]interface{}{pkey} + if c.sortKey != "" { + keys[1], _ = doc.GetField(c.sortKey) // ignore error since keys[1] is nil in that case + } + return keys, nil +} + +func (c *collection) RevisionField() string { return c.opts.RevisionField } + +func (c *collection) RunActions(ctx context.Context, actions []*driver.Action, opts *driver.RunActionsOptions) driver.ActionListError { + errs := make([]error, len(actions)) + beforeGets, gets, writes, writesTx, afterGets := driver.GroupActions(actions) + c.runGets(ctx, beforeGets, errs, opts) + ch := make(chan struct{}) + ch2 := make(chan struct{}) + go func() { defer close(ch); c.runWrites(ctx, writes, errs, opts) }() + go func() { defer close(ch2); c.transactWrite(ctx, writesTx, errs, opts) }() + c.runGets(ctx, gets, errs, opts) + <-ch + <-ch2 + c.runGets(ctx, afterGets, errs, opts) + return driver.NewActionListError(errs) +} + +func (c *collection) runGets(ctx context.Context, actions []*driver.Action, errs []error, opts *driver.RunActionsOptions) { + const batchSize = 100 + t := driver.NewThrottle(c.opts.MaxOutstandingActionRPCs) + for _, group := range driver.GroupByFieldPath(actions) { + n := len(group) / batchSize + for i := 0; i < n; i++ { + i := i + t.Acquire() + go func(group []*driver.Action) { + defer t.Release() + c.batchGet(ctx, group, errs, opts, batchSize*i, batchSize*(i+1)-1) + }(group) + } + if n*batchSize < len(group) { + t.Acquire() + go func(group []*driver.Action) { + defer t.Release() + c.batchGet(ctx, group, errs, opts, batchSize*n, len(group)-1) + }(group) + } + } + t.Wait() +} + +func (c *collection) batchGet(ctx context.Context, gets []*driver.Action, errs []error, opts *driver.RunActionsOptions, start, end int) { + // errors need to be mapped to the actions' indices. + setErr := func(err error) { + for i := start; i <= end; i++ { + errs[gets[i].Index] = err + } + } + + keys := make([]map[string]dyn2Types.AttributeValue, 0, end-start+1) + for i := start; i <= end; i++ { + av, err := encodeDocKeyFields(gets[i].Doc, c.partitionKey, c.sortKey) + if err != nil { + errs[gets[i].Index] = err + } + + keys = append(keys, av.Value) + } + ka := dyn2Types.KeysAndAttributes{ + Keys: keys, + ConsistentRead: aws.Bool(c.opts.ConsistentRead), + } + if len(gets[start].FieldPaths) != 0 { + // We need to add the key fields if the user doesn't include them. The + // BatchGet API doesn't return them otherwise. + var hasP, hasS bool + var nbs []expression.NameBuilder + for _, fp := range gets[start].FieldPaths { + p := strings.Join(fp, ".") + nbs = append(nbs, expression.Name(p)) + if p == c.partitionKey { + hasP = true + } else if p == c.sortKey { + hasS = true + } + } + if !hasP { + nbs = append(nbs, expression.Name(c.partitionKey)) + } + if c.sortKey != "" && !hasS { + nbs = append(nbs, expression.Name(c.sortKey)) + } + expr, err := expression.NewBuilder(). + WithProjection(expression.AddNames(expression.ProjectionBuilder{}, nbs...)). + Build() + if err != nil { + setErr(err) + return + } + ka.ProjectionExpression = expr.Projection() + ka.ExpressionAttributeNames = expr.Names() + } + in := &dyn.BatchGetItemInput{RequestItems: map[string]dyn2Types.KeysAndAttributes{c.table: ka}} + if opts.BeforeDo != nil { + if err := opts.BeforeDo(driver.AsFunc(in)); err != nil { + setErr(err) + return + } + } + out, err := c.db.BatchGetItem(ctx, in) + if err != nil { + setErr(err) + return + } + found := make([]bool, end-start+1) + am := mapActionIndices(gets, start, end) + for _, item := range out.Responses[c.table] { + if item != nil { + key := map[string]interface{}{c.partitionKey: nil} + if c.sortKey != "" { + key[c.sortKey] = nil + } + keysOnly, err := driver.NewDocument(key) + if err != nil { + panic(err) + } + err = decodeDoc(&dyn2Types.AttributeValueMemberM{Value: item}, keysOnly) + if err != nil { + continue + } + decKey, err := c.Key(keysOnly) + if err != nil { + continue + } + i := am[decKey] + errs[gets[i].Index] = decodeDoc(&dyn2Types.AttributeValueMemberM{Value: item}, gets[i].Doc) + found[i-start] = true + } + } + for delta, f := range found { + if !f { + errs[gets[start+delta].Index] = gcerr.Newf(gcerr.NotFound, nil, "item %v not found", gets[start+delta].Doc) + } + } +} + +func mapActionIndices(actions []*driver.Action, start, end int) map[interface{}]int { + m := make(map[interface{}]int) + for i := start; i <= end; i++ { + m[actions[i].Key] = i + } + return m +} + +// runWrites executes all the writes as separate RPCs, concurrently. +func (c *collection) runWrites(ctx context.Context, writes []*driver.Action, errs []error, opts *driver.RunActionsOptions) { + var ops []*writeOp + for _, w := range writes { + op, err := c.newWriteOp(w, opts) + if err != nil { + errs[w.Index] = err + } else { + ops = append(ops, op) + } + } + + t := driver.NewThrottle(c.opts.MaxOutstandingActionRPCs) + for _, op := range ops { + op := op + t.Acquire() + go func() { + defer t.Release() + err := op.run(ctx) + a := op.action + if err != nil { + errs[a.Index] = err + } else { + errs[a.Index] = c.onSuccess(op) + } + }() + } + t.Wait() +} + +// A writeOp describes a single write to DynamoDB. The write can be executed +// on its own, or included as part of a transaction. +type writeOp struct { + action *driver.Action + writeItem dyn2Types.TransactWriteItem // for inclusion in a transaction + newPartitionKey string // for a Create on a document without a partition key + newRevision string + run func(context.Context) error // run as a single RPC +} + +func (c *collection) newWriteOp(a *driver.Action, opts *driver.RunActionsOptions) (*writeOp, error) { + switch a.Kind { + case driver.Create, driver.Replace, driver.Put: + return c.newPut(a, opts) + case driver.Update: + return c.newUpdate(a, opts) + case driver.Delete: + return c.newDelete(a, opts) + default: + panic("bad write kind") + } +} + +func (c *collection) newPut(a *driver.Action, opts *driver.RunActionsOptions) (*writeOp, error) { + av, err := encodeDoc(a.Doc) + if err != nil { + return nil, err + } + avm, ok := av.(*dyn2Types.AttributeValueMemberM) + if !ok { + // should never happen, but handle + return nil, fmt.Errorf("unable to put document, unable to encode to map") + } + mf := c.missingKeyField(avm.Value) + if a.Kind != driver.Create && mf != "" { + return nil, fmt.Errorf("missing key field %q", mf) + } + var newPartitionKey string + if mf == c.partitionKey { + newPartitionKey = driver.UniqueString() + avm.Value[c.partitionKey] = &dyn2Types.AttributeValueMemberS{Value: newPartitionKey} + } + if c.sortKey != "" && mf == c.sortKey { + // It doesn't make sense to generate a random sort key. + return nil, fmt.Errorf("missing sort key %q", c.sortKey) + } + var rev string + if a.Doc.HasField(c.opts.RevisionField) { + rev = driver.UniqueString() + if avm.Value[c.opts.RevisionField], err = encodeValue(rev); err != nil { + return nil, err + } + } + dput := &dyn2Types.Put{ + TableName: &c.table, + Item: avm.Value, + } + cb, err := c.precondition(a) + if err != nil { + return nil, err + } + if cb != nil { + ce, err := expression.NewBuilder().WithCondition(*cb).Build() + if err != nil { + return nil, err + } + dput.ExpressionAttributeNames = ce.Names() + dput.ExpressionAttributeValues = ce.Values() + dput.ConditionExpression = ce.Condition() + } + return &writeOp{ + action: a, + writeItem: dyn2Types.TransactWriteItem{Put: dput}, + newPartitionKey: newPartitionKey, + newRevision: rev, + run: func(ctx context.Context) error { + return c.runPut(ctx, dput, a, opts) + }, + }, nil +} + +func (c *collection) runPut(ctx context.Context, dput *dyn2Types.Put, a *driver.Action, opts *driver.RunActionsOptions) error { + in := &dyn.PutItemInput{ + TableName: dput.TableName, + Item: dput.Item, + ConditionExpression: dput.ConditionExpression, + ExpressionAttributeNames: dput.ExpressionAttributeNames, + ExpressionAttributeValues: dput.ExpressionAttributeValues, + } + if opts.BeforeDo != nil { + if err := opts.BeforeDo(driver.AsFunc(in)); err != nil { + return err + } + } + _, err := c.db.PutItem(ctx, in) + var ccf *dyn2Types.ConditionalCheckFailedException + if errors.As(err, &ccf) { + if a.Kind == driver.Create { + err = gcerr.Newf(gcerr.AlreadyExists, err, "document already exists") + } + if rev, _ := a.Doc.GetField(c.opts.RevisionField); rev == nil && a.Kind == driver.Replace { + err = gcerr.Newf(gcerr.NotFound, nil, "document not found") + } + } + return err +} + +func (c *collection) newDelete(a *driver.Action, opts *driver.RunActionsOptions) (*writeOp, error) { + av, err := encodeDocKeyFields(a.Doc, c.partitionKey, c.sortKey) + if err != nil { + return nil, err + } + + del := &dyn2Types.Delete{ + TableName: &c.table, + Key: av.Value, + } + cb, err := c.precondition(a) + if err != nil { + return nil, err + } + if cb != nil { + ce, err := expression.NewBuilder().WithCondition(*cb).Build() + if err != nil { + return nil, err + } + del.ExpressionAttributeNames = ce.Names() + del.ExpressionAttributeValues = ce.Values() + del.ConditionExpression = ce.Condition() + } + return &writeOp{ + action: a, + writeItem: dyn2Types.TransactWriteItem{Delete: del}, + run: func(ctx context.Context) error { + in := &dyn.DeleteItemInput{ + TableName: del.TableName, + Key: del.Key, + ConditionExpression: del.ConditionExpression, + ExpressionAttributeNames: del.ExpressionAttributeNames, + ExpressionAttributeValues: del.ExpressionAttributeValues, + } + if opts.BeforeDo != nil { + if err := opts.BeforeDo(driver.AsFunc(in)); err != nil { + return err + } + } + _, err := c.db.DeleteItem(ctx, in) + return err + }, + }, nil +} + +func (c *collection) newUpdate(a *driver.Action, opts *driver.RunActionsOptions) (*writeOp, error) { + av, err := encodeDocKeyFields(a.Doc, c.partitionKey, c.sortKey) + if err != nil { + return nil, err + } + + var ub expression.UpdateBuilder + for _, m := range a.Mods { + // TODO(shantuo): check for invalid field paths + fp := expression.Name(strings.Join(m.FieldPath, ".")) + if inc, ok := m.Value.(driver.IncOp); ok { + ub = ub.Add(fp, expression.Value(inc.Amount)) + } else if m.Value == nil { + ub = ub.Remove(fp) + } else { + ub = ub.Set(fp, expression.Value(m.Value)) + } + } + var rev string + if a.Doc.HasField(c.opts.RevisionField) { + rev = driver.UniqueString() + ub = ub.Set(expression.Name(c.opts.RevisionField), expression.Value(rev)) + } + cb, err := c.precondition(a) + if err != nil { + return nil, err + } + ce, err := expression.NewBuilder().WithCondition(*cb).WithUpdate(ub).Build() + if err != nil { + return nil, err + } + up := &dyn2Types.Update{ + TableName: &c.table, + Key: av.Value, + ConditionExpression: ce.Condition(), + UpdateExpression: ce.Update(), + ExpressionAttributeNames: ce.Names(), + ExpressionAttributeValues: ce.Values(), + } + return &writeOp{ + action: a, + writeItem: dyn2Types.TransactWriteItem{Update: up}, + newRevision: rev, + run: func(ctx context.Context) error { + in := &dyn.UpdateItemInput{ + TableName: up.TableName, + Key: up.Key, + ConditionExpression: up.ConditionExpression, + UpdateExpression: up.UpdateExpression, + ExpressionAttributeNames: up.ExpressionAttributeNames, + ExpressionAttributeValues: up.ExpressionAttributeValues, + } + if opts.BeforeDo != nil { + if err := opts.BeforeDo(driver.AsFunc(in)); err != nil { + return err + } + } + _, err := c.db.UpdateItem(ctx, in) + return err + }, + }, nil +} + +// Handle the effects of successful execution. +func (c *collection) onSuccess(op *writeOp) error { + // Set the new partition key (if any) and the new revision into the user's document. + if op.newPartitionKey != "" { + _ = op.action.Doc.SetField(c.partitionKey, op.newPartitionKey) // cannot fail + } + if op.newRevision != "" { + return op.action.Doc.SetField(c.opts.RevisionField, op.newRevision) + } + return nil +} + +func (c *collection) missingKeyField(m map[string]dyn2Types.AttributeValue) string { + v, ok := m[c.partitionKey] + if !ok { + return c.partitionKey + } + if n, ok := v.(*dyn2Types.AttributeValueMemberNULL); ok && n.Value { + return c.partitionKey + } + + if c.sortKey != "" { + v, ok := m[c.sortKey] + if !ok { + return c.sortKey + } + if n, ok := v.(*dyn2Types.AttributeValueMemberNULL); ok && n.Value { + return c.sortKey + } + } + + return "" +} + +// Construct the precondition for the action. +func (c *collection) precondition(a *driver.Action) (*expression.ConditionBuilder, error) { + switch a.Kind { + case driver.Create: + // Precondition: the document doesn't already exist. (Precisely: the partitionKey + // field is not on the document.) + c := expression.AttributeNotExists(expression.Name(c.partitionKey)) + return &c, nil + case driver.Replace, driver.Update: + // Precondition: the revision matches, or if there is no revision, then + // the document exists. + cb, err := revisionPrecondition(a.Doc, c.opts.RevisionField) + if err != nil { + return nil, err + } + if cb == nil { + c := expression.AttributeExists(expression.Name(c.partitionKey)) + cb = &c + } + return cb, nil + case driver.Put, driver.Delete: + // Precondition: the revision matches, if any. + return revisionPrecondition(a.Doc, c.opts.RevisionField) + case driver.Get: + // No preconditions on a Get. + return nil, nil + default: + panic("bad action kind") + } +} + +// revisionPrecondition returns a DynamoDB expression that asserts that the +// stored document's revision matches the revision of doc. +func revisionPrecondition(doc driver.Document, revField string) (*expression.ConditionBuilder, error) { + v, err := doc.GetField(revField) + if err != nil { // field not present + return nil, nil + } + if v == nil { // field is present, but nil + return nil, nil + } + rev, ok := v.(string) + if !ok { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, + "%s field contains wrong type: got %T, want string", + revField, v) + } + if rev == "" { + return nil, nil + } + // Value encodes rev to an attribute value. + cb := expression.Name(revField).Equal(expression.Value(rev)) + return &cb, nil +} + +// transactWrite executes the write actions atomically: either they all succeed or they all fail together. +func (c *collection) transactWrite(ctx context.Context, actions []*driver.Action, errs []error, opts *driver.RunActionsOptions) { + if len(actions) == 0 { + return + } + // all actions will fail atomically even if a single action fails + setErr := func(err error) { + for _, a := range actions { + errs[a.Index] = err + } + } + + tws := make([]dyn2Types.TransactWriteItem, 0, len(actions)) + var ops []*writeOp + for _, w := range actions { + op, err := c.newWriteOp(w, opts) + if err != nil { + setErr(err) + return + } else { + ops = append(ops, op) + tws = append(tws, op.writeItem) + } + } + + in := &dyn.TransactWriteItemsInput{ + ClientRequestToken: aws.String(driver.UniqueString()), + TransactItems: tws, + } + + if opts.BeforeDo != nil { + asFunc := func(i interface{}) bool { + p, ok := i.(**dyn.TransactWriteItemsInput) + if !ok { + return false + } + *p = in + return true + } + if err := opts.BeforeDo(asFunc); err != nil { + setErr(err) + return + } + } + if _, err := c.db.TransactWriteItems(ctx, in); err != nil { + setErr(err) + return + } + for _, op := range ops { + errs[op.action.Index] = c.onSuccess(op) + } +} + +// RevisionToBytes implements driver.RevisionToBytes. +func (c *collection) RevisionToBytes(rev interface{}) ([]byte, error) { + s, ok := rev.(string) + if !ok { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "revision %v of type %[1]T is not a string", rev) + } + return []byte(s), nil +} + +// BytesToRevision implements driver.BytesToRevision. +func (c *collection) BytesToRevision(b []byte) (interface{}, error) { + return string(b), nil +} + +func (c *collection) As(i interface{}) bool { + p, ok := i.(**dyn.Client) + if !ok { + return false + } + *p = c.db + return true +} + +// ErrorAs implements driver.Collection.ErrorAs. +func (c *collection) ErrorAs(err error, i interface{}) bool { + e, ok := err.(*smithy.OperationError) + if !ok { + return false + } + p, ok := i.(*smithy.OperationError) + if !ok { + return false + } + *p = *e + return true +} + +func (c *collection) ErrorCode(err error) gcerrors.ErrorCode { + + var ( + conditionalCheckFailedException *dyn2Types.ConditionalCheckFailedException + idempotentParameterMismatchException *dyn2Types.IdempotentParameterMismatchException + internalServerError *dyn2Types.InternalServerError + itemCollectionSizeLimitExceededException *dyn2Types.ItemCollectionSizeLimitExceededException + provisionedThroughputExceededException *dyn2Types.ProvisionedThroughputExceededException + requestLimitExceeded *dyn2Types.RequestLimitExceeded + resourceNotFoundException *dyn2Types.ResourceNotFoundException + transactionCanceledException *dyn2Types.TransactionCanceledException + transactionConflictException *dyn2Types.TransactionConflictException + transactionInProgressException *dyn2Types.TransactionInProgressException + ) + + switch { + case errors.As(err, &conditionalCheckFailedException): + return gcerrors.FailedPrecondition + case errors.As(err, &idempotentParameterMismatchException): + return gcerrors.InvalidArgument + case errors.As(err, &internalServerError): + return gcerrors.Internal + case errors.As(err, &itemCollectionSizeLimitExceededException): + return gcerrors.ResourceExhausted + case errors.As(err, &provisionedThroughputExceededException): + return gcerrors.ResourceExhausted + case errors.As(err, &requestLimitExceeded): + return gcerrors.ResourceExhausted + case errors.As(err, &resourceNotFoundException): + return gcerrors.NotFound + case errors.As(err, &transactionCanceledException): + return gcerrors.FailedPrecondition + case errors.As(err, &transactionConflictException): + return gcerrors.Internal + case errors.As(err, &transactionInProgressException): + return gcerrors.InvalidArgument + } + + for k, errCode := range errorCodeMap { + if strings.Contains(err.Error(), k) { + return errCode + } + } + + return gcerrors.Unknown +} + +var errorCodeMap = map[string]gcerrors.ErrorCode{ + // handled by type above + // "ConditionalCheckFailedException": gcerrors.FailedPrecondition, + // "IdempotentParameterMismatchException": gcerrors.InvalidArgument, + // "InternalServerErrorException": gcerrors.Internal, + // "ItemCollectionSizeLimitExceededException": gcerrors.ResourceExhausted, + // "ProvisionedThroughputExceededException": gcerrors.ResourceExhausted, + // "RequestLimitExceededException": gcerrors.ResourceExhausted, + // "ResourceNotFoundException": gcerrors.NotFound, + // "TransactionCanceledException": gcerrors.FailedPrecondition, + // "TransactionConflictException": gcerrors.Internal, + // "TransactionInProgressException": gcerrors.InvalidArgument, + + // V2 doesn't have a type for this, inspect message instead + "ValidationException": gcerrors.InvalidArgument, +} + +// Close implements driver.Collection.Close. +func (c *collection) Close() error { return nil } diff --git a/go-cloud/docstore/awsdynamodb/v2/dynamo_test.go b/go-cloud/docstore/awsdynamodb/v2/dynamo_test.go new file mode 100644 index 000000000..add3d306e --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/dynamo_test.go @@ -0,0 +1,238 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "context" + "errors" + "fmt" + "io" + "testing" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + dyn "github.com/aws/aws-sdk-go-v2/service/dynamodb" + "github.com/aws/smithy-go" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" +) + +// To create the tables and indexes needed for these tests, run create_tables.sh in +// this directory. +// +// The docstore-test-2 table is set up to work with queries on the drivertest.HighScore +// struct like so: +// table: "Game" partition key, "Player" sort key +// local index: "Game" partition key, "Score" sort key +// global index: "Player" partition key, "Time" sort key +// The conformance test queries should exercise all of these. +// +// The docstore-test-3 table is used for running benchmarks only. To eliminate +// the effect of dynamo auto-scaling, run: +// aws dynamodb update-table --table-name docstore-test-3 \ +// --provisioned-throughput ReadCapacityUnits=1000,WriteCapacityUnits=1000 +// Don't forget to change it back when done benchmarking. + +const ( + region = "us-east-2" + collectionName1 = "docstore-test-1" + collectionName2 = "docstore-test-2" + collectionName3 = "docstore-test-3" // for benchmark +) + +type harness struct { + sess aws.Config + closer func() +} + +func (h *harness) SupportsAtomicWrites() bool { + return true +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + // Many POST requests for DynamoDB are JSON maps, and they come in randomized + // key order, so strict matching doesn't work. We disable it and count on ordering + // and header matching. + scrubBody := true + sess, _, done, state := setup.NewAWSv2Config(ctx, t, region, scrubBody) + drivertest.MakeUniqueStringDeterministicForTesting(state) + return &harness{sess: sess, closer: done}, nil +} + +func (*harness) BeforeDoTypes() []interface{} { + return []interface{}{ + &dyn.BatchGetItemInput{}, &dyn.TransactWriteItemsInput{}, + &dyn.PutItemInput{}, &dyn.DeleteItemInput{}, &dyn.UpdateItemInput{}, + } +} + +func (*harness) BeforeQueryTypes() []interface{} { + return []interface{}{&dyn.QueryInput{}, &dyn.ScanInput{}} +} + +func (*harness) RevisionsEqual(rev1, rev2 interface{}) bool { + return rev1 == rev2 +} + +func (h *harness) Close() { + h.closer() +} + +func (h *harness) MakeCollection(_ context.Context, kind drivertest.CollectionKind) (driver.Collection, error) { + switch kind { + case drivertest.SingleKey, drivertest.NoRev: + return newCollection(dyn.NewFromConfig(h.sess), collectionName1, drivertest.KeyField, "", &Options{ + AllowScans: true, + ConsistentRead: true, + }) + case drivertest.TwoKey: + // For query test we don't use strong consistency mode since some tests are + // running on global secondary index and it doesn't support ConsistentRead. + return newCollection(dyn.NewFromConfig(h.sess), collectionName2, "Game", "Player", &Options{ + AllowScans: true, + RunQueryFallback: InMemorySortFallback(func() interface{} { return new(drivertest.HighScore) }), + }) + case drivertest.AltRev: + return newCollection(dyn.NewFromConfig(h.sess), collectionName1, drivertest.KeyField, "", + &Options{ + AllowScans: true, + RevisionField: drivertest.AlternateRevisionField, + ConsistentRead: true, + }) + default: + panic("bad kind") + } +} + +func collectHighScores(ctx context.Context, iter driver.DocumentIterator) ([]*drivertest.HighScore, error) { + var hs []*drivertest.HighScore + for { + var h drivertest.HighScore + doc := drivertest.MustDocument(&h) + err := iter.Next(ctx, doc) + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + hs = append(hs, &h) + } + return hs, nil +} + +type highScoreSliceIterator struct { + hs []*drivertest.HighScore + next int +} + +func (it *highScoreSliceIterator) Next(ctx context.Context, doc driver.Document) error { + if it.next >= len(it.hs) { + return io.EOF + } + dest, ok := doc.Origin.(*drivertest.HighScore) + if !ok { + return fmt.Errorf("doc is %T, not HighScore", doc.Origin) + } + *dest = *it.hs[it.next] + it.next++ + return nil +} + +func (*highScoreSliceIterator) Stop() {} +func (*highScoreSliceIterator) As(interface{}) bool { return false } + +type verifyAs struct{} + +func (verifyAs) Name() string { + return "verify As" +} + +func (verifyAs) CollectionCheck(coll *docstore.Collection) error { + var db *dyn.Client + if !coll.As(&db) { + return errors.New("Collection.As failed") + } + return nil +} + +func (verifyAs) QueryCheck(it *docstore.DocumentIterator) error { + var so *dyn.ScanOutput + var qo *dyn.QueryOutput + if !it.As(&so) && !it.As(&qo) { + return errors.New("DocumentIterator.As failed") + } + return nil +} + +func (v verifyAs) ErrorCheck(k *docstore.Collection, err error) error { + var e smithy.OperationError + if !k.ErrorAs(err, &e) { + return errors.New("Collection.ErrorAs failed") + } + return nil +} + +func TestConformance(t *testing.T) { + // Note: when running -record repeatedly in a short time period, change the argument + // in the call below to generate unique transaction tokens. + drivertest.MakeUniqueStringDeterministicForTesting(1) + drivertest.RunConformanceTests(t, newHarness, &codecTester{}, []drivertest.AsTest{verifyAs{}}) +} + +func BenchmarkConformance(b *testing.B) { + cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion(region)) + if err != nil { + b.Fatal("Error loading AWS config for benchmark: ", err) + } + coll, err := newCollection(dyn.NewFromConfig(cfg), collectionName3, drivertest.KeyField, "", &Options{AllowScans: true}) + if err != nil { + b.Fatal(err) + } + drivertest.RunBenchmarks(b, docstore.NewCollection(coll)) +} + +// awsdynamodb-specific tests. + +func TestQueryErrors(t *testing.T) { + // Verify that bad queries return the right errors. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + dc, err := h.MakeCollection(ctx, drivertest.TwoKey) + if err != nil { + t.Fatal(err) + } + coll := docstore.NewCollection(dc) + defer coll.Close() + + // Here we are comparing a key field with the wrong type. DynamoDB cares about this + // because even though it's a document store and hence schemaless, the key fields + // do have a schema (that is, they have known, fixed types). + iter := coll.Query().Where("Game", "=", 1).Get(ctx) + defer iter.Stop() + err = iter.Next(ctx, &h) + if c := gcerrors.Code(err); c != gcerrors.InvalidArgument { + t.Errorf("got %v (code %s, type %T), want InvalidArgument", err, c, err) + } +} diff --git a/go-cloud/docstore/awsdynamodb/v2/example_test.go b/go-cloud/docstore/awsdynamodb/v2/example_test.go new file mode 100644 index 000000000..e7d353e13 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/example_test.go @@ -0,0 +1,53 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb_test + +import ( + "context" + "log" + + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/dynamodb" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + awsdynamodb "github.com/DataDog/iceberg-go/go-cloud/docstore/awsdynamodb/v2" +) + +func ExampleOpenCollection() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + log.Fatal(err) + } + coll, err := awsdynamodb.OpenCollection( + dynamodb.NewFromConfig(cfg), "docstore-test", "partitionKeyField", "", nil) + if err != nil { + log.Fatal(err) + } + defer coll.Close() +} + +func Example_openCollectionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/docstore/awsdynamodb" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // docstore.OpenCollection creates a *docstore.Collection from a URL. + coll, err := docstore.OpenCollection(ctx, "dynamodb://my-table?partition_key=name") + if err != nil { + log.Fatal(err) + } + defer coll.Close() +} diff --git a/go-cloud/docstore/awsdynamodb/v2/query.go b/go-cloud/docstore/awsdynamodb/v2/query.go new file mode 100644 index 000000000..314a5149e --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/query.go @@ -0,0 +1,687 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "reflect" + "sort" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression" + dyn "github.com/aws/aws-sdk-go-v2/service/dynamodb" + dyn2Types "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +// TODO: support parallel scans (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.ParallelScan) + +// TODO(jba): support an empty item slice returned from an RPC: "A Query operation can +// return an empty result set and a LastEvaluatedKey if all the items read for the +// page of results are filtered out." + +type avmap = map[string]dyn2Types.AttributeValue + +func (c *collection) RunGetQuery(ctx context.Context, q *driver.Query) (driver.DocumentIterator, error) { + qr, err := c.planQuery(q) + if err != nil { + if gcerrors.Code(err) == gcerrors.Unimplemented && c.opts.RunQueryFallback != nil { + return c.opts.RunQueryFallback(ctx, q, c.RunGetQuery) + } + return nil, err + } + if err := c.checkPlan(qr); err != nil { + return nil, err + } + it := &documentIterator{ + qr: qr, + offset: q.Offset, + limit: q.Limit, + count: 0, // manually count limit since dynamodb uses "limit" as scan limit before filtering + } + it.items, it.last, it.asFunc, err = it.qr.run(ctx, nil) + if err != nil { + return nil, err + } + return it, nil +} + +func (c *collection) checkPlan(qr *queryRunner) error { + if qr.scanIn != nil && qr.scanIn.FilterExpression != nil && !c.opts.AllowScans { + return gcerr.Newf(gcerr.InvalidArgument, nil, "query requires a table scan; set Options.AllowScans to true to enable") + } + return nil +} + +func (c *collection) planQuery(q *driver.Query) (*queryRunner, error) { + var cb expression.Builder + cbUsed := false // It's an error to build an empty Builder. + // Set up the projection expression. + if len(q.FieldPaths) > 0 { + var pb expression.ProjectionBuilder + hasFields := map[string]bool{} + for _, fp := range q.FieldPaths { + if len(fp) == 1 { + hasFields[fp[0]] = true + } + pb = pb.AddNames(expression.Name(strings.Join(fp, "."))) + } + // Always include the keys. + for _, f := range []string{c.partitionKey, c.sortKey} { + if f != "" && !hasFields[f] { + pb = pb.AddNames(expression.Name(f)) + q.FieldPaths = append(q.FieldPaths, []string{f}) + } + } + cb = cb.WithProjection(pb) + cbUsed = true + } + + // Find the best thing to query (table or index). + indexName, pkey, skey := c.bestQueryable(q) + if indexName == nil && pkey == "" { + // No query can be done: fall back to scanning. + if q.OrderByField != "" { + // Scans are unordered, so we can't run this query. + // TODO(jba): If the user specifies all the partition keys, and there is a global + // secondary index whose sort key is the order-by field, then we can query that index + // for every value of the partition key and merge the results. + // TODO(jba): If the query has a reasonable limit N, then we can run a scan and keep + // the top N documents in memory. + return nil, gcerr.Newf(gcerr.Unimplemented, nil, "query requires a table scan, but has an ordering requirement; add an index or provide Options.RunQueryFallback") + } + if len(q.Filters) > 0 { + cb = cb.WithFilter(filtersToConditionBuilder(q.Filters)) + cbUsed = true + } + in := &dyn.ScanInput{ + TableName: &c.table, + ConsistentRead: aws.Bool(c.opts.ConsistentRead), + } + if cbUsed { + ce, err := cb.Build() + if err != nil { + return nil, err + } + in.ExpressionAttributeNames = ce.Names() + in.ExpressionAttributeValues = ce.Values() + in.FilterExpression = ce.Filter() + in.ProjectionExpression = ce.Projection() + } + return &queryRunner{c: c, scanIn: in, beforeRun: q.BeforeQuery}, nil + } + + // Do a query. + cb = processFilters(cb, q.Filters, pkey, skey) + ce, err := cb.Build() + if err != nil { + return nil, err + } + qIn := &dyn.QueryInput{ + TableName: &c.table, + IndexName: indexName, + ExpressionAttributeNames: ce.Names(), + ExpressionAttributeValues: ce.Values(), + KeyConditionExpression: ce.KeyCondition(), + FilterExpression: ce.Filter(), + ProjectionExpression: ce.Projection(), + ConsistentRead: aws.Bool(c.opts.ConsistentRead), + } + if q.OrderByField != "" && !q.OrderAscending { + qIn.ScanIndexForward = &q.OrderAscending + } + return &queryRunner{ + c: c, + queryIn: qIn, + beforeRun: q.BeforeQuery, + }, nil +} + +// Return the best choice of queryable (table or index) for this query. +// How to interpret the return values: +// - If indexName is nil but pkey is not empty, then use the table. +// - If all return values are zero, no query will work: do a scan. +func (c *collection) bestQueryable(q *driver.Query) (indexName *string, pkey, skey string) { + // If the query has an "=" filter on the table's partition key, look at the table + // and local indexes. + if hasEqualityFilter(q, c.partitionKey) { + // If the table has a sort key that's in the query, and the ordering + // constraint works with the sort key, use the table. + // (Query results are always ordered by sort key.) + if hasFilter(q, c.sortKey) && orderingConsistent(q, c.sortKey) { + return nil, c.partitionKey, c.sortKey + } + // Look at local indexes. They all have the same partition key as the base table. + // If one has a sort key in the query, use it. + for _, li := range c.description.LocalSecondaryIndexes { + pkey, skey := keyAttributes(li.KeySchema) + if hasFilter(q, skey) && localFieldsIncluded(q, li) && orderingConsistent(q, skey) { + return li.IndexName, pkey, skey + } + } + } + // Consider the global indexes: if one has a matching partition and sort key, and + // the projected fields of the index include those of the query, use it. + for _, gi := range c.description.GlobalSecondaryIndexes { + pkey, skey := keyAttributes(gi.KeySchema) + if skey == "" { + continue // We'll visit global indexes without a sort key later. + } + if hasEqualityFilter(q, pkey) && hasFilter(q, skey) && c.globalFieldsIncluded(q, gi) && orderingConsistent(q, skey) { + return gi.IndexName, pkey, skey + } + } + // There are no matches for both partition and sort key. Now consider matches on partition key only. + // That will still be better than a scan. + // First, check the table itself. + if hasEqualityFilter(q, c.partitionKey) && orderingConsistent(q, c.sortKey) { + return nil, c.partitionKey, c.sortKey + } + // No point checking local indexes: they have the same partition key as the table. + // Check the global indexes. + for _, gi := range c.description.GlobalSecondaryIndexes { + pkey, skey := keyAttributes(gi.KeySchema) + if hasEqualityFilter(q, pkey) && c.globalFieldsIncluded(q, gi) && orderingConsistent(q, skey) { + return gi.IndexName, pkey, skey + } + } + // We cannot do a query. + // TODO: return the reason why we couldn't. At a minimum, distinguish failure due to keys + // from failure due to projection (i.e. a global index had the right partition and sort key, + // but didn't project the necessary fields). + return nil, "", "" +} + +// localFieldsIncluded reports whether a local index supports all the selected fields +// of a query. Since DynamoDB will read explicitly provided fields from the table if +// they are not projected into the index, the only case where a local index cannot +// be used is when the query wants all the fields, and the index projection is not ALL. +// See https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LSI.html#LSI.Projections. +func localFieldsIncluded(q *driver.Query, li dyn2Types.LocalSecondaryIndexDescription) bool { + return len(q.FieldPaths) > 0 || li.Projection.ProjectionType == dyn2Types.ProjectionTypeAll +} + +// orderingConsistent reports whether the ordering constraint is consistent with the sort key field. +// That is, either there is no OrderBy clause, or the clause specifies the sort field. +func orderingConsistent(q *driver.Query, sortField string) bool { + return q.OrderByField == "" || q.OrderByField == sortField +} + +// globalFieldsIncluded reports whether the fields selected by the query are +// projected into (that is, contained directly in) the global index. We need this +// check before using the index, because if a global index doesn't have all the +// desired fields, then a separate RPC for each returned item would be necessary to +// retrieve those fields, and we'd rather scan than do that. +func (c *collection) globalFieldsIncluded(q *driver.Query, gi dyn2Types.GlobalSecondaryIndexDescription) bool { + proj := gi.Projection + if proj.ProjectionType == dyn2Types.ProjectionTypeAll { + // The index has all the fields of the table: we're good. + return true + } + if len(q.FieldPaths) == 0 { + // The query wants all the fields of the table, but we can't be sure that the + // index has them. + return false + } + // The table's keys and the index's keys are always in the index. + pkey, skey := keyAttributes(gi.KeySchema) + indexFields := map[string]bool{c.partitionKey: true, pkey: true} + if c.sortKey != "" { + indexFields[c.sortKey] = true + } + if skey != "" { + indexFields[skey] = true + } + for _, nka := range proj.NonKeyAttributes { + indexFields[nka] = true + } + // Every field path in the query must be in the index. + for _, fp := range q.FieldPaths { + if !indexFields[strings.Join(fp, ".")] { + return false + } + } + return true +} + +// Extract the names of the partition and sort key attributes from the schema of a +// table or index. +func keyAttributes(ks []dyn2Types.KeySchemaElement) (pkey, skey string) { + for _, k := range ks { + switch k.KeyType { + case dyn2Types.KeyTypeHash: + pkey = *k.AttributeName + case dyn2Types.KeyTypeRange: + skey = *k.AttributeName + default: + panic("bad key type: " + k.KeyType) + } + } + return pkey, skey +} + +// Reports whether q has a filter that mentions the top-level field. +func hasFilter(q *driver.Query, field string) bool { + if field == "" { + return false + } + for _, f := range q.Filters { + if driver.FieldPathEqualsField(f.FieldPath, field) { + return true + } + } + return false +} + +// Reports whether q has a filter that checks if the top-level field is equal to something. +func hasEqualityFilter(q *driver.Query, field string) bool { + for _, f := range q.Filters { + if f.Op == driver.EqualOp && driver.FieldPathEqualsField(f.FieldPath, field) { + return true + } + } + return false +} + +type queryRunner struct { + c *collection + scanIn *dyn.ScanInput + queryIn *dyn.QueryInput + beforeRun func(asFunc func(i interface{}) bool) error +} + +func (qr *queryRunner) run(ctx context.Context, startAfter avmap) (items []avmap, last avmap, asFunc func(i interface{}) bool, err error) { + if qr.scanIn != nil { + qr.scanIn.ExclusiveStartKey = startAfter + if qr.beforeRun != nil { + asFunc := func(i interface{}) bool { + p, ok := i.(**dyn.ScanInput) + if !ok { + return false + } + *p = qr.scanIn + return true + } + if err := qr.beforeRun(asFunc); err != nil { + return nil, nil, nil, err + } + } + out, err := qr.c.db.Scan(ctx, qr.scanIn) + if err != nil { + return nil, nil, nil, err + } + return out.Items, out.LastEvaluatedKey, + func(i interface{}) bool { + p, ok := i.(**dyn.ScanOutput) + if !ok { + return false + } + *p = out + return true + }, nil + } + qr.queryIn.ExclusiveStartKey = startAfter + if qr.beforeRun != nil { + asFunc := func(i interface{}) bool { + p, ok := i.(**dyn.QueryInput) + if !ok { + return false + } + *p = qr.queryIn + return true + } + if err := qr.beforeRun(asFunc); err != nil { + return nil, nil, nil, err + } + } + out, err := qr.c.db.Query(ctx, qr.queryIn) + if err != nil { + return nil, nil, nil, err + } + return out.Items, out.LastEvaluatedKey, + func(i interface{}) bool { + p, ok := i.(**dyn.QueryOutput) + if !ok { + return false + } + *p = out + return true + }, nil +} + +func processFilters(cb expression.Builder, fs []driver.Filter, pkey, skey string) expression.Builder { + var kbs []expression.KeyConditionBuilder + var cfs []driver.Filter + for _, f := range fs { + if kb, ok := toKeyCondition(f, pkey, skey); ok { + kbs = append(kbs, kb) + continue + } + cfs = append(cfs, f) + } + keyBuilder := kbs[0] + for i := 1; i < len(kbs); i++ { + keyBuilder = keyBuilder.And(kbs[i]) + } + cb = cb.WithKeyCondition(keyBuilder) + if len(cfs) > 0 { + cb = cb.WithFilter(filtersToConditionBuilder(cfs)) + } + return cb +} + +func filtersToConditionBuilder(fs []driver.Filter) expression.ConditionBuilder { + if len(fs) == 0 { + panic("no filters") + } + var cb expression.ConditionBuilder + cb = toFilter(fs[0]) + for _, f := range fs[1:] { + cb = cb.And(toFilter(f)) + } + return cb +} + +func toKeyCondition(f driver.Filter, pkey, skey string) (expression.KeyConditionBuilder, bool) { + kp := strings.Join(f.FieldPath, ".") + if kp == pkey || kp == skey { + key := expression.Key(kp) + val := expression.Value(f.Value) + switch f.Op { + case "<": + return expression.KeyLessThan(key, val), true + case "<=": + return expression.KeyLessThanEqual(key, val), true + case driver.EqualOp: + return expression.KeyEqual(key, val), true + case ">=": + return expression.KeyGreaterThanEqual(key, val), true + case ">": + return expression.KeyGreaterThan(key, val), true + default: + panic(fmt.Sprint("invalid filter operation:", f.Op)) + } + } + return expression.KeyConditionBuilder{}, false +} + +func toFilter(f driver.Filter) expression.ConditionBuilder { + name := expression.Name(strings.Join(f.FieldPath, ".")) + val := expression.Value(f.Value) + switch f.Op { + case "<": + return expression.LessThan(name, val) + case "<=": + return expression.LessThanEqual(name, val) + case driver.EqualOp: + return expression.Equal(name, val) + case ">=": + return expression.GreaterThanEqual(name, val) + case ">": + return expression.GreaterThan(name, val) + case "in": + return toInCondition(f) + case "not-in": + return expression.Not(toInCondition(f)) + default: + panic(fmt.Sprint("invalid filter operation:", f.Op)) + } +} + +func toInCondition(f driver.Filter) expression.ConditionBuilder { + name := expression.Name(strings.Join(f.FieldPath, ".")) + vslice := reflect.ValueOf(f.Value) + right := expression.Value(vslice.Index(0).Interface()) + other := make([]expression.OperandBuilder, vslice.Len()-1) + for i := 1; i < vslice.Len(); i++ { + other[i-1] = expression.Value(vslice.Index(i).Interface()) + } + return expression.In(name, right, other...) +} + +type documentIterator struct { + qr *queryRunner // the query runner + items []map[string]dyn2Types.AttributeValue // items from the last query + curr int // index of the current item in items + offset int // number of items to skip + limit int // number of items to return + count int // number of items returned + last map[string]dyn2Types.AttributeValue // lastEvaluatedKey from the last query + asFunc func(i interface{}) bool // for As +} + +func (it *documentIterator) Next(ctx context.Context, doc driver.Document) error { + // Skip the first 'n' documents where 'n' is the offset. + for it.count < it.offset { + if err := it.next(ctx, doc, false); err != nil { + return err + } + } + return it.next(ctx, doc, true) +} + +func (it *documentIterator) next(ctx context.Context, doc driver.Document, decode bool) error { + // Only start counting towards the limit after the offset has been reached. + if it.limit > 0 && it.count >= it.offset+it.limit { + return io.EOF + } + // it.items can be empty after a call to it.qr.run, but unless it.last is nil there may be more items. + for it.curr >= len(it.items) { + // Make a new query request at the end of this page. + if it.last == nil { + return io.EOF + } + var err error + it.items, it.last, it.asFunc, err = it.qr.run(ctx, it.last) + if err != nil { + return err + } + it.curr = 0 + } + if decode { + if err := decodeDoc(&dyn2Types.AttributeValueMemberM{Value: it.items[it.curr]}, doc); err != nil { + return err + } + } + it.curr++ + it.count++ + return nil +} + +func (it *documentIterator) Stop() { + it.items = nil + it.last = nil +} + +func (it *documentIterator) As(i interface{}) bool { + return it.asFunc(i) +} + +func (c *collection) QueryPlan(q *driver.Query) (string, error) { + qr, err := c.planQuery(q) + if err != nil { + return "", err + } + return qr.queryPlan(), nil +} + +func (qr *queryRunner) queryPlan() string { + if qr.scanIn != nil { + return "Scan" + } + if qr.queryIn.IndexName != nil { + return fmt.Sprintf("Index: %q", *qr.queryIn.IndexName) + } + return "Table" +} + +// InMemorySortFallback returns a query fallback function for Options.RunQueryFallback. +// The function accepts a query with an OrderBy clause. It runs the query without that clause, +// reading all documents into memory, then sorts the documents according to the OrderBy clause. +// +// Only string, numeric, time and binary ([]byte) fields can be sorted. +// +// createDocument should create an empty document to be passed to DocumentIterator.Next. +// The DocumentIterator returned by the FallbackFunc will also expect the same type of document. +// If nil, then a map[string]interface{} will be used. +func InMemorySortFallback(createDocument func() interface{}) FallbackFunc { + if createDocument == nil { + createDocument = func() interface{} { return map[string]interface{}{} } + } + return func(ctx context.Context, q *driver.Query, run RunQueryFunc) (driver.DocumentIterator, error) { + if q.OrderByField == "" { + return nil, errors.New("InMemorySortFallback expects an OrderBy query") + } + // Run the query without the OrderBy. + orderByField := q.OrderByField + q.OrderByField = "" + iter, err := run(ctx, q) + if err != nil { + return nil, err + } + defer iter.Stop() + // Collect the results into a slice. + var docs []driver.Document + for { + doc, err := driver.NewDocument(createDocument()) + if err != nil { + return nil, err + } + err = iter.Next(ctx, doc) + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + docs = append(docs, doc) + } + // Sort the documents. + // OrderByField is a single field, not a field path. + // First, put the field values in another slice, so we can + // return on error. + sortValues := make([]interface{}, len(docs)) + for i, doc := range docs { + v, err := doc.GetField(orderByField) + if err != nil { + return nil, err + } + sortValues[i] = v + } + sort.Sort(docsForSorting{docs, sortValues, q.OrderAscending}) + return &sliceIterator{docs: docs}, nil + } +} + +type docsForSorting struct { + docs []driver.Document + vals []interface{} + ascending bool +} + +func (d docsForSorting) Len() int { return len(d.docs) } + +func (d docsForSorting) Swap(i, j int) { + d.docs[i], d.docs[j] = d.docs[j], d.docs[i] + d.vals[i], d.vals[j] = d.vals[j], d.vals[i] +} + +func (d docsForSorting) Less(i, j int) bool { + c := compare(d.vals[i], d.vals[j]) + if d.ascending { + return c < 0 + } + return c > 0 +} + +// compare returns -1 if v1 < v2, 0 if v1 == v2 and 1 if v1 > v2. +// +// Arbitrarily decide that strings < times < []byte < numbers. +// TODO(jba): find and use the actual sort order that DynamoDB uses. +func compare(v1, v2 interface{}) int { + switch v1 := v1.(type) { + case string: + if v2, ok := v2.(string); ok { + return strings.Compare(v1, v2) + } + return -1 + + case time.Time: + if v2, ok := v2.(time.Time); ok { + return driver.CompareTimes(v1, v2) + } + if _, ok := v2.(string); ok { + return 1 + } + return -1 + + case []byte: + if v2, ok := v2.([]byte); ok { + return bytes.Compare(v1, v2) + } + if _, ok := v2.(string); ok { + return 1 + } + if _, ok := v2.(time.Time); ok { + return 1 + } + return -1 + + default: + cmp, err := driver.CompareNumbers(v1, v2) + if err != nil { + return -1 + } + return cmp + } +} + +type sliceIterator struct { + docs []driver.Document + next int +} + +func (it *sliceIterator) Next(ctx context.Context, doc driver.Document) error { + if it.next >= len(it.docs) { + return io.EOF + } + it.next++ + return copyTopLevel(doc, it.docs[it.next-1]) +} + +// Copy the top-level fields of src into dest. +func copyTopLevel(dest, src driver.Document) error { + for _, f := range src.FieldNames() { + v, err := src.GetField(f) + if err != nil { + return err + } + if err := dest.SetField(f, v); err != nil { + return err + } + } + return nil +} + +func (*sliceIterator) Stop() {} +func (*sliceIterator) As(interface{}) bool { return false } diff --git a/go-cloud/docstore/awsdynamodb/v2/query_test.go b/go-cloud/docstore/awsdynamodb/v2/query_test.go new file mode 100644 index 000000000..30591ceba --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/query_test.go @@ -0,0 +1,684 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "context" + "errors" + "fmt" + "strings" + "testing" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + dyn "github.com/aws/aws-sdk-go-v2/service/dynamodb" + dyn2Types "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" +) + +func TestPlanQuery(t *testing.T) { + c := &collection{ + table: "T", + partitionKey: "tableP", + description: &dyn2Types.TableDescription{}, + opts: &Options{AllowScans: true, RevisionField: "rev"}, + } + + // Build an ExpressionAttributeNames map with the given names. + eans := func(names ...string) map[string]string { + m := map[string]string{} + for i, n := range names { + m[fmt.Sprintf("#%d", i)] = n + } + return m + } + + // Build an ExpressionAttributeValues map. Filter values are always the number 1 + // and the keys are always :0, :1, ..., so we only need to know how many entries. + eavs := func(n int) map[string]dyn2Types.AttributeValue { + if n == 0 { + return nil + } + one := &dyn2Types.AttributeValueMemberN{Value: "1"} + m := map[string]dyn2Types.AttributeValue{} + for i := 0; i < n; i++ { + m[fmt.Sprintf(":%d", i)] = one + } + return m + } + + // Ignores the ConsistentRead field from both QueryInput and ScanInput. + opts := []cmp.Option{ + cmpopts.IgnoreFields(dyn.ScanInput{}, "ConsistentRead"), + cmpopts.IgnoreFields(dyn.QueryInput{}, "ConsistentRead"), + cmpopts.IgnoreUnexported(dyn.ScanInput{}), + cmpopts.IgnoreUnexported(dyn.QueryInput{}), + compareIgnoreAttributeUnexported, + } + + for _, test := range []struct { + desc string + // In all cases, the table has a partition key called "tableP". + tableSortKey string // if non-empty, the table sort key + localIndexSortKey string // if non-empty, there is a local index with this sort key + localIndexFields []string // the fields projected into the local index + globalIndexPartitionKey string // if non-empty, there is a global index with this partition key + globalIndexSortKey string // if non-empty, the global index has this sort key + globalIndexFields []string // the fields projected into the global index + query *driver.Query + want interface{} // either a ScanInput or a QueryInput + wantPlan string + }{ + { + desc: "empty query", + // A query with no filters requires a scan. + query: &driver.Query{}, + want: &dyn.ScanInput{TableName: &c.table}, + wantPlan: "Scan", + }, + { + desc: "equality filter on table partition field", + // A filter that compares the table's partition key for equality is the minimum + // requirement for querying the table. + query: &driver.Query{Filters: []driver.Filter{{[]string{"tableP"}, "=", 1}}}, + want: &dyn.QueryInput{ + KeyConditionExpression: aws.String("#0 = :0"), + ExpressionAttributeNames: eans("tableP"), + ExpressionAttributeValues: eavs(1), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on table partition field (sort key)", + // Same as above, but the table has a sort key; shouldn't make a difference. + tableSortKey: "tableS", + query: &driver.Query{Filters: []driver.Filter{{[]string{"tableP"}, "=", 1}}}, + want: &dyn.QueryInput{ + KeyConditionExpression: aws.String("#0 = :0"), + ExpressionAttributeNames: eans("tableP"), + ExpressionAttributeValues: eavs(1), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on other field", + // This query has an equality filter, but not on the table's partition key. + // Since there are no matching indexes, we must scan. + query: &driver.Query{Filters: []driver.Filter{{[]string{"other"}, "=", 1}}}, + want: &dyn.ScanInput{ + FilterExpression: aws.String("#0 = :0"), + ExpressionAttributeNames: eans("other"), + ExpressionAttributeValues: eavs(1), + }, + wantPlan: "Scan", + }, + { + desc: "non-equality filter on table partition field", + // If the query doesn't have an equality filter on the partition key, and there + // are no indexes, we must scan. The filter becomes a FilterExpression, evaluated + // on the backend. + query: &driver.Query{Filters: []driver.Filter{{[]string{"tableP"}, ">", 1}}}, + want: &dyn.ScanInput{ + FilterExpression: aws.String("#0 > :0"), + ExpressionAttributeNames: eans("tableP"), + ExpressionAttributeValues: eavs(1), + }, + wantPlan: "Scan", + }, + { + desc: "equality filter on partition, filter on other", + // The equality filter on the table's partition key lets us query the table. + // The other filter is used in the filter expression. + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"other"}, "<=", 1}, + }}, + want: &dyn.QueryInput{ + KeyConditionExpression: aws.String("#1 = :1"), + FilterExpression: aws.String("#0 <= :0"), + ExpressionAttributeNames: eans("other", "tableP"), + ExpressionAttributeValues: eavs(2), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on partition, filter on sort", + // If the table has a sort key and the query has a filter on it as well + // as an equality filter on the table's partition key, we can query the + // table. + tableSortKey: "tableS", + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"tableS"}, "<=", 1}, + }}, + want: &dyn.QueryInput{ + KeyConditionExpression: aws.String("(#0 = :0) AND (#1 <= :1)"), + ExpressionAttributeNames: eans("tableP", "tableS"), + ExpressionAttributeValues: eavs(2), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on table partition, filter on local index sort", + // The equality filter on the table's partition key allows us to query + // the table, but there is a better choice: a local index with a sort key + // that is mentioned in the query. + localIndexSortKey: "localS", + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"localS"}, "<=", 1}, + }}, + want: &dyn.QueryInput{ + IndexName: aws.String("local"), + KeyConditionExpression: aws.String("(#0 = :0) AND (#1 <= :1)"), + ExpressionAttributeNames: eans("tableP", "localS"), + }, + wantPlan: `Index: "local"`, + }, + { + desc: "equality filter on table partition, filter on local index sort, bad projection", + // The equality filter on the table's partition key allows us to query + // the table. There seems to be a better choice: a local index with a sort key + // that is mentioned in the query. But the query wants the entire document, + // and the local index only has some fields. + localIndexSortKey: "localS", + localIndexFields: []string{}, // keys only + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"localS"}, "<=", 1}, + }}, + want: &dyn.QueryInput{ + KeyConditionExpression: aws.String("#1 = :1"), + FilterExpression: aws.String("#0 <= :0"), + ExpressionAttributeNames: eans("localS", "tableP"), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on table partition, filter on local index sort, good projection", + // Same as above, but now the query no longer asks for all fields, so + // we will only read the requested fields from the table. + localIndexSortKey: "localS", + localIndexFields: []string{}, // keys only + query: &driver.Query{ + FieldPaths: [][]string{{"tableP"}, {"localS"}}, + Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"localS"}, "<=", 1}, + }, + }, + want: &dyn.QueryInput{ + IndexName: aws.String("local"), + KeyConditionExpression: aws.String("(#0 = :0) AND (#1 <= :1)"), + ExpressionAttributeNames: eans("tableP", "localS"), + ExpressionAttributeValues: eavs(2), + ProjectionExpression: aws.String("#0, #1"), + }, + wantPlan: `Index: "local"`, + }, + { + desc: "equality filter on table partition, filters on local index and table sort", + // Given the choice of querying the table or a local index, prefer the table. + tableSortKey: "tableS", + localIndexSortKey: "localS", + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"localS"}, "<=", 1}, + {[]string{"tableS"}, ">", 1}, + }}, + want: &dyn.QueryInput{ + IndexName: nil, + KeyConditionExpression: aws.String("(#1 = :1) AND (#2 > :2)"), + FilterExpression: aws.String("#0 <= :0"), + ExpressionAttributeNames: eans("localS", "tableP", "tableS"), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on other field with index", + // The query is the same as in "equality filter on other field," but now there + // is a global index with that field as partition key, so we can query it. + globalIndexPartitionKey: "other", + query: &driver.Query{Filters: []driver.Filter{{[]string{"other"}, "=", 1}}}, + want: &dyn.QueryInput{ + IndexName: aws.String("global"), + KeyConditionExpression: aws.String("#0 = :0"), + ExpressionAttributeNames: eans("other"), + }, + wantPlan: `Index: "global"`, + }, + { + desc: "equality filter on table partition, filter on global index sort", + // The equality filter on the table's partition key allows us to query + // the table, but there is a better choice: a global index with the same + // partition key and a sort key that is mentioned in the query. + // (In these tests, the global index has all the fields of the table by default.) + globalIndexPartitionKey: "tableP", + globalIndexSortKey: "globalS", + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"globalS"}, "<=", 1}, + }}, + want: &dyn.QueryInput{ + IndexName: aws.String("global"), + KeyConditionExpression: aws.String("(#0 = :0) AND (#1 <= :1)"), + ExpressionAttributeNames: eans("tableP", "globalS"), + }, + wantPlan: `Index: "global"`, + }, + { + desc: "equality filter on table partition, filter on global index sort, bad projection", + // Although there is a global index that matches the filters best, it doesn't + // have the necessary fields. So we query against the table. + // The query does not specify FilterPaths, so it retrieves the entire document. + // globalIndexFields explicitly lists the fields that the global index has. + // Since the global index does not have all the document fields, it can't be used. + globalIndexPartitionKey: "tableP", + globalIndexSortKey: "globalS", + globalIndexFields: []string{"other"}, + query: &driver.Query{Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"globalS"}, "<=", 1}, + }}, + want: &dyn.QueryInput{ + IndexName: nil, + KeyConditionExpression: aws.String("#1 = :1"), + FilterExpression: aws.String("#0 <= :0"), + ExpressionAttributeNames: eans("globalS", "tableP"), + }, + wantPlan: "Table", + }, + { + desc: "equality filter on table partition, filter on global index sort, good projection", + // The global index matches the filters best and has the necessary + // fields. So we query against it. + globalIndexPartitionKey: "tableP", + globalIndexSortKey: "globalS", + globalIndexFields: []string{"other", "rev"}, + query: &driver.Query{ + FieldPaths: [][]string{{"other"}}, + Filters: []driver.Filter{ + {[]string{"tableP"}, "=", 1}, + {[]string{"globalS"}, "<=", 1}, + }, + }, + want: &dyn.QueryInput{ + IndexName: aws.String("global"), + KeyConditionExpression: aws.String("(#0 = :0) AND (#1 <= :1)"), + ProjectionExpression: aws.String("#2, #0"), + ExpressionAttributeNames: eans("tableP", "globalS", "other"), + ExpressionAttributeValues: eavs(2), + }, + wantPlan: `Index: "global"`, + }, + } { + t.Run(test.desc, func(t *testing.T) { + c.sortKey = test.tableSortKey + if test.localIndexSortKey == "" { + c.description.LocalSecondaryIndexes = nil + } else { + c.description.LocalSecondaryIndexes = []dyn2Types.LocalSecondaryIndexDescription{ + { + IndexName: aws.String("local"), + KeySchema: keySchema("tableP", test.localIndexSortKey), + Projection: indexProjection(test.localIndexFields), + }, + } + } + if test.globalIndexPartitionKey == "" { + c.description.GlobalSecondaryIndexes = nil + } else { + c.description.GlobalSecondaryIndexes = []dyn2Types.GlobalSecondaryIndexDescription{ + { + IndexName: aws.String("global"), + KeySchema: keySchema(test.globalIndexPartitionKey, test.globalIndexSortKey), + Projection: indexProjection(test.globalIndexFields), + }, + } + } + gotRunner, err := c.planQuery(test.query) + if err != nil { + t.Fatal(err) + } + var got interface{} + switch tw := test.want.(type) { + case *dyn.ScanInput: + got = gotRunner.scanIn + tw.TableName = &c.table + if tw.ExpressionAttributeValues == nil { + tw.ExpressionAttributeValues = eavs(len(tw.ExpressionAttributeNames)) + } + case *dyn.QueryInput: + got = gotRunner.queryIn + tw.TableName = &c.table + if tw.ExpressionAttributeValues == nil { + tw.ExpressionAttributeValues = eavs(len(tw.ExpressionAttributeNames)) + } + default: + t.Fatalf("bad type for test.want: %T", test.want) + } + if diff := cmp.Diff(got, test.want, opts...); diff != "" { + t.Error("input:\n", diff) + } + gotPlan := gotRunner.queryPlan() + if diff := cmp.Diff(gotPlan, test.wantPlan); diff != "" { + t.Error("plan:\n", diff) + } + }) + } +} + +func TestQueryNoScans(t *testing.T) { + c := &collection{ + table: "T", + partitionKey: "tableP", + description: &dyn2Types.TableDescription{}, + opts: &Options{AllowScans: false}, + } + + for _, test := range []struct { + q *driver.Query + wantErr bool + }{ + {&driver.Query{}, false}, + {&driver.Query{Filters: []driver.Filter{{[]string{"other"}, "=", 1}}}, true}, + } { + qr, err := c.planQuery(test.q) + if err != nil { + t.Fatalf("%v: %v", test.q, err) + } + err = c.checkPlan(qr) + if test.wantErr { + if err == nil || !strings.Contains(err.Error(), "AllowScans") { + t.Errorf("%v: got %v, want an error that mentions the AllowScans option", test.q, err) + } + } else if err != nil { + t.Errorf("%v: got %v, want nil", test.q, err) + } + } +} + +// Make a key schema from the names of the partition and sort keys. +func keySchema(pkey, skey string) []dyn2Types.KeySchemaElement { + return []dyn2Types.KeySchemaElement{ + {AttributeName: &pkey, KeyType: dyn2Types.KeyTypeHash}, + {AttributeName: &skey, KeyType: dyn2Types.KeyTypeRange}, + } +} + +func indexProjection(fields []string) *dyn2Types.Projection { + var ptype dyn2Types.ProjectionType + switch { + case fields == nil: + ptype = dyn2Types.ProjectionTypeAll + case len(fields) == 0: + ptype = dyn2Types.ProjectionTypeKeysOnly + default: + ptype = dyn2Types.ProjectionTypeInclude + } + proj := &dyn2Types.Projection{ProjectionType: ptype} + for _, f := range fields { + f := f + proj.NonKeyAttributes = append(proj.NonKeyAttributes, f) + } + return proj +} + +func TestGlobalFieldsIncluded(t *testing.T) { + c := &collection{partitionKey: "tableP", sortKey: "tableS"} + gi := dyn2Types.GlobalSecondaryIndexDescription{ + KeySchema: keySchema("globalP", "globalS"), + } + for _, test := range []struct { + desc string + queryFields []string + wantKeysOnly bool // when the projection includes only table and index keys + wantInclude bool // when the projection includes fields "f" and "g". + }{ + { + desc: "all", + queryFields: nil, + wantKeysOnly: false, + wantInclude: false, + }, + { + desc: "key fields", + queryFields: []string{"tableS", "globalP"}, + wantKeysOnly: true, + wantInclude: true, + }, + { + desc: "included fields", + queryFields: []string{"f", "g"}, + wantKeysOnly: false, + wantInclude: true, + }, + { + desc: "included and key fields", + queryFields: []string{"f", "g", "tableP", "globalS"}, + wantKeysOnly: false, + wantInclude: true, + }, + { + desc: "not included field", + queryFields: []string{"f", "g", "h"}, + wantKeysOnly: false, + wantInclude: false, + }, + } { + t.Run(test.desc, func(t *testing.T) { + var fps [][]string + for _, qf := range test.queryFields { + fps = append(fps, strings.Split(qf, ".")) + } + q := &driver.Query{FieldPaths: fps} + for _, p := range []struct { + name string + proj *dyn2Types.Projection + want bool + }{ + {"ALL", indexProjection(nil), true}, + {"KEYS_ONLY", indexProjection([]string{}), test.wantKeysOnly}, + {"INCLUDE", indexProjection([]string{"f", "g"}), test.wantInclude}, + } { + t.Run(p.name, func(t *testing.T) { + gi.Projection = p.proj + got := c.globalFieldsIncluded(q, gi) + if got != p.want { + t.Errorf("got %t, want %t", got, p.want) + } + }) + } + }) + } +} + +func TestCompare(t *testing.T) { + tm := time.Now() + for _, test := range []struct { + a, b interface{} + want int + }{ + {1, 1, 0}, + {1, 2, -1}, + {2, 1, 1}, + {1.5, 2, -1}, + {2.5, 2.1, 1}, + {3.8, 3.8, 0}, + {"x", "x", 0}, + {"x", "xx", -1}, + {"x", "a", 1}, + {tm, tm, 0}, + {tm, tm.Add(1), -1}, + {tm, tm.Add(-1), 1}, + {[]byte("x"), []byte("x"), 0}, + {[]byte("x"), []byte("xx"), -1}, + {[]byte("x"), []byte("a"), 1}, + } { + got := compare(test.a, test.b) + if got != test.want { + t.Errorf("compare(%v, %v) = %d, want %d", test.a, test.b, got, test.want) + } + } +} + +func TestCopyTopLevel(t *testing.T) { + type E struct{ C int } + type S struct { + A int + B int + E + } + + s := &S{A: 1, B: 2, E: E{C: 3}} + m := map[string]interface{}{"A": 1, "B": 2, "C": 3} + for _, test := range []struct { + dest, src interface{} + want interface{} + }{ + { + dest: map[string]interface{}{}, + src: m, + want: m, + }, + { + dest: &S{}, + src: s, + want: s, + }, + { + dest: map[string]interface{}{}, + src: s, + want: m, + }, + { + dest: &S{}, + src: m, + want: s, + }, + } { + dest := drivertest.MustDocument(test.dest) + src := drivertest.MustDocument(test.src) + if err := copyTopLevel(dest, src); err != nil { + t.Fatalf("src=%+v: %v", test.src, err) + } + if !cmp.Equal(test.dest, test.want) { + t.Errorf("src=%+v: got %v, want %v", test.src, test.dest, test.want) + } + } +} + +func Test_documentIterator_Next(t *testing.T) { + type fields struct { + qr *queryRunner + items []map[string]dyn2Types.AttributeValue + curr int + offset int + limit int + count int + last map[string]dyn2Types.AttributeValue + asFunc func(i interface{}) bool + } + type args struct { + ctx context.Context + doc driver.Document + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + { + name: "nextWithNoDecodeError", + fields: fields{ + qr: &queryRunner{}, + items: []map[string]dyn2Types.AttributeValue{ + {"key": &dyn2Types.AttributeValueMemberM{Value: map[string]dyn2Types.AttributeValue{"key": &dyn2Types.AttributeValueMemberS{Value: "value"}}}}, + }, + curr: 0, + offset: 0, + limit: 0, + count: 0, + last: map[string]dyn2Types.AttributeValue{}, + }, + args: args{ + ctx: context.Background(), + doc: drivertest.MustDocument(map[string]interface{}{}), + }, + wantErr: false, + }, + { + name: "nextWithDecodeError", + fields: fields{ + qr: &queryRunner{}, + items: []map[string]dyn2Types.AttributeValue{ + {"key": nil}, // set M to nil to trigger decode error + }, + curr: 0, + offset: 0, + limit: 0, + count: 0, + last: map[string]dyn2Types.AttributeValue{}, + }, + args: args{ + ctx: context.Background(), + doc: drivertest.MustDocument(map[string]interface{}{}), + }, + wantErr: true, + }, + { + name: "nextWhereCurrIsGreaterThanOrEqualToItemsAndLastIsNotNil", + fields: fields{ + qr: &queryRunner{ + scanIn: &dyn.ScanInput{}, + // hack to return error from run + beforeRun: func(asFunc func(i interface{}) bool) error { return errors.New("invalid") }, + }, + items: []map[string]dyn2Types.AttributeValue{{"key": &dyn2Types.AttributeValueMemberM{Value: map[string]dyn2Types.AttributeValue{"key": &dyn2Types.AttributeValueMemberS{Value: "value"}}}}}, + curr: 1, + offset: 0, + limit: 0, + count: 0, + last: map[string]dyn2Types.AttributeValue{"key": &dyn2Types.AttributeValueMemberS{Value: "value"}}, + }, + args: args{ + ctx: context.Background(), + doc: drivertest.MustDocument(map[string]interface{}{}), + }, + wantErr: true, + }, + } + for i, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + it := &documentIterator{ + qr: tt.fields.qr, + items: tt.fields.items, + curr: tt.fields.curr, + offset: tt.fields.offset, + limit: tt.fields.limit, + count: tt.fields.count, + last: tt.fields.last, + asFunc: tt.fields.asFunc, + } + if err := it.Next(tt.args.ctx, tt.args.doc); (err != nil) != tt.wantErr { + t.Errorf("documentIterator.Next() test=%v(%v) error = %v, wantErr %v", i+1, tt.name, err, tt.wantErr) + } + }) + } +} diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/ActionsOnStructNoRev.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/ActionsOnStructNoRev.replay new file mode 100644 index 000000000..290926bee --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/ActionsOnStructNoRev.replay @@ -0,0 +1,597 @@ +{ + "Initial": "AQAAAA7gDNWKN5zvAQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "04016e22600892ab", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "8RDUOJSC6OT7M1TAIN9D0L6BMNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "f5b5a186209c65d7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "155" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3085739104" + ], + "X-Amzn-Requestid": [ + "EAPU9ODHMM74AD0QEQB8JPVPCBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3RTZXJpYWxpemVSZXZpc2lvbiJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI1ZmUzZjBjZi1hYWE5LTQ2NzItYmI1ZC00OWFjODNmM2E5NjUifSwieCI6eyJOIjoiMSJ9fV0sIlNjYW5uZWRDb3VudCI6MX0=" + } + }, + { + "ID": "c3a84b42a131fd1e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "241" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "E3IVN0FNIBC4T14F9OTJB53KJVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bee8841cf6c55cee", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "177" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "04P52VN6ITDPHNMQ58Q0PG337FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a5eb4b45a37eb2eb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "U92N4FNE1CGVUUT165HC0ST68BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5eb6f73db98a621a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "133" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "148" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1989180713" + ], + "X-Amzn-Requestid": [ + "7VP7UG08IDFQN3FTK43G87A3V3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJJIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6ImNyZWF0ZWFuZHJlcGxhY2UifX0seyJJIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6InB1dGFuZHVwZGF0ZSJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "17f28f43795241dd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "1HKERKRES09ACVF7I2SBO16UNBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2f753df4c3d1f4a2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "J9EKP34GVK03NIEBCV9O094LSJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5d6034f3330e20b0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "215" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "148" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:47 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1795518206" + ], + "X-Amzn-Requestid": [ + "R39832P71HEKIAJOEMDB0MQ79JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJJIjp7Ik4iOiIwIn0sIm5hbWUiOnsiUyI6ImNyZWF0ZWFuZHJlcGxhY2UifX0seyJJIjp7Ik4iOiIxIn0sIm5hbWUiOnsiUyI6InB1dGFuZHVwZGF0ZSJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/ActionsWithCompositeID.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/ActionsWithCompositeID.replay new file mode 100644 index 000000000..f7ff0ae5f --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/ActionsWithCompositeID.replay @@ -0,0 +1,841 @@ +{ + "Initial": "AQAAAA7gDNWLI6/B9QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "d8a597edf6afaac0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1609" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3233200316" + ], + "X-Amzn-Requestid": [ + "80HR6J4F9ENLGQJJ7RJS78CHHBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIkF0dHJpYnV0ZVR5cGUiOiJTIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJBdHRyaWJ1dGVUeXBlIjoiTiJ9LHsiQXR0cmlidXRlTmFtZSI6IlRpbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwODA2OTVFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkdsb2JhbFNlY29uZGFyeUluZGV4ZXMiOlt7IkluZGV4QXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMi9pbmRleC9nbG9iYWwiLCJJbmRleE5hbWUiOiJnbG9iYWwiLCJJbmRleFNpemVCeXRlcyI6MTA3LCJJbmRleFN0YXR1cyI6IkFDVElWRSIsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiUGxheWVyIiwiS2V5VHlwZSI6IkhBU0gifSx7IkF0dHJpYnV0ZU5hbWUiOiJUaW1lIiwiS2V5VHlwZSI6IlJBTkdFIn1dLCJQcm9qZWN0aW9uIjp7IlByb2plY3Rpb25UeXBlIjoiQUxMIn0sIlByb3Zpc2lvbmVkVGhyb3VnaHB1dCI6eyJOdW1iZXJPZkRlY3JlYXNlc1RvZGF5IjowLCJSZWFkQ2FwYWNpdHlVbml0cyI6NSwiV3JpdGVDYXBhY2l0eVVuaXRzIjo1fSwiV2FybVRocm91Z2hwdXQiOnsiUmVhZFVuaXRzUGVyU2Vjb25kIjo1LCJTdGF0dXMiOiJBQ1RJVkUiLCJXcml0ZVVuaXRzUGVyU2Vjb25kIjo1fX1dLCJJdGVtQ291bnQiOjEsIktleVNjaGVtYSI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJLZXlUeXBlIjoiSEFTSCJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIktleVR5cGUiOiJSQU5HRSJ9XSwiTG9jYWxTZWNvbmRhcnlJbmRleGVzIjpbeyJJbmRleEFybiI6ImFybjphd3M6ZHluYW1vZGI6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3Njp0YWJsZS9kb2NzdG9yZS10ZXN0LTIvaW5kZXgvbG9jYWwiLCJJbmRleE5hbWUiOiJsb2NhbCIsIkluZGV4U2l6ZUJ5dGVzIjoxMDcsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiR2FtZSIsIktleVR5cGUiOiJIQVNIIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJLZXlUeXBlIjoiUkFOR0UifV0sIlByb2plY3Rpb24iOnsiUHJvamVjdGlvblR5cGUiOiJBTEwifX1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMiIsIlRhYmxlSWQiOiIwZDRmOTk4My1kOGE5LTRhZjEtYTY0NC05YmE3M2NlMGYyMjciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIiLCJUYWJsZVNpemVCeXRlcyI6MTA3LCJUYWJsZVN0YXR1cyI6IkFDVElWRSIsIldhcm1UaHJvdWdocHV0Ijp7IlJlYWRVbml0c1BlclNlY29uZCI6NSwiU3RhdHVzIjoiQUNUSVZFIiwiV3JpdGVVbml0c1BlclNlY29uZCI6NX19fQ==" + } + }, + { + "ID": "72ee78f5216c8e12", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "235" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "882282052" + ], + "X-Amzn-Requestid": [ + "JFD912CE0N131I2SVKAOSSTHV7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTI1VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InN0ZXBoIn0sIlNjb3JlIjp7Ik4iOiIyNCJ9LCJHYW1lIjp7IlMiOiJEYXlzIEdvbmUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNDFmNGNjNGEtMjEyNy00ZTlmLWFjY2MtYzA3ODI1M2JjZjM3In19XSwiU2Nhbm5lZENvdW50IjoxfQ==" + } + }, + { + "ID": "2a91f0cb6f9eea9c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OHGD3C3GFSTRQ7HJIEH1QLJ67RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "24137ac91f7a44b2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "352" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "167" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2041333382" + ], + "X-Amzn-Requestid": [ + "B3MFPASTTBCIRL30QV0BBVV9TRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uLmNvcmFsLnZhbGlkYXRlI1ZhbGlkYXRpb25FeGNlcHRpb24iLCJtZXNzYWdlIjoiT25lIG9yIG1vcmUgcGFyYW1ldGVyIHZhbHVlcyB3ZXJlIGludmFsaWQ6IFR5cGUgbWlzbWF0Y2ggZm9yIGtleSBQbGF5ZXIgZXhwZWN0ZWQ6IFMgYWN0dWFsOiBOVUxMIn0=" + } + }, + { + "ID": "072c3a8d8dabc54c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "238" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "NIUA1TOVEJK5Q5V6IT4DOS02NBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "df12b497cfc1584a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "L43LM1KJ891E99OB54FU84EJOVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "65dbe47a06d731fb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "244" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M3MIAPP66AEJK88DN4EV8N5BANVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2b0a98a1a6f44060", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "235" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VITE7T340UPDITU3ROPGCTEDANVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "64e4202321c68b50", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DDGM5V1C10GAEN7TL7V34C540FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "384709f8d8a02683", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "S7RG40THCI89MJDH85C303GSRJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "24017dea06068310", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "244" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OJ2GJH9E4QGT5061UI2TPDNSFRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "13542c845e135151", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JT97K02TKADCHST7M1UPFK7CL3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ab65473ee54e7a89", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "504" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1667" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "273375396" + ], + "X-Amzn-Requestid": [ + "R92R228ERUHV4STO7MVOU3IS03VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0yIjpbeyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wMy0yMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJmcmFuIn0sIlNjb3JlIjp7Ik4iOiIzMyJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImUzY2M1NTFmLTQ2NjMtNDEzMS1hZTA3LTM5NTQ5M2Y1YzJkZiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYjVmNWM0OTYtZGFmMy00MDUxLTljMmQtM2Q0OWY3YjUzZDExIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijk0NDUzN2MyLTk5NWItNGUyMS05NDg1LTExYWRlZjI2YWZjZSJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiNjAifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2YTU4ZmI3My0xZTg3LTRhNWQtYWNhNC1hZjg3NzFkMTVlMGQifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJiaWxsaWUifSwiU2NvcmUiOnsiTiI6IjExMSJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjlkN2U5ODY5LTZmNzUtNGMyNC1hZWVkLTFmYzcxYmFiNGNiMSJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6dHJ1ZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMDFUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiIxMjAifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIyYjVmOTc2OS1mOWJiLTQ2YjctOWM2MC1hZTU2Nzc5ZGU3YTgifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wMy0xOVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJmcmFuIn0sIlNjb3JlIjp7Ik4iOiIzMyJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjkyMjI4NGQ5LTBhZjMtNGQxYS04Mjg2LWViNGU5ZjlhNzllNCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6dHJ1ZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMThUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiIxOTAifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlNjcwOTNjMi0yOTE1LTQ5ODQtYmE1Yi1jZDNiZGNiYWNlOTgifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/As/verify_As.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/As/verify_As.replay new file mode 100644 index 000000000..692a8bf8a --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/As/verify_As.replay @@ -0,0 +1,902 @@ +{ + "Initial": "AQAAAA7gDNWQKMtxoQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "c0075c9ae695cf55", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1609" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:52 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3233200316" + ], + "X-Amzn-Requestid": [ + "A3UALT8FB8B27456VN3R3H4DVVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIkF0dHJpYnV0ZVR5cGUiOiJTIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJBdHRyaWJ1dGVUeXBlIjoiTiJ9LHsiQXR0cmlidXRlTmFtZSI6IlRpbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwODA2OTVFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkdsb2JhbFNlY29uZGFyeUluZGV4ZXMiOlt7IkluZGV4QXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMi9pbmRleC9nbG9iYWwiLCJJbmRleE5hbWUiOiJnbG9iYWwiLCJJbmRleFNpemVCeXRlcyI6MTA3LCJJbmRleFN0YXR1cyI6IkFDVElWRSIsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiUGxheWVyIiwiS2V5VHlwZSI6IkhBU0gifSx7IkF0dHJpYnV0ZU5hbWUiOiJUaW1lIiwiS2V5VHlwZSI6IlJBTkdFIn1dLCJQcm9qZWN0aW9uIjp7IlByb2plY3Rpb25UeXBlIjoiQUxMIn0sIlByb3Zpc2lvbmVkVGhyb3VnaHB1dCI6eyJOdW1iZXJPZkRlY3JlYXNlc1RvZGF5IjowLCJSZWFkQ2FwYWNpdHlVbml0cyI6NSwiV3JpdGVDYXBhY2l0eVVuaXRzIjo1fSwiV2FybVRocm91Z2hwdXQiOnsiUmVhZFVuaXRzUGVyU2Vjb25kIjo1LCJTdGF0dXMiOiJBQ1RJVkUiLCJXcml0ZVVuaXRzUGVyU2Vjb25kIjo1fX1dLCJJdGVtQ291bnQiOjEsIktleVNjaGVtYSI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJLZXlUeXBlIjoiSEFTSCJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIktleVR5cGUiOiJSQU5HRSJ9XSwiTG9jYWxTZWNvbmRhcnlJbmRleGVzIjpbeyJJbmRleEFybiI6ImFybjphd3M6ZHluYW1vZGI6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3Njp0YWJsZS9kb2NzdG9yZS10ZXN0LTIvaW5kZXgvbG9jYWwiLCJJbmRleE5hbWUiOiJsb2NhbCIsIkluZGV4U2l6ZUJ5dGVzIjoxMDcsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiR2FtZSIsIktleVR5cGUiOiJIQVNIIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJLZXlUeXBlIjoiUkFOR0UifV0sIlByb2plY3Rpb24iOnsiUHJvamVjdGlvblR5cGUiOiJBTEwifX1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMiIsIlRhYmxlSWQiOiIwZDRmOTk4My1kOGE5LTRhZjEtYTY0NC05YmE3M2NlMGYyMjciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIiLCJUYWJsZVNpemVCeXRlcyI6MTA3LCJUYWJsZVN0YXR1cyI6IkFDVElWRSIsIldhcm1UaHJvdWdocHV0Ijp7IlJlYWRVbml0c1BlclNlY29uZCI6NSwiU3RhdHVzIjoiQUNUSVZFIiwiV3JpdGVVbml0c1BlclNlY29uZCI6NX19fQ==" + } + }, + { + "ID": "afc3c52afa1ba098", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:52 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "6590H353PDGO5I2MU054Q8K3LNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "abf53e0055dad5ac", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "260" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:52 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "08LHSLQ09A29RNABUCC7VP73F3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "91c9cbad45224613", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "THOTIG1HHMGVMOL95T1CCR75ORVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ec5a1878323f5f77", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7089SEBI7NVD16V7DLVO4VBLAJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c2666b92febba345", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "261" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "1F14BMADR2K5HTKD62T7OKS7JBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5efdedafa0ee70ba", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "J31KEATNFBUOALK3B0FMLH41U3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5b48c31f1fec750b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "416NPEKDG2V8HKI2QDAU2BJG83VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e700b08a43cfa080", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "261" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:52 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "16C4GSEIN4AFEVVIRNVOG1MJM3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "acd5d0c58161dcb7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "260" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "R7SGKUJJNS1BUPJBT34USUIASRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "493d55fb6a11b7bc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "183" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "FCVOJDRAOOLR1P3HJB1ACN85LFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "827d00474ee42ce8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "3LPP9AHVDV55RE0542OEF3M8FBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "abdca3af1c415a7d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "326" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6M5E1PBMHE3CNJLDRM2B45A407VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8fd429438cfa5df6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "326" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "QA9DSCG85G0TKFKC3DDE4EJ8BBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..6f0a5c42f --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,475 @@ +{ + "Initial": "AQAAAA7gDNWRFux59QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "d480c6ac9f3752be", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1609" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3233200316" + ], + "X-Amzn-Requestid": [ + "8MD0LHIFOCB745RLSK0QDP7TG7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIkF0dHJpYnV0ZVR5cGUiOiJTIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJBdHRyaWJ1dGVUeXBlIjoiTiJ9LHsiQXR0cmlidXRlTmFtZSI6IlRpbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwODA2OTVFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkdsb2JhbFNlY29uZGFyeUluZGV4ZXMiOlt7IkluZGV4QXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMi9pbmRleC9nbG9iYWwiLCJJbmRleE5hbWUiOiJnbG9iYWwiLCJJbmRleFNpemVCeXRlcyI6MTA3LCJJbmRleFN0YXR1cyI6IkFDVElWRSIsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiUGxheWVyIiwiS2V5VHlwZSI6IkhBU0gifSx7IkF0dHJpYnV0ZU5hbWUiOiJUaW1lIiwiS2V5VHlwZSI6IlJBTkdFIn1dLCJQcm9qZWN0aW9uIjp7IlByb2plY3Rpb25UeXBlIjoiQUxMIn0sIlByb3Zpc2lvbmVkVGhyb3VnaHB1dCI6eyJOdW1iZXJPZkRlY3JlYXNlc1RvZGF5IjowLCJSZWFkQ2FwYWNpdHlVbml0cyI6NSwiV3JpdGVDYXBhY2l0eVVuaXRzIjo1fSwiV2FybVRocm91Z2hwdXQiOnsiUmVhZFVuaXRzUGVyU2Vjb25kIjo1LCJTdGF0dXMiOiJBQ1RJVkUiLCJXcml0ZVVuaXRzUGVyU2Vjb25kIjo1fX1dLCJJdGVtQ291bnQiOjEsIktleVNjaGVtYSI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJLZXlUeXBlIjoiSEFTSCJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIktleVR5cGUiOiJSQU5HRSJ9XSwiTG9jYWxTZWNvbmRhcnlJbmRleGVzIjpbeyJJbmRleEFybiI6ImFybjphd3M6ZHluYW1vZGI6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3Njp0YWJsZS9kb2NzdG9yZS10ZXN0LTIvaW5kZXgvbG9jYWwiLCJJbmRleE5hbWUiOiJsb2NhbCIsIkluZGV4U2l6ZUJ5dGVzIjoxMDcsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiR2FtZSIsIktleVR5cGUiOiJIQVNIIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJLZXlUeXBlIjoiUkFOR0UifV0sIlByb2plY3Rpb24iOnsiUHJvamVjdGlvblR5cGUiOiJBTEwifX1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMiIsIlRhYmxlSWQiOiIwZDRmOTk4My1kOGE5LTRhZjEtYTY0NC05YmE3M2NlMGYyMjciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIiLCJUYWJsZVNpemVCeXRlcyI6MTA3LCJUYWJsZVN0YXR1cyI6IkFDVElWRSIsIldhcm1UaHJvdWdocHV0Ijp7IlJlYWRVbml0c1BlclNlY29uZCI6NSwiU3RhdHVzIjoiQUNUSVZFIiwiV3JpdGVVbml0c1BlclNlY29uZCI6NX19fQ==" + } + }, + { + "ID": "2086454f2b43dbf9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "235" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3114832516" + ], + "X-Amzn-Requestid": [ + "BRSPRNPJJR8SS29MN6SLFVSCN3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTI1VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InN0ZXBoIn0sIlNjb3JlIjp7Ik4iOiIyNCJ9LCJHYW1lIjp7IlMiOiJEYXlzIEdvbmUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNmMyMDg2OWYtNzM0Zi00YWIxLTk1MWYtMGViZWQ0MTE2M2Y0In19XSwiU2Nhbm5lZENvdW50IjoxfQ==" + } + }, + { + "ID": "51950d86b95868c4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0C789GP99HKS2TNGL35IK8OPD7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1ceb3a76a5339fa2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "183" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "F6Q5T9C12B9QECKHHPC959O8NBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "9f5508df894efadf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "KFS22MD89H3449MVNQM6Q6EGTVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "d148ff32b99155c3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "326" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VA6O85JIBVDCJE6BA9N4U3CCMRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "055e000edaa3ee46", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "326" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "PO6U31DDH1HGRQTDQDVSN8CRU7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/AtomicWrites.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/AtomicWrites.replay new file mode 100644 index 000000000..db6741344 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/AtomicWrites.replay @@ -0,0 +1,3037 @@ +{ + "Initial": "AQAAAA7gDNVzG+iG/QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "8787401c60bbafcd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "10R3FESMSUVK4LIDQ0ECHODJUNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "c692d5285855702d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "951" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3177318638" + ], + "X-Amzn-Requestid": [ + "T35E9GB3G58UPTP0FTQKLMT293VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7IkIiOnsiQk9PTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiI1YjRiN2ZhNS0yODQ1LTQzMDUtOGNmZS05MjI0MzEzNmZmMjcifSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdENyZWF0ZVN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fSx7Im5hbWUiOnsiUyI6InRlc3RDcmVhdGVNYXAifSwiRXRhZyI6eyJTIjoiYzQwMWM5YzEtZjFkMi00NmEzLWIzZTQtZWRiNjdkZjhmMGUyIn0sImIiOnsiQk9PTCI6dHJ1ZX19LHsiRXRhZyI6eyJTIjoiNmE2ZGEzNTYtMjZlMC00YjFkLWE5YzktY2E4MDU2YWE3NDI5In0sIm5hbWUiOnsiUyI6IjVjZGE1YjhhLWU4MjMtNDBhYi1iYTI2LTNhMzA3MTRlNDliMCJ9LCJiIjp7IkJPT0wiOnRydWV9fSx7IkIiOnsiQk9PTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiIwNGI5YjJkZi04OGNiLTQwZmEtODhlNS00MDc1YjdmYmM5YjQifSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoiYmQyY2E2NzctODcyMC00MWJmLTk5ZjgtNmVlYmNhZjVkOGY1In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19LHsiQiI6eyJCT09MIjp0cnVlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiUyI6ImY1MDQ1MTE0LTYwMzAtNDViMy05ZTJjLTJjNGI5ZDE1MTFlOCJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJkYTFjZThkYi1iYTEwLTRhNWMtYWJiMy1mMWZlN2YyZWJlZDAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJOVUxMIjp0cnVlfX1dLCJTY2FubmVkQ291bnQiOjV9" + } + }, + { + "ID": "340f87010feb5b7a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HHOCT2KPCNLKH2IS1GEO2D22ABVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2de604839d3ec1df", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "E0QHDB1U6586N1LULI9P46CMHFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "44207484c3c85039", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "4D1LS22OP59E821C67NU77R04BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bbe014af3b480eff", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0NLQ4MMMGQOFRK45686KIP7VFNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4e59f6aa144c3261", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "EGJJ78M3EVI4UMMCV8J8473NRVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ef78660ad453a07c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "K63LH3A0RN0EH7JAQ94CN91DMFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7ff295e848e2975d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KK8VBG5IQGUOHJAALSBVPJRVP3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7138d59987d89e2f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "65R212QKOH55TMQ70EF30AMPHVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c037a700e0b89708", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "COGB8KL7CL0BGFIU5P7B3BKO27VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "dbcf9a4ff1798edf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LU5F0E49CFKO17GJIC35QHIQRNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7b92a89f5fd25803", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "O268HJ6CKUO79UMCL8E4JPKGKJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6564343c748710c9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "Q2DDQTA34VFP7PMNPLP1EKPVN3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "80a8f052a64b6ce3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "K0SL7LU74FNSN1BVHDOPQUVLSNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d98f0806117c6bd3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3FLON77NQQINM63JSLVII99QFNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e89f37f720ea5b40", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PR4VJDUS3PPCJ405PC41IA7K0FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9dd3767f2b0223d3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "174" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "395" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "125455835" + ], + "X-Amzn-Requestid": [ + "FMJMLECRAR8A2MMSHGD7VB434JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIyYTJlNDU4Mi00ZmU4LTRkMWYtYWZmYy1hMWUzZDg1N2NhMjMifSwicyI6eyJTIjoiMyJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImEyMTNmMGE4LWU2ODAtNGQxYS05YjZkLTAyYjZhYWUwOTVmZSJ9LCJzIjp7IlMiOiI0In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTYxZGRmNTctMjAzYS00ODZhLTg1NmEtNTJmNjkzNWQwY2M1In0sInMiOnsiUyI6IjUifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "46531df5d5c0fd13", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3543C04NUS2DP1L8I84IPCKGUVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4258a6669ab7ebd0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "94NRV0FR1H92F676QP58LKN3RRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bd6b236256096d36", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "1183" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.TransactWriteItems" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QO5DAMJ5KM2MPGPEI0223QC683VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1e3ddbc0bb133980", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "170" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1252753773" + ], + "X-Amzn-Requestid": [ + "4FAS2KDPPKL9VEV0APOPV1N8HRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIxYTJiODQ0Yi1iMTgwLTRkYjItYjkyMi0wYzhkZjk1MGYyYzYifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwicyI6eyJTIjoiNjYifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "018d495fcf9d6185", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "170" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3528314867" + ], + "X-Amzn-Requestid": [ + "CT0RF4HV3P2SRLJ4M5SI6PJEQBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIyMzI5NjU5Ny05MTQ0LTQ1YTUtOTIwYy0xYTNjZmNhMTk2NjAifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifSwicyI6eyJTIjoiNzcifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "53b631bf32fa0574", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "170" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2086226600" + ], + "X-Amzn-Requestid": [ + "R04CDTJJ96HJM05QCFGK5A0N9JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4MDJjZDQ1Zi0wMzA3LTRkYTYtODRmOS0zN2FkOTZkOTg3OGEifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczgifSwicyI6eyJTIjoiODgifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "0d8840e87b646fff", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "11S7EF9STRF35T8LH0K25I63H7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "dd63837e4d660f31", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "719" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2980878973" + ], + "X-Amzn-Requestid": [ + "1G1QT9QMODLM7C5NAE03IV1GIJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NiwiSXRlbXMiOlt7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjgwMmNkNDVmLTAzMDctNGRhNi04NGY5LTM3YWQ5NmQ5ODc4YSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzOCJ9LCJzIjp7IlMiOiI4OCJ9fSx7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjIzMjk2NTk3LTkxNDQtNDVhNS05MjBjLTFhM2NmY2ExOTY2MCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9LCJzIjp7IlMiOiI3NyJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImEyMTNmMGE4LWU2ODAtNGQxYS05YjZkLTAyYjZhYWUwOTVmZSJ9LCJzIjp7IlMiOiI0In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTYxZGRmNTctMjAzYS00ODZhLTg1NmEtNTJmNjkzNWQwY2M1In0sInMiOnsiUyI6IjUifX0seyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIyYTJlNDU4Mi00ZmU4LTRkMWYtYWZmYy1hMWUzZDg1N2NhMjMifSwicyI6eyJTIjoiMyJ9fSx7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjFhMmI4NDRiLWIxODAtNGRiMi1iOTIyLTBjOGRmOTUwZjJjNiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNiJ9LCJzIjp7IlMiOiI2NiJ9fV0sIlNjYW5uZWRDb3VudCI6Nn0=" + } + }, + { + "ID": "9c6cbbbb0c59f9e1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "759FJRVBOEPV1S8QVBTDMNEM6RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5baa01bfab7ed4e4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "03TD5VBEA8EO1J6DR9KJMJ259FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "83e76f0bac64379e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TLQHJ58Q86N4POR51LO2TLV7AFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7515e9cc0468d905", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HEP8T3TO20SAQ3ATVEJI5NTRANVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0e5298eaaf1a4d7e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FRNMA5MOLP8SU0HV2KMR1U45HNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "043281f28bbe886f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JP4M8DEGQ6QV0718D8CC10KAAVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a9dce7cab98cf2a4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JOLC5PUA1MKGG7IUC0KUOQRQ0JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f7749e88174aa87b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "R3CRHTHKDJMTK22SGJKGCK6EOBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "69beb2438b03811f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TOUUURAHUV59TRV94PG5LJ1H0RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2ded7be6d5d2c5ef", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "B9AFIP9RFCRNQH9S31R0EI36RBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "159a8cc8d8b05710", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0JHBU5O7HJ7108DHG5QULCBT0VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8c5e4b67e70ce944", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0E6KQABC7GP9TCMHTF0MMU5UF3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "803b212adab91116", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3GNLSI54U4SHOR00DGC5KQEUIVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e94ad5f2cdfda221", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3K3ISTJU9S4B8JBCBKRGDGH7HNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ff9985c62b8c9ac3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:24 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JCL20FG2KBATO9UOSVAGLH6TM3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0cbaa8d7764b8339", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "INC9RCJ066P96C3MNP0VMREA9JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "002130474e60a7a2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "E6L66626PTDUN3A643P2V4M57JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "aa3fbdeac1b2360f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VR6B6FMG72TNSVQ5DGJ0EENKRRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "518751a2c61b44f1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "174" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "359" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3297822940" + ], + "X-Amzn-Requestid": [ + "M6EEE1JQ5QP0DO7LKBVQE0BQ2NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNCJ9LCJFdGFnIjp7IlMiOiJkZmVhNzQwNS1mY2RkLTRlODItOGJmMC1iNjhmMjI0MmUzZGIifSwicyI6eyJTIjoiNCJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM1In0sIkV0YWciOnsiUyI6IjY1OTM3ZGU5LTRlNzgtNDY4MC04N2EzLTdiZWY0NTYwMWU0NSJ9LCJzIjp7IlMiOiI1In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczMifSwiRXRhZyI6eyJTIjoiMDBhN2E3N2YtMzVhZi00MjBkLWIyYzQtYjliZjY0OWU5Nzk0In0sInMiOnsiUyI6IjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "fa51798dc86963fc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "1147" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.TransactWriteItems" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PL3HC89DT49LS3JL5L2MUPRBVFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a58ba549250158e9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "158" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1465257071" + ], + "X-Amzn-Requestid": [ + "8JLO0I1TI2DGC9BAONDUJ38KAVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiIyNWMzYjVlOS0xNWNhLTRhZDgtODEzMC02MTgzMTRhMmVlZmMifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwicyI6eyJTIjoiNjYifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "7ece43a1fb4c1362", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "158" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "378066325" + ], + "X-Amzn-Requestid": [ + "MN0K5T7PCAC715VE66ULUI6BARVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiJkMGI1ZjM1Zi04ZGUzLTQ1YjgtODRiNy0xZDU0MTQwMDJiMGMifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifSwicyI6eyJTIjoiNzcifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "b417034028065f52", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "158" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2700481946" + ], + "X-Amzn-Requestid": [ + "0PEKHGJJ5LRCJS80THGC9BMC63VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiIzZTUxZGZlZC0wM2QyLTQ0NmMtYjFkNC04NzRiYzhiZDkyZmQifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczgifSwicyI6eyJTIjoiODgifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/AtomicWritesFail.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/AtomicWritesFail.replay new file mode 100644 index 000000000..453580a0d --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/AtomicWritesFail.replay @@ -0,0 +1,2793 @@ +{ + "Initial": "AQAAAA7gDNV1GOdZxAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "63c4a5c578fe220d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "TQVFPSS303O4G4NUUNFSHVEGNNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "1e85633d1835fb6e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "647" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1148207523" + ], + "X-Amzn-Requestid": [ + "3I19D8D50OF0GH35STREEBEG57VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NiwiSXRlbXMiOlt7IkV0YWciOnsiUyI6IjNlNTFkZmVkLTAzZDItNDQ2Yy1iMWQ0LTg3NGJjOGJkOTJmZCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzOCJ9LCJzIjp7IlMiOiI4OCJ9fSx7IkV0YWciOnsiUyI6ImQwYjVmMzVmLThkZTMtNDViOC04NGI3LTFkNTQxNDAwMmIwYyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9LCJzIjp7IlMiOiI3NyJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In0sIkV0YWciOnsiUyI6ImRmZWE3NDA1LWZjZGQtNGU4Mi04YmYwLWI2OGYyMjQyZTNkYiJ9LCJzIjp7IlMiOiI0In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwiRXRhZyI6eyJTIjoiNjU5MzdkZTktNGU3OC00NjgwLTg3YTMtN2JlZjQ1NjAxZTQ1In0sInMiOnsiUyI6IjUifX0seyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9LCJFdGFnIjp7IlMiOiIwMGE3YTc3Zi0zNWFmLTQyMGQtYjJjNC1iOWJmNjQ5ZTk3OTQifSwicyI6eyJTIjoiMyJ9fSx7IkV0YWciOnsiUyI6IjI1YzNiNWU5LTE1Y2EtNGFkOC04MTMwLTYxODMxNGEyZWVmYyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNiJ9LCJzIjp7IlMiOiI2NiJ9fV0sIlNjYW5uZWRDb3VudCI6Nn0=" + } + }, + { + "ID": "eecec30ffe8ded5a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "BU73CIRPM6B5684E6FBKUIPGKJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cbf8d3f51ea19ed3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DIVQL6CQ447DG3OBJ30LHQIH3RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3e347a4f1e0aab11", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "C7E0NE7RFI4J9A375BEKMAN6GFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "57522de242e0fbdb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DTCIRJ1SD43PF8LA2EAC5KKTN3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4c99a42830b74094", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OC1DNBBQU3D5LOC96DVBDJGNCBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c20ca9cf764c6d0b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MFSQQCN8S2O7CT9H4MURBMRKMNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "512c1c94dfeb1727", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "INT2H4FFINDFJDS05KDQ7NFFVFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f0873d895da5fdc8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JHG2H7MHSGTD9P35H958PKCVLVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6219dd2f5965424a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GMBKCFGCOCPCG8UF7U1JOB1067VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fd8f94324a9e5dc4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9QPCAON43I4CKG8F8IDAQCAI97VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0b63d28218f97975", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "EJN9UDOO5KI902AH6GJKSQACFRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "91ccf1a9fea6d8da", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "50GDO92PUNO4H4LNEEB5UBP4RVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a4de6577a4252106", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VNVQKH0KMC7KFTLM0UQR9QMH4BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b6c8ec53d0e1ee94", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FS59V5L4HOHQLDKTO73GMRMNPFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0aefe72145d26395", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "174" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "395" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:25 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1585290119" + ], + "X-Amzn-Requestid": [ + "S3R1PN5R3VK623RKB45IAHAKBVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIxYTIzZWEzZC01NzU1LTQ2NzItYmMyNi1jZDNmN2QxYWM3MzQifSwicyI6eyJTIjoiMyJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjQ1ZTllM2Y2LWFkZTEtNDEzOC04MDZhLWFiZWIyYzU0MGIzMyJ9LCJzIjp7IlMiOiI0In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiY2IwMzcwZTYtZjkyMi00ZjgwLWEyNDUtNTQwZmY3OTdhMmJmIn0sInMiOnsiUyI6IjUifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "2caf6998c200615d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "2M4HPE1PPOG368NU1U4CPD16NJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "948632db177dfcd3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FERCBF8O2IUEI0VT9DHUKS51UJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5f9333017ff5dc96", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "237" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "1TU52TU2I50S16TN3H1J3JJ4AVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9f3cc0d45e9bb844", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "1159" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.TransactWriteItems" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "334" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2597991568" + ], + "X-Amzn-Requestid": [ + "IOSNDLIJA63UCV40PTSMHUAE8VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNUcmFuc2FjdGlvbkNhbmNlbGVkRXhjZXB0aW9uIiwiQ2FuY2VsbGF0aW9uUmVhc29ucyI6W3siQ29kZSI6Ik5vbmUifSx7IkNvZGUiOiJOb25lIn0seyJDb2RlIjoiQ29uZGl0aW9uYWxDaGVja0ZhaWxlZCIsIk1lc3NhZ2UiOiJUaGUgY29uZGl0aW9uYWwgcmVxdWVzdCBmYWlsZWQifV0sIk1lc3NhZ2UiOiJUcmFuc2FjdGlvbiBjYW5jZWxsZWQsIHBsZWFzZSByZWZlciBjYW5jZWxsYXRpb24gcmVhc29ucyBmb3Igc3BlY2lmaWMgcmVhc29ucyBbTm9uZSwgTm9uZSwgQ29uZGl0aW9uYWxDaGVja0ZhaWxlZF0ifQ==" + } + }, + { + "ID": "b16da1a9662f05ff", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "169" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2244273174" + ], + "X-Amzn-Requestid": [ + "HVAT0FG9B8CUFAF6S89H9UG093VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNiJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlMTM1ZmI2YS0zMGFjLTQyM2MtYTdhMC04NDMwMTM4MzNlMDMifSwicyI6eyJTIjoiNiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "2fadaddbbcb48a58", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "169" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "118631068" + ], + "X-Amzn-Requestid": [ + "7CQ4FUR97JRPHPQB4UI0ABMMIJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIyZmMxOGNhMi1kZmZmLTRiZDgtYmU4Yy03ODhkNjcwMDg3ZWMifSwicyI6eyJTIjoiNyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "2e781bdf0d0d2c25", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "C7PB014MNO453C44EOJA3T1CIBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "3d280a706400f79e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "603" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "662860440" + ], + "X-Amzn-Requestid": [ + "CPVU4V3UC26NDA09B14MSJG9Q3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM3In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJmYzE4Y2EyLWRmZmYtNGJkOC1iZThjLTc4OGQ2NzAwODdlYyJ9LCJzIjp7IlMiOiI3In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNDVlOWUzZjYtYWRlMS00MTM4LTgwNmEtYWJlYjJjNTQwYjMzIn0sInMiOnsiUyI6IjQifX0seyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNSJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJjYjAzNzBlNi1mOTIyLTRmODAtYTI0NS01NDBmZjc5N2EyYmYifSwicyI6eyJTIjoiNSJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXMzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjFhMjNlYTNkLTU3NTUtNDY3Mi1iYzI2LWNkM2Y3ZDFhYzczNCJ9LCJzIjp7IlMiOiIzIn19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZTEzNWZiNmEtMzBhYy00MjNjLWE3YTAtODQzMDEzODMzZTAzIn0sInMiOnsiUyI6IjYifX1dLCJTY2FubmVkQ291bnQiOjV9" + } + }, + { + "ID": "8c037229052c4f34", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LN5BD9FC03KKK7IS3GE5M9KTBRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6ad290dfeb5391ee", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8GK0QQ6DALH90QDN8G1BJQ6C8RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2ce3ba079caa4fbb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "65CIO7EN4N6G8BBLKR7UTL04H7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "99c2ed15b0f8b67d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9DV3DAG3DP4K2MHE0KEJETHKUVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "698761f89dfbf2e7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GCHIHGVHNMR1JCOKLVL8TF4PDVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cc217cc7c6e0f6ee", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "G0K1ANBAQOT7F0711C0F468U3BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8de19a5504d9b27d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0DQ1CUP01H1JRD49B2VKE0C16VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b5c5f2022b4cae5e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DVGCI2A2OPQ31AS0TP4IMSE1QFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "40e679cddba2c0d3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "ERGHCTAMBGGCI4RUSIF9INK9BJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "08ce600fe42530f9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CD85VULVN61E7L8EHQIGBFS8SVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2f986cb252d2257d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "1EK5PNB5J0C6OEU9BHAPSG8AC7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9c7e6cbaef54c420", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "50PBLOI4VLS2H6A2HNH8JSAQ03VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c040a3d7e644b156", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3PE9BOE65TC5U2F8UKNUP4B0FNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fd18f70237c45a5f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "EVOQ794GQRO64DFUMJUHQPUJ7BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ab7fc7e2e166a455", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "1123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.TransactWriteItems" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "334" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2597991568" + ], + "X-Amzn-Requestid": [ + "F8BDDGA2PT3OK5JOBAVG7333JRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNUcmFuc2FjdGlvbkNhbmNlbGVkRXhjZXB0aW9uIiwiQ2FuY2VsbGF0aW9uUmVhc29ucyI6W3siQ29kZSI6Ik5vbmUifSx7IkNvZGUiOiJOb25lIn0seyJDb2RlIjoiQ29uZGl0aW9uYWxDaGVja0ZhaWxlZCIsIk1lc3NhZ2UiOiJUaGUgY29uZGl0aW9uYWwgcmVxdWVzdCBmYWlsZWQifV0sIk1lc3NhZ2UiOiJUcmFuc2FjdGlvbiBjYW5jZWxsZWQsIHBsZWFzZSByZWZlciBjYW5jZWxsYXRpb24gcmVhc29ucyBmb3Igc3BlY2lmaWMgcmVhc29ucyBbTm9uZSwgTm9uZSwgQ29uZGl0aW9uYWxDaGVja0ZhaWxlZF0ifQ==" + } + }, + { + "ID": "4da88f2b30fc5639", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "IGJN2572AQV2BR75EECFDQ9V4JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e66f3d56b503e22f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "174" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "359" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2422119830" + ], + "X-Amzn-Requestid": [ + "4TERVUEGJUET6MH6TUI2R8GK2NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzMyJ9LCJFdGFnIjp7IlMiOiIwYTNmYTRiOC0yNTVkLTQ3NTMtYTEzYS1mMmE3ZGZhOTc4Y2QifSwicyI6eyJTIjoiMyJ9fSx7IkV0YWciOnsiUyI6IjhiNTAyZTVmLTg1MGUtNGY2OS1hNTQ0LWQ1ZTJlM2M3YTBiMyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNSJ9LCJzIjp7IlMiOiI1In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifSwiRXRhZyI6eyJTIjoiM2Y4YjU4MjYtOTNjZi00MmVjLWI2ZDktNDllNjZhYTFhOTdhIn0sInMiOnsiUyI6IjQifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "5012c96b87659dd6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "225" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:26 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KQRFV1I6NG0ACE1T3UFAOLJ0J7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "902f220f25fb7eff", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "157" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2815669241" + ], + "X-Amzn-Requestid": [ + "H4TCNM4UKMTURBMO8RDDCUT5QFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiIwNDliMTY0ZC0wYzdiLTQ1ZDEtOGQ2MS01MjEyOWU5ZTYwYWIifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczYifSwicyI6eyJTIjoiNiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "51f99f15e81fb32f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "157" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1807236012" + ], + "X-Amzn-Requestid": [ + "4FG2PM1SLS3O2TI1BGD740129FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI0ODk4ZWNmOC03ZThmLTQ0MzYtYjIyNC1iMThmOTVjZDE5MWIifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczcifSwicyI6eyJTIjoiNyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/BeforeDo.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/BeforeDo.replay new file mode 100644 index 000000000..123e0a346 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/BeforeDo.replay @@ -0,0 +1,536 @@ +{ + "Initial": "AQAAAA7gDNWPLpDQ8AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "3ed33d41e95436ef", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "UDP3J4QIS8VEO8OCQMRCAI8NIBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "952981eb048c44b7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "L5I95THD5DJ78FQ7ETGFKTTUKBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "ccd97b27f2d532ba", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "159" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SNDFQ1SHGIONL2EBH8PLEJCE0RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "eafca5eb1a122f73", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MUMGQ4R4PFLR9PF7BJR3QPB66NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "504718956ba828fb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VBORGEM65OQVVKS1LJC54922KRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ac53efebd3bb4cfc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:52 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "Q12K8E06I80VIGK4HNJ4BBH9SNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1e6fafe27e9e80b5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "99" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "100" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:52 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3495001968" + ], + "X-Amzn-Requestid": [ + "2INQ095VCQKPJ9OEE5FADU6KRJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7Ik4iOiIxIn0sIm5hbWUiOnsiUyI6InRlc3RCZWZvcmVEbyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "8bd9a20cde33aaa9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:52 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "B4OMK8FAAMK26QD9EUGF36NLPJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/BeforeQuery.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/BeforeQuery.replay new file mode 100644 index 000000000..e9e1fdf72 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/BeforeQuery.replay @@ -0,0 +1,231 @@ +{ + "Initial": "AQAAAA7gDNWQFsaFJAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "3f27037c66d654d2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:52 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "S0SLRQF3LAMJFKGTTIANSUJQJVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "7d4e2ad4513a5e29", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:52 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "MIIA99UBPJMAKJ3IML7A6CTDKNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "75576e66cfdb27b8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:52 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "RRLOM5EBOPC6U0T41FP5C369ONVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Create.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Create.replay new file mode 100644 index 000000000..486a08d97 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Create.replay @@ -0,0 +1,1939 @@ +{ + "Initial": "AQAAAA7gDNVxA3NRVgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "28eb7db06b5f2e91", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "M55AV0RQ4G71IHD8THV48H57G3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "e2806c17bf65038e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3413411624" + ], + "X-Amzn-Requestid": [ + "R69TGUTBV38HEA3BTD2Q8N8RDFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MCwiSXRlbXMiOltdLCJTY2FubmVkQ291bnQiOjB9" + } + }, + { + "ID": "d29e795855a10ebc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "242" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KS9I0TL093BVKOSF43C8FSKJ8FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f98f214025c94ba3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "169" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "235516159" + ], + "X-Amzn-Requestid": [ + "O9R0EKA4FU5E9P6GJQVD9DIGP3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0Q3JlYXRlTWFwIn0sImIiOnsiQk9PTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjdkN2ExODc3LTVkMjgtNGVkOC1iY2U5LTQxZWUyYWMxYzEyYSJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "802ba1f8fdbf4c21", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "224" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:21 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "RSV7HNMUKHS0NCAI1PKKRVDFANVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "ff327e3b3655b51d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "265" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OUJLMGNSAOB4BI0SLBDK9PHV9JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9196b4de956a1a5d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "192" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2932140693" + ], + "X-Amzn-Requestid": [ + "P2TVFMNKPLBF9MGUM8DA13ST4FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJiNWEzMGFiOC0xNzZlLTRhMWItOGMxMC02MjcxNzAzZDhjMDUifSwiYiI6eyJCT09MIjp0cnVlfSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYjc0OTA4ZTktOWE3NS00M2ZiLTljYjUtMDY2M2YwYzNjZjFlIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "c1e453797c4c9842", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "345" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GCLMLTNQF35MB4B8NVMQ42KTOJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0fc2eb64402a0ecd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "272" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2775518028" + ], + "X-Amzn-Requestid": [ + "VUOU5DBI1LRFBH0IEI1T1H1DABVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdENyZWF0ZVN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJkNjk0YTQ3Mi1hNDc2LTRmMzUtOWQ4ZS01MTMzYjdmMzllMzAifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "74866f700e1f2bb4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "365" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VAVMLDMTAERVU1K7CETF7BS75JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bfd520ca264929ba", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "861160918" + ], + "X-Amzn-Requestid": [ + "4HSNGJ4IV4H706938ORG481NVFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoiOGYxZmRkMGUtYmJlMS00MDBhLWFlYTMtZDgzNTE0NDEyOGM3In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImY4Yzc1NjhmLWZjZDctNGYyOC1hYTRkLTdlZWJjMWEyOTM4MCJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "56b0beffff3107b2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "365" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LG6C14676KCV6NAPAR1K77PNKVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c68478eb369cd421", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1874687309" + ], + "X-Amzn-Requestid": [ + "4M5UVQAG6A9BTSUIH920IG82L7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoiYTJiZDBkOWMtODQxNi00ZjUzLWIwOGYtYzM4NmMxNDc0OTg3In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImRiOWE2MzIzLWIxNzUtNGI5Ny1hOTYxLTc0YWIwOGI1ZTRiYiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "d0a72101098f56b6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "DI54MCUNAO3KEPPHHEAOGCBE2NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "2c068ea54c27cbe9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "975" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1597966203" + ], + "X-Amzn-Requestid": [ + "D826KR7OP09UHFUJ35D9R1S49RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7IkIiOnsiQk9PTCI6dHJ1ZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJhMmJkMGQ5Yy04NDE2LTRmNTMtYjA4Zi1jMzg2YzE0NzQ5ODcifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZGI5YTYzMjMtYjE3NS00Yjk3LWE5NjEtNzRhYjA4YjVlNGJiIn19LHsiQiI6eyJCT09MIjp0cnVlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RDcmVhdGVTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZDY5NGE0NzItYTQ3Ni00ZjM1LTlkOGUtNTEzM2I3ZjM5ZTMwIn19LHsibmFtZSI6eyJTIjoidGVzdENyZWF0ZU1hcCJ9LCJiIjp7IkJPT0wiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI3ZDdhMTg3Ny01ZDI4LTRlZDgtYmNlOS00MWVlMmFjMWMxMmEifX0seyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoiOGYxZmRkMGUtYmJlMS00MDBhLWFlYTMtZDgzNTE0NDEyOGM3In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImY4Yzc1NjhmLWZjZDctNGYyOC1hYTRkLTdlZWJjMWEyOTM4MCJ9fSx7Im5hbWUiOnsiUyI6ImI1YTMwYWI4LTE3NmUtNGExYi04YzEwLTYyNzE3MDNkOGMwNSJ9LCJiIjp7IkJPT0wiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiNzQ5MDhlOS05YTc1LTQzZmItOWNiNS0wNjYzZjBjM2NmMWUifX1dLCJTY2FubmVkQ291bnQiOjV9" + } + }, + { + "ID": "b3efce95b0789442", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "RMUJ26BHRHCFUMASCH024QGOPNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "99d639ae225db631", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "F60AFF6CHBAD4ILDRBU7AQ61KFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9220d0b42a7a1277", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GIAMLJ0AUS9RMN5KM8VJMDRVAJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1362b89762aba73c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "91" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GALAAH2JK4GTKDCOE21RLN800BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "565a86e23afd7613", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KTR4I8UKSOB6HLER919BEVCFARVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "188169d88288bb2e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "230" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JP5U61MH8VRH41NA9GMS4ROQN7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d230b78ebb9dd31c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "157" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1982366572" + ], + "X-Amzn-Requestid": [ + "VEJJP7U0MKQ4GOF89J9DQDLJB7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0Q3JlYXRlTWFwIn0sIkV0YWciOnsiUyI6ImM0MDFjOWMxLWYxZDItNDZhMy1iM2U0LWVkYjY3ZGY4ZjBlMiJ9LCJiIjp7IkJPT0wiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "b5fd6210381aa23f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "212" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "NTSR3PRL1RCVG2T8LKTVIJ0417VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "eea1599795d3b67b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:22 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VS6S7CPSL3RD5ILJVJHFT58EVFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b0fb80f5cad3fe8a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "180" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1042964175" + ], + "X-Amzn-Requestid": [ + "F2MIIQ3V7MBF7L90C44THIAED7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI2YTZkYTM1Ni0yNmUwLTRiMWQtYTljOS1jYTgwNTZhYTc0MjkifSwibmFtZSI6eyJTIjoiNWNkYTViOGEtZTgyMy00MGFiLWJhMjYtM2EzMDcxNGU0OWIwIn0sImIiOnsiQk9PTCI6dHJ1ZX19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "d61cc3908da63b29", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "345" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JLP6K5AV7PBRF1VMJ057QM9EO7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "219eed47a1600559", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "272" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2539483134" + ], + "X-Amzn-Requestid": [ + "U9NIJIFA18RNP0BNHMIVC8J43FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiNWI0YjdmYTUtMjg0NS00MzA1LThjZmUtOTIyNDMxMzZmZjI3In0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RDcmVhdGVTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJOVUxMIjp0cnVlfX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "bb81c9e41b1e459c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "365" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8JKVG0SS7A825MAH9VJE6IF5FFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "79dd56e46191db2c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "249134433" + ], + "X-Amzn-Requestid": [ + "PQVT0A93AGCN4GDR6I941D5H87VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiMDRiOWIyZGYtODhjYi00MGZhLTg4ZTUtNDA3NWI3ZmJjOWI0In0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6ImJkMmNhNjc3LTg3MjAtNDFiZi05OWY4LTZlZWJjYWY1ZDhmNSJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "33a264d9bd8743ae", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "365" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FJTULJOPTKSV0FCOG3L8MAG69RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "71c44cdbf30b1fb0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:23 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1785255644" + ], + "X-Amzn-Requestid": [ + "LIAE8HA0NSJV186QOC9HFCPCJBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiZjUwNDUxMTQtNjAzMC00NWIzLTllMmMtMmM0YjlkMTUxMWU4In0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6ImRhMWNlOGRiLWJhMTAtNGE1Yy1hYmIzLWYxZmU3ZjJlYmVkMCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Data.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Data.replay new file mode 100644 index 000000000..7b139439d --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Data.replay @@ -0,0 +1,2122 @@ +{ + "Initial": "AQAAAA7gDNWEIoxXCQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "c0ddd21433598551", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "0KJNMTT8VTKT88AJ1IIO34NOBJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "f9bc5b818463aabd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1393" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3146450670" + ], + "X-Amzn-Requestid": [ + "CUN0FNLJ27NDG2VOI95MS4KVU3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoic3RyIn0sIlUiOnsiTiI6IjQifSwiRiI6eyJOIjoiMC41In0sIkV0YWciOnsiUyI6ImFkMjNkMzVmLWU5NjEtNDQ3OS1iMmIwLWQ5OWFjMGY5MWYyZiJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0In19LHsiRXRhZyI6eyJTIjoiYzE5OTY4NDktNTEyMC00OGQzLWE2NWYtNDM5YjRiYmI4YTE5In0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvbk1hcCJ9LCJzIjp7IlMiOiJjIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJzdHIifSwiVSI6eyJOIjoiNCJ9LCJGIjp7Ik4iOiIwIn0sIkV0YWciOnsiUyI6Ijc1MzZlYTBhLTIzZjAtNGE1NC1hYTQ4LTVlZDExODMyMDQ5YiJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0V3J0In19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJzdCJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAuNSJ9LCJJIjp7Ik4iOiIxIn0sIkV0YWciOnsiUyI6IjAwNzlkOTljLWU4NmYtNGYwNy1iY2ZkLTIxYTY5MGUyNGI4MiJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0SW5jIn19LHsiYSI6eyJTIjoiQSJ9LCJpIjp7Ik4iOiIzLjUifSwiRXRhZyI6eyJTIjoiOGQ1MWYzYjItOTUzOS00OTAwLTkwMjktNmE5ZjhiNjZhMjhjIn0sIm0iOnsiTiI6IjMifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBJbmMifX0seyJhIjp7IlMiOiJYIn0sIkV0YWciOnsiUyI6ImFmMWM1MzQzLThkNTItNDRkMS1iNjg5LTNlZGFkMzQxODA2MSJ9LCJjIjp7IlMiOiJDIn0sIm0iOnsiTiI6IjMifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXAifX0seyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwicyI6eyJTIjoiYyJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiJlYmJiMmZmYy1kYjAzLTQ4ZDktYWU3OC1iYjIyZDUyYjIxOWQifSwiTSI6eyJOVUxMIjp0cnVlfSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LHsiYSI6eyJTIjoiWCJ9LCJFdGFnIjp7IlMiOiJhMjM0NTIwNi1jNWVjLTRjMWItODM4Yy02MTIwMjU5NGI5Y2MifSwibSI6eyJOIjoiMyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwV3J0In19XSwiU2Nhbm5lZENvdW50Ijo4fQ==" + } + }, + { + "ID": "3a82523069e32e74", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3NQH2THHSO2FV0B4JSLIE5IPBNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "dd64a28cc9076225", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FUQLQHDDVO8UE0CV6HFV9P3RO7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c9d5d0c194ebea8b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LO3CR4PR53B8VKR2OA8QKH8R97VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b50d828baf5c1711", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "74" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FHUUPOI7DU8VUV4BUT4F5U37K7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2abd946075c43c87", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "1GDBD27SN9EA72D0BGVROKQO93VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f5720dc1529ae139", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "90TC0P164M4HPI16F0G4U19IQJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e84ab5294dc10d5f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3L3IMRJPT2LMLNBA9ADARVEITRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "74e50ab80b195d66", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "74" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M11TLC4TQ5106BC7KESOLF4VLFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ac1ede7ba2ee4932", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7EFQT0KV8M4IHPDKOKUG81JPEFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "efa66932749f18db", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3054047241" + ], + "X-Amzn-Requestid": [ + "L5PLANCFDESAL91T254RT305MNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6Ii0xIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "c0f0636d530db56f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "022E5LI1UVBA2VV9A0R3MP8L6FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9d30923a8ff92761", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3121808892" + ], + "X-Amzn-Requestid": [ + "AH9C1VMBRJO627N6B4CHDOGDTVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6Ii04In19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "6f92e2fe27812b11", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MJFQLBB7M732OV2ML4RA2BEF3BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "833365da1448d30e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "100" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2455135972" + ], + "X-Amzn-Requestid": [ + "A68BDE8PCLALAVBUBIHFFKQA4FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6Ii0xNiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "a30bd2306b5c8bf8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "S60CHEKEMIKFR9TUR59E6GRPUJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "62026f8ab3411bc5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "100" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385046232" + ], + "X-Amzn-Requestid": [ + "3DSBM97OJTIG50CRR1OFO11DANVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6Ii0zMiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "1121f7c0cde121cf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0832P4137JL8TAORPMLHUFTD6BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "da4eab6c7e044f39", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "100" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1666946403" + ], + "X-Amzn-Requestid": [ + "VMEHF2T4DP8QKNHR429VOPPJBRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6Ii02NCJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "0d82a03b0eef4bdf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "80" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "76NFL3NINUP4BFRQ7HSUC4Q94NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bde9e5b6ea3ca263", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "98" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2670645296" + ], + "X-Amzn-Requestid": [ + "DGV1P3FJ6RN80J2CU1IICOO5S7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "d7f7c2cb47235173", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "80" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "AJ6LE4POE4FC44TQVF31T9MO8FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "de77d84b5a96fb9e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "98" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2469709253" + ], + "X-Amzn-Requestid": [ + "FMSEQ3OJ3S4R10DUNHDUU2C5INVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjgifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "2cf236c0338b3a72", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DTV3235FINF87N7JKMQVUDSO93VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5e8b789ff184871a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3447376172" + ], + "X-Amzn-Requestid": [ + "FRGJ2T87O5G8VV6QHR4JU10NGNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjE2In19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "f71a8d1dc7c47833", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CE19BFFMJ2VRL5AGPSU5HQ41TJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "556ee1743d7df42b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "228757264" + ], + "X-Amzn-Requestid": [ + "MU3LQ1KSM7UKQ4ANTGP0810TE7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjMyIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "c67408357c8eb039", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GICGKC4590BR85B1R6R6C22TSBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6489fd289d5f02d2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:41 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1014446763" + ], + "X-Amzn-Requestid": [ + "KOOO44R8M18EECKI9OTM29P65FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjY0In19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "9b25de7e65c61f2f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "BC3KAK3B67DRIBC8B6MNH104BRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2e6b71b8be1b596c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "100" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2334279914" + ], + "X-Amzn-Requestid": [ + "PQ8DDM05EL17HJJ0U6BQ293TCVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiTiI6IjMuNSJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "22cbd0fc12431e1c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "83" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5AGBMCGAG177FIHA6IQELOH4VBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "57033d816b4839cd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "101" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "129752700" + ], + "X-Amzn-Requestid": [ + "J2JA5TB0MIBFJ2T7OUF2M45INBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0RGF0YSJ9LCJ2YWwiOnsiQiI6IkFBRUMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Delete.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Delete.replay new file mode 100644 index 000000000..1fe4e5d2b --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Delete.replay @@ -0,0 +1,2061 @@ +{ + "Initial": "AQAAAA7gDNV+Jgu8xgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "365aea3a658cd862", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "7EMN6727EPRUD1K6P39NCDDQGVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "15132062378c0fed", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1139" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "771391000" + ], + "X-Amzn-Requestid": [ + "G3TI11M3CU9RLFE0FRBABAC9GVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7ImkiOnsiTiI6Ijk1In0sIkV0YWciOnsiUyI6IjJiNTZiNGI5LThjZGQtNGIwNC1hNTdiLTRmMWVlMjNmYjA2MyJ9LCJzIjp7IlMiOiJhIHN0cmluZyJ9LCJtIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRNYXBGUCJ9LCJmIjp7Ik4iOiIzMi4zIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJhIHN0cmluZyJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjMyLjMifSwiSSI6eyJOIjoiOTUifSwiRXRhZyI6eyJTIjoiNTY4OTE3ZWQtMDA0My00ZmM3LWIyMGQtNWJjNTY3NDVhYTk0In0sIk0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSBzdHJpbmcifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIzMi4zIn0sIkkiOnsiTiI6Ijk1In0sIkV0YWciOnsiUyI6IjI5NjA2MGI0LTViZjctNGUxMS1iMzdjLTgyYWMxMzliYjU1MiJ9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3RXQyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fSx7ImkiOnsiTiI6Ijk1In0sIkV0YWciOnsiUyI6IjNkNTAxYmZhLTZhMGItNGM1Mi1hMzIxLTM0YWQwY2Y0NDcxYSJ9LCJzIjp7IlMiOiJhIHN0cmluZyJ9LCJtIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRNYXAifSwiZiI6eyJOIjoiMzIuMyJ9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSBzdHJpbmcifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIzMi4zIn0sIkkiOnsiTiI6Ijk1In0sIkV0YWciOnsiUyI6IjkyMDliYmJmLTFiNmMtNGFlZi05M2UwLWQxYjM5NTQ2OGFkNSJ9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3RGUCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV0sIlNjYW5uZWRDb3VudCI6NX0=" + } + }, + { + "ID": "355222c7fd191b5f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "EE8FNNNCITJ712MUFVVOEGP5CVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "330ede344bee4b98", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9B5H8FAH4SDRRM6PA6P8S2A6L7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fda2a3dcf4bd9da8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "S28BUO8UITR0JDR4JUPAPULV1BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "71c6d99446eb32e0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FOMKAR4B2M4T6JSBMMKRTDT7PNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c4e6060fc6c1a8ef", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JFG3PGFTUG4JMRS46N7GRSURTFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "263878d6b683ae78", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "133" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8M3P6SDRAS694S86JU9DLM6SVNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "352a367fedb8c4d6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "233" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "BGU6A9JKL4HQAT6G2N9393ND53VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9ddd09c6e1e15db9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "36FQKG5V9S8C55ENAAMNT6PURFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "3171bb75c7b94e9d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "151" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "73DMLMUEBG2O0RUOUORFJ6UD3VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6db8ff7bb18b179b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "233" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "HT9278PHMK1IO4RSUIFI6MCBU7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "fb200a0e94769f43", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "255" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "E705TA20U13RP17LML09UIFUGRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f0180dc4908a1b63", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "236" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "REDM6A4A1T5IGRFKTKUKSMAK07VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "11f69172efd7de3b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "M7K1SKG3G5O194FQ7TGBIU2VIRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "b7fbdc00536b8860", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "L0982OO32F6VBUH0E18FLE97ABVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f0dbcdbdac4b519c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "236" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "VNVDAC5P2OP42HUQC44C7VDC9BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "8f074a21d8b25a11", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "Q6LPR1KTG4O015JRUMLLS7KAO7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a99571a51a56a766", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "P2QNRI2IGRUPG2FMUBE20GI0N7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "0ba46c8ba82c4ea6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "367" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3296419173" + ], + "X-Amzn-Requestid": [ + "HTTH5UJOHRPSA7LH4DOKGU371BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3REZWxldGVNYXAifSwiYiI6eyJCT09MIjp0cnVlfSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiY2E2YWE1MDctZTEwMC00MjY5LTg3ZTEtY2RkZjFhNDI0NzlmIn19LHsiQiI6eyJCT09MIjp0cnVlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3REZWxldGVTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiN2UyODljMTgtNmFjNS00NDRiLTlmZGQtYTBlNDgxOGYxZjkxIn19XSwiU2Nhbm5lZENvdW50IjoyfQ==" + } + }, + { + "ID": "ebafd779544376e5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "A04JO6JQCMORUR3OF7BS8JBLKVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "84ceb8584f320a18", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6NKG97R18D3VN84D9EO1O4OBLFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6d45ff6388609c1d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "121" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CR5O46HIBQQ2RQOEA38058Q3V7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3902f5912a429492", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "221" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8461V1OCJDAI448E6A2FMPHGLRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0c682e1027734320", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "7QHS0PC9R2N07S50E1AI9TQ7J7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "6314e9224fc04ece", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "139" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "MHGD0VA1FF37RD9ECFIS0GNBURVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3919be88347bda6e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "221" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "MSOQ5G6TC6KV8JU5DOQSRHCTCRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "6ad166d678637b6a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "255" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FN7KMD412F7C6CH4FFD87SEQ0JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "25356377fee113c1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "224" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GEE5H5EGSLLSQ8ST8A1CQAVABJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "75ab6138a8805abc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "L52OO7RT7L0L5B5KMA3NKF5A17VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "df57b179a036b219", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "39PI8ATNPUEUV6K5677GHP2KS7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d7031c11fd6b805b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "224" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "1JOKTG0C050PGKB23Q3BFMEVFBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "44806b044091a1de", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "2PMT1HUQI1EP6Q5MIGMANN1JKBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/ExampleInDoc.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/ExampleInDoc.replay new file mode 100644 index 000000000..a882a7c8b --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/ExampleInDoc.replay @@ -0,0 +1,658 @@ +{ + "Initial": "AQAAAA7gDNWPCU2WtwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "f08b9c4592a830df", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "5SRQOFJUE6BLI2ET2M9E1K6DANVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "56b058ddaa88a2f4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "130" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2772784065" + ], + "X-Amzn-Requestid": [ + "DEK0MT0FU0GO2MP3N6IPVTSTDJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7IkkiOnsiTiI6IjEifSwibmFtZSI6eyJTIjoicHV0YW5kdXBkYXRlIn19LHsiSSI6eyJOIjoiMCJ9LCJuYW1lIjp7IlMiOiJjcmVhdGVhbmRyZXBsYWNlIn19XSwiU2Nhbm5lZENvdW50IjoyfQ==" + } + }, + { + "ID": "233708c3e294b7ce", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "52QFEGCQ35H7H8J78PNFB246R3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0efad3bfd92cfc96", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "G7PH0NIKKM5SODVT1LQHN16IHVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f2af3b2c6c18628b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "282" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JROVQDR40V8SFJ1P0ABGUSFFURVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2eac5dc4e086297f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "185" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VPH2P5VL6AFG6EK0H96KA1C9VBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3fac88cb51a89cd9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "147" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "356" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "704779417" + ], + "X-Amzn-Requestid": [ + "TEH9BGJ4C46HNCJ68EKDV9VLQRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJwdWJfeWVhcnMiOnsiTCI6W3siTiI6IjE5NjcifSx7Ik4iOiIxOTczIn1dfSwibmFtZSI6eyJTIjoiVGhlIE1hc3RlciBhbmQgTWFyZ2FyaXRhIn0sImF1dGhvciI6eyJNIjp7Ikxhc3QiOnsiUyI6IkJ1bGdha292In0sIkZpcnN0Ijp7IlMiOiJNaWtoYWlsIn19fX0seyJwdWJfeWVhcnMiOnsiTCI6W3siTiI6IjE5NjgifSx7Ik4iOiIxOTg3In1dfSwibmFtZSI6eyJTIjoiVGhlIEhlYXJ0IG9mIGEgRG9nIn0sImF1dGhvciI6eyJNIjp7Ikxhc3QiOnsiUyI6IkJ1bGdha292In0sIkZpcnN0Ijp7IlMiOiJNaWtoYWlsIn19fX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "482015ff88e27581", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "192" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "338" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2286982984" + ], + "X-Amzn-Requestid": [ + "KVKVBSCD6ETOH21U94VSF78H9BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7InB1Yl95ZWFycyI6eyJMIjpbeyJOIjoiMTk2OCJ9LHsiTiI6IjE5ODcifV19LCJuYW1lIjp7IlMiOiJUaGUgSGVhcnQgb2YgYSBEb2cifSwiYXV0aG9yIjp7Ik0iOnsiTGFzdCI6eyJTIjoiQnVsZ2Frb3YifSwiRmlyc3QiOnsiUyI6Ik1pa2hhaWwifX19fSx7InB1Yl95ZWFycyI6eyJMIjpbeyJOIjoiMTk2NyJ9LHsiTiI6IjE5NzMifV19LCJuYW1lIjp7IlMiOiJUaGUgTWFzdGVyIGFuZCBNYXJnYXJpdGEifSwiYXV0aG9yIjp7Ik0iOnsiTGFzdCI6eyJTIjoiQnVsZ2Frb3YifSwiRmlyc3QiOnsiUyI6Ik1pa2hhaWwifX19fV0sIlNjYW5uZWRDb3VudCI6Mn0=" + } + }, + { + "ID": "e44390c47cd7618e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V45JQNP3I63VOAMM6TSJ09E5IVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "308b56a0c9f2760f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "79" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:51 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JK8B593PQOIL6T6PE7FI1L5N3JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Get.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Get.replay new file mode 100644 index 000000000..bfff47926 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Get.replay @@ -0,0 +1,2183 @@ +{ + "Initial": "AQAAAA7gDNV8H8xzmwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "2628868d8d9ef14d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "O8042HF0VK3FC219T1L21AUASFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "29ffc7f101cf6b1c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "664" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2605401374" + ], + "X-Amzn-Requestid": [ + "1T5I710T0SEN813TO4DLCM6TIJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7IkV0YWciOnsiUyI6IjQzMzdjNTZiLWU0YjctNDNjMS04N2ZkLTQ2M2E5OGJjYmRjNCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZU1hcCJ9LCJzIjp7IlMiOiJiIn19LHsiRXRhZyI6eyJTIjoiZDY5NzVmNjctMGM0Ny00YzFmLTlkMDYtNzQ4OTIwYWRlODY2In0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvbk1hcCJ9LCJzIjp7IlMiOiJhIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJiIn0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiUyI6IjFhMjdhYjg4LWNlZTUtNGVjZi1hYzhlLTQxYzg2MjVmYTNlMyJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZVN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiJhZDc0MjdjYy02ZDgzLTRhMzYtOTVmZi0yMTk3ZDY3NjE5MDAifSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19XSwiU2Nhbm5lZENvdW50Ijo0fQ==" + } + }, + { + "ID": "f836e2e8d9294b68", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M60PH7S4TT3HN9F6IM82N3IJPFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f68be19c408296f4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "1G26A791M5L4IDA1A7DUC49IG7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "884f11ab741f39e1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "396THCPHT9CNJJU46SU79VVN3BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7fa8de8a3e89a2c4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FLC9OOP002H5N8K6MQQ0FFDHFBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c41543c62a885c28", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "227" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "J8V2PNBBCKOJDLIMT6JU64BUDFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "baf3ce3162125144", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "245" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2119605892" + ], + "X-Amzn-Requestid": [ + "TVD065OP7IQMES428TOMF3T2LFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJpIjp7Ik4iOiI5NSJ9LCJzIjp7IlMiOiJhIHN0cmluZyJ9LCJtIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRNYXAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYjEzNGQyODMtYTkxMC00Y2Q0LTk1MjUtNTBmMmU4MWE1N2JkIn0sImYiOnsiTiI6IjMyLjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "c1ce566b5d05888b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "285" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8MACLN5EKBHHLDSF1NL8T1J6HVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e5989ea7298eb4bc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "303" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4174898976" + ], + "X-Amzn-Requestid": [ + "F8IICE5ALOREU5M2PC57QH92L7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEgc3RyaW5nIn0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMzIuMyJ9LCJJIjp7Ik4iOiI5NSJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik0iOnsiYSI6eyJTIjoib25lIn0sImIiOnsiUyI6InR3byJ9fX0sIm5hbWUiOnsiUyI6InRlc3RHZXRTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjA1MThhODEtZjE1ZS00Mzg2LWEyMWYtYjRkNTFlZWIyYzIwIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "b8e23801ed4a9ad3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "229" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "RIDD32FQV2R4K2R8EV71JC5D37VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9a395dd2a428e787", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "195" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "527308508" + ], + "X-Amzn-Requestid": [ + "4M9E1E1RIT497OE4KK9LNIDN53VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJtIjp7Ik0iOnsiYiI6eyJTIjoidHdvIn19fSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiY2M2NGM5ODctYmU5ZS00Mjc2LWI2NDEtYjU0ZGIwMDQ5YTdhIn0sImYiOnsiTiI6IjMyLjMifSwibmFtZSI6eyJTIjoidGVzdEdldE1hcEZQIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "7b6a4ef101434b06", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "287" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SEN0PR01PSEE9CP8DILJ3GDD7NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a3ab0ba437e90f0c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "238" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "203" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3671362033" + ], + "X-Amzn-Requestid": [ + "LSUFGP73KLLTPK4V36S1H6IR17VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJTdCI6eyJTIjoiYSBzdHJpbmcifSwiTSI6eyJNIjp7ImEiOnsiUyI6Im9uZSJ9fX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjQ5NTljYjA5LWY1NGUtNDRlNS1iZDRmLWEzZTk3MDEwNDNkMyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0RlAifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "e4d6d34d1e512384", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "287" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "O7L47B06U2OFVS7KRPK79LMHGBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a86e8ebda64be9ba", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "210" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "89" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2845408016" + ], + "X-Amzn-Requestid": [ + "L03PQSHHRBC6KGD42R3QUNT4HJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0V0MifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "c8557648fcab586b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "99" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "78IMC8GE0UMVI037ISOUU2HB8RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "da038b22c281545b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "OQCK2VG80KEP2KLVJOF19CN6DRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "4f16bea000407ff6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1163" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2578224509" + ], + "X-Amzn-Requestid": [ + "ERDSQEUPJRQUM18GJ80BE9JDSRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7ImkiOnsiTiI6Ijk1In0sInMiOnsiUyI6ImEgc3RyaW5nIn0sIm0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldE1hcEZQIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImNjNjRjOTg3LWJlOWUtNDI3Ni1iNjQxLWI1NGRiMDA0OWE3YSJ9LCJmIjp7Ik4iOiIzMi4zIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJhIHN0cmluZyJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjMyLjMifSwiSSI6eyJOIjoiOTUifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJNIjp7ImEiOnsiUyI6Im9uZSJ9LCJiIjp7IlMiOiJ0d28ifX19LCJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjYwNTE4YTgxLWYxNWUtNDM4Ni1hMjFmLWI0ZDUxZWViMmMyMCJ9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSBzdHJpbmcifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIzMi4zIn0sIkkiOnsiTiI6Ijk1In0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdFdDIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImNiNTE0MTFkLWJiZmQtNGMyOC1iZjg5LWMyNWQ1NDRhYWM3OCJ9fSx7ImkiOnsiTiI6Ijk1In0sInMiOnsiUyI6ImEgc3RyaW5nIn0sIm0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldE1hcCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiMTM0ZDI4My1hOTEwLTRjZDQtOTUyNS01MGYyZTgxYTU3YmQifSwiZiI6eyJOIjoiMzIuMyJ9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSBzdHJpbmcifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIzMi4zIn0sIkkiOnsiTiI6Ijk1In0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifSwiYiI6eyJTIjoidHdvIn19fSwibmFtZSI6eyJTIjoidGVzdEdldFN0cnVjdEZQIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjQ5NTljYjA5LWY1NGUtNDRlNS1iZDRmLWEzZTk3MDEwNDNkMyJ9fV0sIlNjYW5uZWRDb3VudCI6NX0=" + } + }, + { + "ID": "7a64031f76059194", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V356M297QTVCN8T29N2HIN4L3JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e08899fd09f49a62", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5OANEBOB39UV16D647AI5IDCPFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0bd790908262ce02", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "67" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OMGV1QMTC2U6BQK68F92RCJLOFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ffb0371e95589f55", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SLLR04LCOHH0EL4IIKNGFI841BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "dcba229211b79c69", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:33 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "E6OLOIEH30Q3DO6UREQBHHOIS3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8398cdb180050abd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "215" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PCQQ5JSI45DLMJBR90PQMC35V7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d7eb9e0addf92b3d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "233" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "158417208" + ], + "X-Amzn-Requestid": [ + "7E240QSF96IGQ5EMB25P62116NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJpIjp7Ik4iOiI5NSJ9LCJFdGFnIjp7IlMiOiIzZDUwMWJmYS02YTBiLTRjNTItYTMyMS0zNGFkMGNmNDQ3MWEifSwicyI6eyJTIjoiYSBzdHJpbmcifSwibSI6eyJNIjp7ImEiOnsiUyI6Im9uZSJ9LCJiIjp7IlMiOiJ0d28ifX19LCJuYW1lIjp7IlMiOiJ0ZXN0R2V0TWFwIn0sImYiOnsiTiI6IjMyLjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "60172e6d38e7e7d8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "285" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "U5FEUSTIAN98V9HHFN8GB5E0MVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5964dcfc28b96184", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "303" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3582895283" + ], + "X-Amzn-Requestid": [ + "9TOMRLI2TPUSP5S0B8FR2QN753VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEgc3RyaW5nIn0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMzIuMyJ9LCJJIjp7Ik4iOiI5NSJ9LCJFdGFnIjp7IlMiOiI1Njg5MTdlZC0wMDQzLTRmYzctYjIwZC01YmM1Njc0NWFhOTQifSwiTSI6eyJNIjp7ImEiOnsiUyI6Im9uZSJ9LCJiIjp7IlMiOiJ0d28ifX19LCJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "a66b66f58e9b2748", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "217" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VA7R4EJ7K9NVU3KGLUSOC7BE4VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "265bf0e00830105e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "222" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "183" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3800270538" + ], + "X-Amzn-Requestid": [ + "KFVT71OOCFC7NUO1JP3K87VGMBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiIyYjU2YjRiOS04Y2RkLTRiMDQtYTU3Yi00ZjFlZTIzZmIwNjMifSwibSI6eyJNIjp7ImIiOnsiUyI6InR3byJ9fX0sImYiOnsiTiI6IjMyLjMifSwibmFtZSI6eyJTIjoidGVzdEdldE1hcEZQIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "5cadbc58f1e9ff9e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "287" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "G4Q4559K0DAHQ38IGM0B26D9UJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a6ca93448e5d47e0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "226" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "191" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1607822566" + ], + "X-Amzn-Requestid": [ + "AN64MCBF6P12UP9RK59OAGFHIJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI5MjA5YmJiZi0xYjZjLTRhZWYtOTNlMC1kMWIzOTU0NjhhZDUifSwiU3QiOnsiUyI6ImEgc3RyaW5nIn0sIk0iOnsiTSI6eyJhIjp7IlMiOiJvbmUifX19LCJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0RlAifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "65a1efe6adb099ee", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "287" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M6T8D9F0DG5SLP68HI6NV65L8NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e742bdc91b6fcaf7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "210" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "89" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2845408016" + ], + "X-Amzn-Requestid": [ + "DP0HABB0GCBFBRP9N6JQR38PFBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0R2V0U3RydWN0V0MifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "83c58bee749e7998", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "99" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:34 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "OA1IPHEBJJGKOJOU227KT4T3OBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/GetQuery.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/GetQuery.replay new file mode 100644 index 000000000..1e4145c8a --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/GetQuery.replay @@ -0,0 +1,2976 @@ +{ + "Initial": "AQAAAA7gDNWMJ1DeCgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "2dff1e3209d784ac", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1609" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3233200316" + ], + "X-Amzn-Requestid": [ + "V8QHT9J20N9F737NTM6B2SGPVFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIkF0dHJpYnV0ZVR5cGUiOiJTIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJBdHRyaWJ1dGVUeXBlIjoiTiJ9LHsiQXR0cmlidXRlTmFtZSI6IlRpbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwODA2OTVFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkdsb2JhbFNlY29uZGFyeUluZGV4ZXMiOlt7IkluZGV4QXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMi9pbmRleC9nbG9iYWwiLCJJbmRleE5hbWUiOiJnbG9iYWwiLCJJbmRleFNpemVCeXRlcyI6MTA3LCJJbmRleFN0YXR1cyI6IkFDVElWRSIsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiUGxheWVyIiwiS2V5VHlwZSI6IkhBU0gifSx7IkF0dHJpYnV0ZU5hbWUiOiJUaW1lIiwiS2V5VHlwZSI6IlJBTkdFIn1dLCJQcm9qZWN0aW9uIjp7IlByb2plY3Rpb25UeXBlIjoiQUxMIn0sIlByb3Zpc2lvbmVkVGhyb3VnaHB1dCI6eyJOdW1iZXJPZkRlY3JlYXNlc1RvZGF5IjowLCJSZWFkQ2FwYWNpdHlVbml0cyI6NSwiV3JpdGVDYXBhY2l0eVVuaXRzIjo1fSwiV2FybVRocm91Z2hwdXQiOnsiUmVhZFVuaXRzUGVyU2Vjb25kIjo1LCJTdGF0dXMiOiJBQ1RJVkUiLCJXcml0ZVVuaXRzUGVyU2Vjb25kIjo1fX1dLCJJdGVtQ291bnQiOjEsIktleVNjaGVtYSI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJLZXlUeXBlIjoiSEFTSCJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIktleVR5cGUiOiJSQU5HRSJ9XSwiTG9jYWxTZWNvbmRhcnlJbmRleGVzIjpbeyJJbmRleEFybiI6ImFybjphd3M6ZHluYW1vZGI6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3Njp0YWJsZS9kb2NzdG9yZS10ZXN0LTIvaW5kZXgvbG9jYWwiLCJJbmRleE5hbWUiOiJsb2NhbCIsIkluZGV4U2l6ZUJ5dGVzIjoxMDcsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiR2FtZSIsIktleVR5cGUiOiJIQVNIIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJLZXlUeXBlIjoiUkFOR0UifV0sIlByb2plY3Rpb24iOnsiUHJvamVjdGlvblR5cGUiOiJBTEwifX1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMiIsIlRhYmxlSWQiOiIwZDRmOTk4My1kOGE5LTRhZjEtYTY0NC05YmE3M2NlMGYyMjciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIiLCJUYWJsZVNpemVCeXRlcyI6MTA3LCJUYWJsZVN0YXR1cyI6IkFDVElWRSIsIldhcm1UaHJvdWdocHV0Ijp7IlJlYWRVbml0c1BlclNlY29uZCI6NSwiU3RhdHVzIjoiQUNUSVZFIiwiV3JpdGVVbml0c1BlclNlY29uZCI6NX19fQ==" + } + }, + { + "ID": "d7daff1425f8964c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "191478508" + ], + "X-Amzn-Requestid": [ + "6GOQ0MDC8B166V0CI7DG3PBRJRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWQ3ZTk4NjktNmY3NS00YzI0LWFlZWQtMWZjNzFiYWI0Y2IxIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlM2NjNTUxZi00NjYzLTQxMzEtYWUwNy0zOTU0OTNmNWMyZGYifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZTY3MDkzYzItMjkxNS00OTg0LWJhNWItY2QzYmRjYmFjZTk4In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiNWY5NzY5LWY5YmItNDZiNy05YzYwLWFlNTY3NzlkZTdhOCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYjVmNWM0OTYtZGFmMy00MDUxLTljMmQtM2Q0OWY3YjUzZDExIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI5MjIyODRkOS0wYWYzLTRkMWEtODI4Ni1lYjRlOWY5YTc5ZTQifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNmE1OGZiNzMtMWU4Ny00YTVkLWFjYTQtYWY4NzcxZDE1ZTBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijk0NDUzN2MyLTk5NWItNGUyMS05NDg1LTExYWRlZjI2YWZjZSJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "f3971433bda94d68", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "260" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UVA1IB1OKN02C6TQ1N35MF205JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8e72062a36daf45b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M1K07BTOI9HQS40515FA2M7V4JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cd529b85ddb9ffa1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "260" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "18T3FPQTNIK5OEAA65JO2E3243VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6a5b6352c56fd272", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "IUFQSA823VD83FED8JC3V2R007VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "96c7203be9e500d0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "L9KQ71AIV850ACQGVS7VML0GJ7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bf6ecd0ee12d99fd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "B7DQ3UEEBEK2KS260A053M24V3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3824b2080e4f2648", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "261" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:48 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "173LB8QUILEEUAH0UHRQPA1KQBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "637b3f084f6c1c67", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "261" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "16O5Q50F3592R4CURGTNI2MT0VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "be0f238cf160b0c3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "244" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "PR49ENBAFVBST007N83NKE5DM3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "580f41579c151a7c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "244" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SF3L1625BPD8CB08MTVROIATDRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "135b27a537698ca4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JL9MP1V735IOAS1F2O53QSJ62RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9ee7645a4b76bc48", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "238" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "F9ER3O7245IMSLD92IICUG6B2FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4e0acb16aa568d6a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "235" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "BJ27BM69NIP1ERE3GA5ST0Q23BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d5d488882811bf93", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8IEP5Q65V9J68QRDB6V5R9MDVRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b670e6531d2f0d21", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "2D85G2JVC2P1EV7AQVGO1DIQ1NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a0817a3919ad7044", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "4U3GAV5NN3LVPBKNFE55J1JNSVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6ee81cdfb142dcfe", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "IAFMMMO82UH4HH1B89PUPLLEBRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "f92b147c7dde4cbd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "184" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "827" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "939543948" + ], + "X-Amzn-Requestid": [ + "IKVD0E2RI5L59OU3AGU6PH5777VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fV0sIlNjYW5uZWRDb3VudCI6NH0=" + } + }, + { + "ID": "db5fb0dc6e1540cb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "172" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "630" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "6233728" + ], + "X-Amzn-Requestid": [ + "IFMQHM3EUNNCOBD5SDRMDO74VBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xOFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjE5MCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImVmYzU5YTY5LWI3MjAtNDdlOS1iNDk4LTBlNWNjMDQ5OGE4YyJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6dHJ1ZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMDFUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiIxMjAifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIyYjkzNzEwMy03MmEzLTRhYzEtYWUyZC0yYjQxMzQyZDM4ZTAifX1dLCJTY2FubmVkQ291bnQiOjh9" + } + }, + { + "ID": "b3b619faa088d217", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "203" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "238" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3506531083" + ], + "X-Amzn-Requestid": [ + "2IQ102I6RRMQTUDV71JMP4D7A7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IlBsYXllciI6eyJTIjoiYmlsbGllIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19XSwiU2Nhbm5lZENvdW50IjoxfQ==" + } + }, + { + "ID": "eb673aab0bba92ba", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "241" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "244" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2563490042" + ], + "X-Amzn-Requestid": [ + "9B056BTCBDFHD08CHJPAT32D6BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19XSwiU2Nhbm5lZENvdW50IjoxfQ==" + } + }, + { + "ID": "dc30e8bb7e867b83", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "259" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "243" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2349370659" + ], + "X-Amzn-Requestid": [ + "6PL57R9GRFMB118Q6CU2IRP2V3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IlBsYXllciI6eyJTIjoicGF0In0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTEzVDAwOjAwOjAwWiJ9LCJTY29yZSI6eyJOIjoiNDkifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2OWNkYzY1MC0yMjM5LTRlNzQtOGYzMy05MmFhN2JkNGRiZWIifX1dLCJTY2FubmVkQ291bnQiOjJ9" + } + }, + { + "ID": "97fdae53cdbf4b14", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "259" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "449" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "941895975" + ], + "X-Amzn-Requestid": [ + "5QDVP4RAFFLN9IIP5G5SLR387NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlNjb3JlIjp7Ik4iOiI2MCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIxM2YwMDZiZS0yMmQ0LTQwMDgtOTM0YS03MWI5ZDdhYjY1MDYifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiUGxheWVyIjp7IlMiOiJhbmR5In0sIlRpbWUiOnsiUyI6IjIwMTktMDItMDFUMDA6MDA6MDBaIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjA2Mzk2YzMyLWVlOGYtNDdkNS04OTg0LTRhN2YxOWUyZTQwZCJ9fV0sIlNjYW5uZWRDb3VudCI6Mn0=" + } + }, + { + "ID": "4e4269b6d4c6a295", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "262" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "439" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4040240867" + ], + "X-Amzn-Requestid": [ + "B7R20KCSB3IHNGIVD57DJ30IHJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7IlBsYXllciI6eyJTIjoibWVsIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJTY29yZSI6eyJOIjoiNjAifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIxM2YwMDZiZS0yMmQ0LTQwMDgtOTM0YS03MWI5ZDdhYjY1MDYifX0seyJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19XSwiU2Nhbm5lZENvdW50IjoyfQ==" + } + }, + { + "ID": "7c2ef54646aa04b0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "639" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1949309610" + ], + "X-Amzn-Requestid": [ + "GAP1BL0TVAR7SUVL8OP86S9RJNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xOFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjE5MCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImVmYzU5YTY5LWI3MjAtNDdlOS1iNDk4LTBlNWNjMDQ5OGE4YyJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiNjAifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIxM2YwMDZiZS0yMmQ0LTQwMDgtOTM0YS03MWI5ZDdhYjY1MDYifX1dLCJTY2FubmVkQ291bnQiOjh9" + } + }, + { + "ID": "f3ff775f01c888af", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "200" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "639" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3100798559" + ], + "X-Amzn-Requestid": [ + "GRG29DD59OQHP2VQUKMT7U52H7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTEzVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9LCJTY29yZSI6eyJOIjoiNDkifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2OWNkYzY1MC0yMjM5LTRlNzQtOGYzMy05MmFhN2JkNGRiZWIifX1dLCJTY2FubmVkQ291bnQiOjh9" + } + }, + { + "ID": "27ef4677a69f6df4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "206" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1048" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "181428449" + ], + "X-Amzn-Requestid": [ + "CKI9T20OHK25N11B34GIGQO2U3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTIwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImZyYW4ifSwiU2NvcmUiOnsiTiI6IjMzIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOGM2NGJhMDYtMTJlZC00N2YwLTgzMDctOWQ3Mjg2ZTcyZjBiIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xOFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjE5MCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImVmYzU5YTY5LWI3MjAtNDdlOS1iNDk4LTBlNWNjMDQ5OGE4YyJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19XSwiU2Nhbm5lZENvdW50Ijo4fQ==" + } + }, + { + "ID": "69c68cbc35705037", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "179" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "430" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2892341150" + ], + "X-Amzn-Requestid": [ + "N1TIPL0LGS539EJFGRGCI1HDQNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6dHJ1ZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMThUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiIxOTAifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZmM1OWE2OS1iNzIwLTQ3ZTktYjQ5OC0wZTVjYzA0OThhOGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9LCJTY29yZSI6eyJOIjoiMTIwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmI5MzcxMDMtNzJhMy00YWMxLWFlMmQtMmI0MTM0MmQzOGUwIn19XSwiU2Nhbm5lZENvdW50Ijo4fQ==" + } + }, + { + "ID": "836a235fb5bf2df1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "182" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "430" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:49 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2892341150" + ], + "X-Amzn-Requestid": [ + "K3LOJ8C8B1CICBQ2IRP52CS06VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6dHJ1ZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMThUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiIxOTAifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZmM1OWE2OS1iNzIwLTQ3ZTktYjQ5OC0wZTVjYzA0OThhOGMifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9LCJTY29yZSI6eyJOIjoiMTIwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMmI5MzcxMDMtNzJhMy00YWMxLWFlMmQtMmI0MTM0MmQzOGUwIn19XSwiU2Nhbm5lZENvdW50Ijo4fQ==" + } + }, + { + "ID": "21daf1868cc0a9cf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "188" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1257" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2515920261" + ], + "X-Amzn-Requestid": [ + "MVU7FAFDSJB8FD0U61153GH81NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NiwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wMi0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJhbmR5In0sIlNjb3JlIjp7Ik4iOiI4MSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjA2Mzk2YzMyLWVlOGYtNDdkNS04OTg0LTRhN2YxOWUyZTQwZCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTE5VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImZyYW4ifSwiU2NvcmUiOnsiTiI6IjMzIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOGE4YWRmNDEtMjgxNS00NjNkLTkzNjAtZjc2OTk5ZDFiZWI1In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDQtMTBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoibWVsIn0sIlNjb3JlIjp7Ik4iOiI2MCJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjEzZjAwNmJlLTIyZDQtNDAwOC05MzRhLTcxYjlkN2FiNjUwNiJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTEzVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9LCJTY29yZSI6eyJOIjoiNDkifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2OWNkYzY1MC0yMjM5LTRlNzQtOGYzMy05MmFhN2JkNGRiZWIifX1dLCJTY2FubmVkQ291bnQiOjh9" + } + }, + { + "ID": "dfc6e502cd473fb5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "K1TGH00QCNT9QFF4MBOUA9OT1RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "0a959fa006020b50", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "66HIVR04RT2D61K42QA33LAJGBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "4c4f5b1ad7766385", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "238" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "860" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1560499134" + ], + "X-Amzn-Requestid": [ + "6A00J6SF3VEJF72K25FUG51UARVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6NH0=" + } + }, + { + "ID": "1d6467542bfb1184", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "263" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "860" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2292908763" + ], + "X-Amzn-Requestid": [ + "DGU3N696D21AJLSOSOAFN0Q647VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAzLTEzVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9LCJTY29yZSI6eyJOIjoiNDkifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2OWNkYzY1MC0yMjM5LTRlNzQtOGYzMy05MmFhN2JkNGRiZWIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wMi0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJhbmR5In0sIlNjb3JlIjp7Ik4iOiI4MSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjA2Mzk2YzMyLWVlOGYtNDdkNS04OTg0LTRhN2YxOWUyZTQwZCJ9fV0sIlNjYW5uZWRDb3VudCI6NH0=" + } + }, + { + "ID": "922ab756440ecc58", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "169" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "984" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1315895868" + ], + "X-Amzn-Requestid": [ + "HK8LONFS7M84ETQRS2G3PAB79JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn0sIlBsYXllciI6eyJTIjoiYmlsbGllIn19LHsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifSwiUGxheWVyIjp7IlMiOiJmcmFuIn19LHsiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJlZmM1OWE2OS1iNzIwLTQ3ZTktYjQ5OC0wZTVjYzA0OThhOGMifSwiUGxheWVyIjp7IlMiOiJtZWwifX0seyJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9LCJQbGF5ZXIiOnsiUyI6InBhdCJ9fSx7IkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn0sIlBsYXllciI6eyJTIjoiYW5keSJ9fSx7IkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOGE4YWRmNDEtMjgxNS00NjNkLTkzNjAtZjc2OTk5ZDFiZWI1In0sIlBsYXllciI6eyJTIjoiZnJhbiJ9fSx7IkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In0sIlBsYXllciI6eyJTIjoibWVsIn19LHsiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2OWNkYzY1MC0yMjM5LTRlNzQtOGYzMy05MmFhN2JkNGRiZWIifSwiUGxheWVyIjp7IlMiOiJwYXQifX1dLCJTY2FubmVkQ291bnQiOjh9" + } + }, + { + "ID": "305d748584d92849", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "208" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1361" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1718650979" + ], + "X-Amzn-Requestid": [ + "V73TV313KA211V5OEKL25S2HBBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IlBsYXllciI6eyJTIjoiYmlsbGllIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlNjb3JlIjp7Ik4iOiIxMTEifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiUGxheWVyIjp7IlMiOiJmcmFuIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlNjb3JlIjp7Ik4iOiIzMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIlNjb3JlIjp7Ik4iOiIxOTAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiUGxheWVyIjp7IlMiOiJwYXQifSwiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJTY29yZSI6eyJOIjoiMTIwIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IlBsYXllciI6eyJTIjoiYW5keSJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJTY29yZSI6eyJOIjoiODEifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiUGxheWVyIjp7IlMiOiJmcmFuIn0sIldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIlNjb3JlIjp7Ik4iOiIzMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJTY29yZSI6eyJOIjoiNjAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiUGxheWVyIjp7IlMiOiJwYXQifSwiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiU2NvcmUiOnsiTiI6IjQ5In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "f28ef88f02425617", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "OEDRIGKOACJV3DA6DMTIKCBFGJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "4ce31769d7be76e9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "86J74NTGA9E39P4JAART00QNDBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "eaf8237b53ce2f32", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "09N709NLTN866CRMI3Q917RMJVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "b7cafbcdeed16e5f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "55CGSP0IR0KGVO9R5JQ9FSDAVRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "6affa91c51dfc2be", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "USVJ361UJRFH7E1AK8SQ4H3K5RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "8dabef98879fa492", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "022G76FJQFRHVR1PGJULA401QBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "600eb0706bca1223", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "3CA0GKJAG8PJDAS3SN9GBROCK3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "ffe947a8497a465c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "1GMRHSMLNV66QD8HOSAVNGHD7VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "6aa79218ee988d88", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "TC3ELL00LNI0P9HB7JUU4J29SFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + }, + { + "ID": "c8dcaeae272cbb12", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1649" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:50 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1385118414" + ], + "X-Amzn-Requestid": [ + "7LVM2LP5J39GU1RS3H8G9N879FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTEwVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImJpbGxpZSJ9LCJTY29yZSI6eyJOIjoiMTExIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiM2M2M2IzZDMtYjIwZC00Zjg1LWFlMmUtNDFiMWE4YzFlOGJmIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMjBUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiWm9tYmllIERNViJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YzY0YmEwNi0xMmVkLTQ3ZjAtODMwNy05ZDcyODZlNzJmMGIifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOnRydWV9LCJUaW1lIjp7IlMiOiIyMDE5LTA0LTE4VDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6Im1lbCJ9LCJTY29yZSI6eyJOIjoiMTkwIn0sIkdhbWUiOnsiUyI6IlpvbWJpZSBETVYifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZWZjNTlhNjktYjcyMC00N2U5LWI0OTgtMGU1Y2MwNDk4YThjIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjp0cnVlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0wMVQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJwYXQifSwiU2NvcmUiOnsiTiI6IjEyMCJ9LCJHYW1lIjp7IlMiOiJab21iaWUgRE1WIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJiOTM3MTAzLTcyYTMtNGFjMS1hZTJkLTJiNDEzNDJkMzhlMCJ9fSx7IldpdGhHbGl0Y2giOnsiQk9PTCI6ZmFsc2V9LCJUaW1lIjp7IlMiOiIyMDE5LTAyLTAxVDAwOjAwOjAwWiJ9LCJQbGF5ZXIiOnsiUyI6ImFuZHkifSwiU2NvcmUiOnsiTiI6IjgxIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDYzOTZjMzItZWU4Zi00N2Q1LTg5ODQtNGE3ZjE5ZTJlNDBkIn19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTlUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoiZnJhbiJ9LCJTY29yZSI6eyJOIjoiMzMifSwiR2FtZSI6eyJTIjoiUHJhaXNlIEFsbCBNb25zdGVycyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI4YThhZGY0MS0yODE1LTQ2M2QtOTM2MC1mNzY5OTlkMWJlYjUifX0seyJXaXRoR2xpdGNoIjp7IkJPT0wiOmZhbHNlfSwiVGltZSI6eyJTIjoiMjAxOS0wNC0xMFQwMDowMDowMFoifSwiUGxheWVyIjp7IlMiOiJtZWwifSwiU2NvcmUiOnsiTiI6IjYwIn0sIkdhbWUiOnsiUyI6IlByYWlzZSBBbGwgTW9uc3RlcnMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMTNmMDA2YmUtMjJkNC00MDA4LTkzNGEtNzFiOWQ3YWI2NTA2In19LHsiV2l0aEdsaXRjaCI6eyJCT09MIjpmYWxzZX0sIlRpbWUiOnsiUyI6IjIwMTktMDMtMTNUMDA6MDA6MDBaIn0sIlBsYXllciI6eyJTIjoicGF0In0sIlNjb3JlIjp7Ik4iOiI0OSJ9LCJHYW1lIjp7IlMiOiJQcmFpc2UgQWxsIE1vbnN0ZXJzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjY5Y2RjNjUwLTIyMzktNGU3NC04ZjMzLTkyYWE3YmQ0ZGJlYiJ9fV0sIlNjYW5uZWRDb3VudCI6OH0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/GetQueryKeyField.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/GetQueryKeyField.replay new file mode 100644 index 000000000..c518d5436 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/GetQueryKeyField.replay @@ -0,0 +1,1451 @@ +{ + "Initial": "AQAAAA7gDNWJDVTMyAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "a6396ecc660f85cc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "LSQI9BKI12VCK2QBCV4RCBS5B7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "8b4e234557c372ca", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "699" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3161549481" + ], + "X-Amzn-Requestid": [ + "U67DTHKO0TJ5DI9R95TN3BG3TRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NiwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3RVbm9yZGVyZWRBY3Rpb25zMyJ9LCJFdGFnIjp7IlMiOiIyNGVhOTBhNS1mN2UxLTRjOWUtOWNkZC0yZDdlZWM1MjlhN2MifSwicyI6eyJTIjoiMyJ9fSx7IkV0YWciOnsiUyI6IjVjODY1MDUzLWNlMmMtNGEwNC05YmE1LTg2MWVkMDZlOWQ3OSJ9LCJzIjp7IlMiOiI4In0sIm4iOnsiTiI6Ii0xIn0sIm5hbWUiOnsiUyI6InRlc3RVbm9yZGVyZWRBY3Rpb25zOCJ9fSx7Im5hbWUiOnsiUyI6InRlc3RVbm9yZGVyZWRBY3Rpb25zNCJ9LCJFdGFnIjp7IlMiOiJjMmY3MGNmYS1jZDA5LTQzMzItOGRjNS0zMWIyMThjYThjMTYifSwicyI6eyJTIjoiNCJ9fSx7IkV0YWciOnsiUyI6ImY4N2ZiOTg4LWMwOTgtNGVjYS05YzVmLTc2N2Y3N2U0YjE4MiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczcifSwicyI6eyJTIjoiNycifX0seyJFdGFnIjp7IlMiOiIzMzZhMzA5MC04ZjI5LTRiZDgtYmIxYi0wYjNjNTEzZjRlNGQifSwicyI6eyJTIjoiNicifSwibiI6eyJOIjoiMSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczYifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifSwiRXRhZyI6eyJTIjoiMzZmMTU0MTctZTk5Ny00MDJlLTg0YmYtYTdiMjllNmE2YWZjIn0sInMiOnsiUyI6IjUifX1dLCJTY2FubmVkQ291bnQiOjZ9" + } + }, + { + "ID": "3dfb2389bd99d24f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UO85OR4NMM8V93CEPJQOLFLKTRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "35d23025ea19997f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8M0J3DB7213LLQKAAASKRQTCKBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f57683de26b689b5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CBQPK4N8R1O7QBQB0LLL9CQ9UVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fcf3712aa8157904", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5TMCCIM5B1RT5U8LQK9V3UC00BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "78a8cd4ddc2727ff", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HT5DSM4PCM5C24KK03SES9GPVRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "aef996647839ddd7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QEHMT4RQ9H0IN9FNAMEEIGB1CJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a30840f49b3ad435", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "142" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QUVB69BCSNB7F8HSOGD6TPQCR7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "62cdb2f644a5e999", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "140" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FK8F9TSN32IKKLOMFKMF37RN03VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c48a010ade549df5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "140" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LP56OBVNM67OKMUF8O030NG1CBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c47561ba7c744453", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "242" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2184589102" + ], + "X-Amzn-Requestid": [ + "G2CARLVM5B7A6VRMCD6JRNB7C3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJuYW1lIjp7IlMiOiJxa2YxIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImZjMDc0NDlhLTY0MmItNDZmZi04YmY1LTBkMGFjZDcxNGY0YyJ9fSx7ImEiOnsiUyI6InR3byJ9LCJuYW1lIjp7IlMiOiJxa2YyIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjZiYTg4MTBhLWQ4NDEtNGE2ZC05NWZhLTM3MDViNDNmN2E1YyJ9fV0sIlNjYW5uZWRDb3VudCI6M30=" + } + }, + { + "ID": "20d8185e1a1bb054", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "346" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1433927240" + ], + "X-Amzn-Requestid": [ + "VE04UCFB3S5BJ3SV2FQ0UARUMVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmYzA3NDQ5YS02NDJiLTQ2ZmYtOGJmNS0wZDBhY2Q3MTRmNGMifSwibmFtZSI6eyJTIjoicWtmMSJ9fSx7ImEiOnsiUyI6InRocmVlIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImI1NDU1N2MzLTcxMTMtNDc5Yi05Zjc1LWQ3NGMxMDk0Zjk1YyJ9LCJuYW1lIjp7IlMiOiJxa2YzIn19LHsiYSI6eyJTIjoidHdvIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjZiYTg4MTBhLWQ4NDEtNGE2ZC05NWZhLTM3MDViNDNmN2E1YyJ9LCJuYW1lIjp7IlMiOiJxa2YyIn19XSwiU2Nhbm5lZENvdW50IjozfQ==" + } + }, + { + "ID": "ccf36205e127f1b3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "89CG19UQLP2ELJJB2A2IUHT5EFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "493c51c744bba3bd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "346" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1252271263" + ], + "X-Amzn-Requestid": [ + "M80S00LFR5GG17FKKVOOFGQ2D3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJuYW1lIjp7IlMiOiJxa2YxIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImZjMDc0NDlhLTY0MmItNDZmZi04YmY1LTBkMGFjZDcxNGY0YyJ9fSx7ImEiOnsiUyI6InRocmVlIn0sIm5hbWUiOnsiUyI6InFrZjMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYjU0NTU3YzMtNzExMy00NzliLTlmNzUtZDc0YzEwOTRmOTVjIn19LHsiYSI6eyJTIjoidHdvIn0sIm5hbWUiOnsiUyI6InFrZjIifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNmJhODgxMGEtZDg0MS00YTZkLTk1ZmEtMzcwNWI0M2Y3YTVjIn19XSwiU2Nhbm5lZENvdW50IjozfQ==" + } + }, + { + "ID": "b7a4f3340e20d8cf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3UA9AV6KVEGBNTQMVI7OUHH0QBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "948a0176a6c7bee7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "NMVKQMEN72HAQUG5THGOKRCVJ3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b15c060c2337f4b8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "54ABECAMAC5S780FSFR18JRORBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "de4d222ed297a8a3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "128" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "2IO04FMJ1K97ETF9QDTQKCQ3CNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d354f990237d71a4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "130" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "B3Q551IBCPRIQ3J1NOOSQDEN3BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "51b1a1b74ada0990", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "128" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8I5ELEL64GK8BN4MRCHDPG5JGRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0a8f11ca78ea41fb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "218" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1534914876" + ], + "X-Amzn-Requestid": [ + "IG6B1BMJ9CN6H17IG13ID8D59JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJuYW1lIjp7IlMiOiJxa2YxIn0sIkV0YWciOnsiUyI6ImJiYWY3YzFjLWI1ZGYtNGY2Mi05NjM5LWJkNDNmNTExYzVhNyJ9fSx7ImEiOnsiUyI6InR3byJ9LCJuYW1lIjp7IlMiOiJxa2YyIn0sIkV0YWciOnsiUyI6ImIwMzY5M2EyLTIzNWUtNDU5Yi04ODI0LTA2ODhlYzZkZTAxNSJ9fV0sIlNjYW5uZWRDb3VudCI6M30=" + } + }, + { + "ID": "1592a29c1ddfb413", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "151" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "310" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2178078998" + ], + "X-Amzn-Requestid": [ + "FBITF1PUGPOOGKOFGFR524Q9INVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJFdGFnIjp7IlMiOiJiYmFmN2MxYy1iNWRmLTRmNjItOTYzOS1iZDQzZjUxMWM1YTcifSwibmFtZSI6eyJTIjoicWtmMSJ9fSx7ImEiOnsiUyI6InRocmVlIn0sIkV0YWciOnsiUyI6ImZlZDYzOWU0LTI3YTYtNDU1MS1iNzk5LTU2YThhM2M5OThlOCJ9LCJuYW1lIjp7IlMiOiJxa2YzIn19LHsiYSI6eyJTIjoidHdvIn0sIkV0YWciOnsiUyI6ImIwMzY5M2EyLTIzNWUtNDU5Yi04ODI0LTA2ODhlYzZkZTAxNSJ9LCJuYW1lIjp7IlMiOiJxa2YyIn19XSwiU2Nhbm5lZENvdW50IjozfQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/MultipleActions.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/MultipleActions.replay new file mode 100644 index 000000000..d75c82d43 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/MultipleActions.replay @@ -0,0 +1,4013 @@ +{ + "Initial": "AQAAAA7gDNWHAE54CwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b2c79f8ebe07442b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "UCON8GBA505BJTSJG78BG0DJDNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "a646e9d245c6ef60", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "174" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4141619758" + ], + "X-Amzn-Requestid": [ + "97VIGQFUJNOSSNBIELBC2H47T3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IlB0clRvUHJvdG8iOnsiQiI6IkNDcz0ifSwibmFtZSI6eyJTIjoidGVzdGluZyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmYmJkYjA1YS1lMTU5LTQ3OWMtODYwZi0wMzIyODk1ZTcyZTQifSwiUHJvdG8iOnsiQiI6IkNDbz0ifX1dLCJTY2FubmVkQ291bnQiOjF9" + } + }, + { + "ID": "96149a0325d89f44", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "227" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "19FLM59QVJI03DV2KF86LRHVSBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8285a8e9aa2c3bc9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "J3L5R427QVL545653I6TO9D89JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "acf9d0c05729add5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "L7BHB2ILBV8RE8HP2C5D3MMPFNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2e696455ae39b110", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "P3AIV73KTVR6M4RO4EJF9QCBNFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f8eeeb116144504e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HGT1H3PJO2A2CBDOCIECVGH7RJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4dd09ab2cb56f0d2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "AO6KVN2E7ET6LDJJ564IV7FA4RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "dd2fa5e30f1fb65b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LR62H88PH27L2RN8T221F7EI33VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d69a0fe537772469", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "4O9KFJU8MM8V2PJLEULCDCLQVFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "16d860a80a1bd3e8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "320" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JV5Q5IHU071H3QS1SKGF1RJDIBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f277b8c79cd35642", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "321" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "U0135LVUFBP7EAT7KB5UB4F2URVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b4bbbafc9bc7d997", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "K0PCVUMO4LGQ704FKR3A1NM6DVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "556b5d209a5ec84a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5DHSD9MPHLTVRTFJBBQ834UPLJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c4509b6c62467529", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "320" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "S0FFBN8VEUDKNQBJ8QM0EP11BJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6ce234004ad62478", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "320" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SK9LRT9IPUQP9RPMCQAJ5K7737VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5aa46bf3e1aa4166", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "321" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8205KQV424VI5FEC00MGBE7AIFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a06cbbc5c4f5e38d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "321" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UJAQ1GBTIN94PU957FMV98JALBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "755aafe3ac6bba46", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "186" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "407" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1769515862" + ], + "X-Amzn-Requestid": [ + "93R9EHT0GUL21C4GL8PPOR84EBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczQifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNjkyMmFlMTktZWY5OC00MDY5LTlmMzctMmM4ZWM0MjdiYmQ5In0sInMiOnsiUyI6IjQifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZmVlMDM5OWUtMjgwOS00NDQxLWI1MDgtZDhlOWQ0NjU5MTZkIn0sInMiOnsiUyI6IjMifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiODYwZGZkZDItNzgzMy00ODliLTg2NzYtODNlZDBiNTExZTRjIn0sInMiOnsiUyI6IjUifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "610084537e04cdff", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "362" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0KQCCMUNAH1J7MDFIALEUBC5ENVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ae4c3d0167639b1c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "241" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TJJGH14GPFTPV7CKPFTE77INKVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d1f050e0f6b492b0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "395" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "61CV5DUPRQO9O53G12KVJNDQRVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7667f74a63a9ee48", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "241" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "E89AHKCGK1B898CO7VHBUF3Q1FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "256420cd9d1da819", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "360" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FURLS5M9VIFECRDLG7DTJ6591RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b1ee0c805970b410", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "241" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "RJ4EV5I6L6I3LQDI9IPNHNVHR3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "63dc8d8f145b6fc6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "108" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "70J88TOV3UPPRJ013OMV53N66FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "05fc154ae6b2400d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "186" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "173" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1636819582" + ], + "X-Amzn-Requestid": [ + "N4H3A02O27M87S952JTJL0MPI3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZmVlMDM5OWUtMjgwOS00NDQxLWI1MDgtZDhlOWQ0NjU5MTZkIn0sInMiOnsiUyI6IjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "ef3482cec373b4fb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5PC7LR0KMI6M9BICMLVKJA99VFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "94b671eb949cac41", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "I7UQIL13T0FRR29VST9RSHORRVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "a63a6236efe03dea", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "320" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:43 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DVLJTCI930RMP35G03AJB7TCOJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7a368362ef1e638b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "DVEBEUCBV8ETHGK98J3JRPD6FFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "2f9485ad3ee00cce", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "771" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3794425121" + ], + "X-Amzn-Requestid": [ + "8H6SPPQAC4JRB064K7O2Q1S1HVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NiwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3RVbm9yZGVyZWRBY3Rpb25zMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmZWUwMzk5ZS0yODA5LTQ0NDEtYjUwOC1kOGU5ZDQ2NTkxNmQifSwicyI6eyJTIjoiMyJ9fSx7InMiOnsiUyI6IjgifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNWIyMDdkZWEtMjI5NC00OTFmLTk4ZWYtNTQ5OTIxMmY4MTg2In0sIm4iOnsiTiI6Ii0xIn0sIm5hbWUiOnsiUyI6InRlc3RVbm9yZGVyZWRBY3Rpb25zOCJ9fSx7Im5hbWUiOnsiUyI6InRlc3RVbm9yZGVyZWRBY3Rpb25zNCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2OTIyYWUxOS1lZjk4LTQwNjktOWYzNy0yYzhlYzQyN2JiZDkifSwicyI6eyJTIjoiNCJ9fSx7IkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjRiN2NhZTdlLTRjZjktNGYwMi04ODg2LTZmMTM3MGY4MzZhMyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczcifSwicyI6eyJTIjoiNycifX0seyJzIjp7IlMiOiI2JyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI0YmFiODgyNy1jYThkLTQ4YmQtYmJjZC00M2RiNWM2OGVjYzAifSwibiI6eyJOIjoiMSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczYifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMjZmZTliY2EtZjg2Ny00NmE0LTk2NDYtMWFjZjFjMzkwNzZiIn0sInMiOnsiUyI6IjUifX1dLCJTY2FubmVkQ291bnQiOjZ9" + } + }, + { + "ID": "6c18b79131a18bd9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "B9V28H6B2FPA6NJ1KPLFC535P3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f72cf18bfdefef12", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FTL5OO97FO5CS36U025P8318NNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1d939bdf4e20007d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "EJIUSJGF0JNA60ORDK6P61N2K7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0d7863dfb10837ab", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3JN0KQCFNT6K79JBRUFT5M2CRRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f8a79606c8448a3d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "44AKLQSK8P34SUB4GI6TUKFO8NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f662d133818ce90d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LDLQ3DRC4CBOL2EI0G05L0U0BFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8450482ae62232b3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KATSUS9M94T0JF6T9RPSLKLC97VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "128b1853f18f9989", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DPQ990MGOV9AODMIMU557ANG6RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "49389d0b64228b04", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "T7UUJHMET3383834QD87NN5TUJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5b946b5faf86342b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DG73KUPTBBQCCARKF68P331GFJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7b8a73d3c4812d92", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "288CFS1B1IVNJMRBV20G2TTTF7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8ebd9dee1f863995", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "APH04M3059JJ94TK9RC1SRFP8FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1032e5fd58459efd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "297" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "K9TUIN41MMNFATMQF0AE55OGRBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6d0207cfce233e1d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "296" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "J4QOKP270KK3QQQHB397CRUPHVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5a5d673c0530d094", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "296" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7OOD69H4EQRRBN6NBAOR3D9E9BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2f7d8607b4f47f0a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "143" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7V4RC3GECD7BCR74HLRPMB6C4BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cafc8c54c18490e0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "143" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LTPET5JJNRU9I599SM78JKQ52VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "05b19afb92cd06d9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "143" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "C152L24K3LFLFGR71PCIR1D62BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5dec3f77100136bf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "297" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5P1PLR4228RPLP3GNNPUS3MU07VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b9efe93670c9a9f4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "297" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "53JB5OHQ86U8HHOVE82SIJ98B7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b7388d525b05769c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "296" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UDO9A7OCDI6U4124274FV4HNMVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "eef648319b4c8d7d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "186" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "371" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2201052510" + ], + "X-Amzn-Requestid": [ + "JJF16K93OG1N6VSDVGN2PTILFNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczQifSwiRXRhZyI6eyJTIjoiYzJmNzBjZmEtY2QwOS00MzMyLThkYzUtMzFiMjE4Y2E4YzE2In0sInMiOnsiUyI6IjQifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczUifSwiRXRhZyI6eyJTIjoiZDU2ZDY1N2ItNDg2Yy00NmQzLTg5NGQtODEyMGU5ZTUxYjVmIn0sInMiOnsiUyI6IjUifX0seyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifSwiRXRhZyI6eyJTIjoiMjRlYTkwYTUtZjdlMS00YzllLTljZGQtMmQ3ZWVjNTI5YTdjIn0sInMiOnsiUyI6IjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "c6aa731ff9bf6c07", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "350" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QATNU5IQE70GR77055ORAD3LLFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8254fb82b41154a9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "348" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M3NEU8FKCKCN3K44SRJ19DE3SRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ec7409e57f58801e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "229" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "GE4AQEVN45FDNBS5RARIRBM99JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1309b534ca4c58f4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "229" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "22CSUKC26JBE6C1F9NNCTAKV4RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "429e65766e2f0517", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "229" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:44 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OTA5E1NVT2L5AFLLEFM844UVTFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "dc4797eb69a763bf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "383" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "S546HHU0915A7KKEDLVL3ICLD7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "547a9f62e96beff7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "108" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "57" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "289144682" + ], + "X-Amzn-Requestid": [ + "2HQRPSB7PIIUQN2EUQHB06J4Q3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbXX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "323075b375132e2a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "76" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "I8T1QRFV3KGRJO4K874TCRFUQRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ae5fdd320caa6663", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "186" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "161" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2324510762" + ], + "X-Amzn-Requestid": [ + "1T8998TUVBGF8B54PDEM2S5S6NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0VW5vcmRlcmVkQWN0aW9uczMifSwiRXRhZyI6eyJTIjoiMjRlYTkwYTUtZjdlMS00YzllLTljZGQtMmQ3ZWVjNTI5YTdjIn0sInMiOnsiUyI6IjMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "322871a1136ea6c3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "296" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "A4STVQKRLQT7AQJL1MO7PKRQMJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c594357a1938d1d6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "234" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:45 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "CKULBB73UG0CFCJU5S6L2TB03NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Proto.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Proto.replay new file mode 100644 index 000000000..33c16af92 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Proto.replay @@ -0,0 +1,353 @@ +{ + "Initial": "AQAAAA7gDNWGGfFcJAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b281ddce47d2e8e2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "HIA2414H97LM6VQKOMF1ANDFGRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "43c97687da2df6aa", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "83" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1006067942" + ], + "X-Amzn-Requestid": [ + "AOB7028U1FECTVS7DV7G58SCI3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3REYXRhIn0sInZhbCI6eyJCIjoiQUFFQyJ9fV0sIlNjYW5uZWRDb3VudCI6MX0=" + } + }, + { + "ID": "861fdc2ea3fe1422", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "63" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HCHBA0DIJIV4V5MCACDIJAOI83VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f887e32afb14cb9a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "265" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "UV1O8UTV0T6HTUR3LC56HOUS2BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "49603436e7ff6a27", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "174" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:42 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4141619758" + ], + "X-Amzn-Requestid": [ + "UDC6M054EVIFE0JDJ1G1L02HHJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MSwiSXRlbXMiOlt7IlB0clRvUHJvdG8iOnsiQiI6IkNDcz0ifSwibmFtZSI6eyJTIjoidGVzdGluZyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJmYmJkYjA1YS1lMTU5LTQ3OWMtODYwZi0wMzIyODk1ZTcyZTQifSwiUHJvdG8iOnsiQiI6IkNDbz0ifX1dLCJTY2FubmVkQ291bnQiOjF9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Put.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Put.replay new file mode 100644 index 000000000..5bc5b52ae --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Put.replay @@ -0,0 +1,3037 @@ +{ + "Initial": "AQAAAA7gDNV3DC/cHgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "43b166cc1a741c2d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "CSR2UAULFHGHI4T8U7KLHR9AFJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "cebfe595a42c5bb9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "543" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "543435765" + ], + "X-Amzn-Requestid": [ + "D8816D5CV83EMG519FOHRHTMBJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NSwiSXRlbXMiOlt7IkV0YWciOnsiUyI6IjQ4OThlY2Y4LTdlOGYtNDQzNi1iMjI0LWIxOGY5NWNkMTkxYiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0QXRvbWljV3JpdGVzNyJ9LCJzIjp7IlMiOiI3In19LHsibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczQifSwiRXRhZyI6eyJTIjoiM2Y4YjU4MjYtOTNjZi00MmVjLWI2ZDktNDllNjZhYTFhOTdhIn0sInMiOnsiUyI6IjQifX0seyJFdGFnIjp7IlMiOiI4YjUwMmU1Zi04NTBlLTRmNjktYTU0NC1kNWUyZTNjN2EwYjMifSwibmFtZSI6eyJTIjoidGVzdEF0b21pY1dyaXRlczUifSwicyI6eyJTIjoiNSJ9fSx7Im5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXMzIn0sIkV0YWciOnsiUyI6IjBhM2ZhNGI4LTI1NWQtNDc1My1hMTNhLWYyYTdkZmE5NzhjZCJ9LCJzIjp7IlMiOiIzIn19LHsiRXRhZyI6eyJTIjoiMDQ5YjE2NGQtMGM3Yi00NWQxLThkNjEtNTIxMjllOWU2MGFiIn0sIm5hbWUiOnsiUyI6InRlc3RBdG9taWNXcml0ZXM2In0sInMiOnsiUyI6IjYifX1dLCJTY2FubmVkQ291bnQiOjV9" + } + }, + { + "ID": "d9823d54ba11ed59", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SUIB3E78RIFRL8QNA2AS29BKNNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "56605dd9a3580c16", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OSJJP2L64NNR1S7DMR0I3KHEV7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "341f0dbe06c1ab07", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8I9JAD23DCHG2O4DNCVC97FMKNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "52dd0603dc9314f5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CEUAKBVVN0GJFGP77LP2D91UU3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fd87f9b0fac6e8c1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6VISLBRSK5UP66BFTNU8DU46FVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7d1d777318be143b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "148" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CA21ME3FGBSNQD17UT07F79IV7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ec3f50ac1d901571", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "166" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3434708428" + ], + "X-Amzn-Requestid": [ + "L9L2AIP4056881ISCDSE23J4DRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn0sImIiOnsiQk9PTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjM3ZDZjNjY4LTNlODQtNGRiNi04MGY4LTEzZmVkMWVlZjlhMyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "1b74cf05c52011fc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "2ERQL0P7O13SQK5236MTIE9717VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9d21b07e94363f90", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "269" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2016052282" + ], + "X-Amzn-Requestid": [ + "1GCNUFFA89PKC1AVF7IVHVFE83VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFB1dFN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2ZjM3ODI4NS05ZTg0LTRmMmEtYjQwMC1hZjZlMWZjZjhkNmEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "28a435d89480e0fa", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "149" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "O7CBRVK4N8OK3D14RIGO6UMNH3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6802b7b8291f3fd5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "167" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4003386832" + ], + "X-Amzn-Requestid": [ + "HBB2DJLC4GQ3THUPR2GR3EJNGJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn0sImIiOnsiQk9PTCI6ZmFsc2V9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiIwY2YzZWY4NC1hMmYzLTQ0ZTUtOGEwNy1hMDcwNzY0NDQ4OGEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "16eb2b977d2e9d08", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "B2TU2D3OBTRMUGMFIDIQ25A0OJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "dd3eba33fb6a178e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "270" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:27 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "761615548" + ], + "X-Amzn-Requestid": [ + "2RR6T5PD30ELU2ROVEHJ9LLIPVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RQdXRTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiODczMTQxNzYtMTEzYi00MGU0LWE5NmQtMzAwMDU3NzM5M2Y2In19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "f120814c3fb564f7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "296" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "R6S4EVOI1I6GIC0N7K7K5TBHE3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "8087a14f57192b86", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "449" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "FCNL8QM2GMSQTNP2R43QP9EUQ3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "3358e3fb083512a6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "149" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LH1BB94RJ2EU2EQJGJ0P5MFC4NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4968c7594e315522", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "167" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3153785517" + ], + "X-Amzn-Requestid": [ + "5PGQVT18HA5O1QPEPU46GKADMFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYWI5ZjJkYTYtZjQ4YS00OGQ4LWJiM2YtNmI2ZDBjMTE1OGRkIn0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "a4b6c93847aca7c6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "314" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QNNCAIK3NMGHCIIPI3CL65R687VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7f826b6597494b27", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "314" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "MAKK2J4UAKV687A03J4U7HE4U3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "f092876f83dbf6fb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "RBV5O7DINJS0HUCIBSRV4CCB7JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0e3a0c8aefad93bb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3079197867" + ], + "X-Amzn-Requestid": [ + "1LDVQV3O20V49096TNBAJDGQKNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjJhOWIwOTIzLWE0ZTYtNGI4OC1iMTkwLWJmMjRmYzU3ZmZjOCJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "ea3aeb508314d1b9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "418" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VJ2H3V877UDTOR2I23HUNHUC2FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5174102bd7c46b3a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "418" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "93351KDIHTNN4UME4UQS4R6NPVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "711fd949162bfe55", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "0V50AREVH7L8S8IMB5FD1S6J67VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "98e94a0df38acfe0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "689" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4189308677" + ], + "X-Amzn-Requestid": [ + "VGKNR1NJN2LJVIPJJ051SGA45BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3RSZXZpc2lvbk1hcCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI1ZjJkZDZmOS04NzcxLTRmZGUtOGI4MS00NTkzMTZmYzA0ZDMifSwicyI6eyJTIjoiYSJ9fSx7Im5hbWUiOnsiUyI6InRlc3RQdXRNYXAifSwiYiI6eyJCT09MIjpmYWxzZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjBjZjNlZjg0LWEyZjMtNDRlNS04YTA3LWEwNzA3NjQ0NDg4YSJ9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZjUzMjdhYzAtMDk1OS00OTIyLTk3MGItMjAwYTc3ZTI5YTFmIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0U3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijg3MzE0MTc2LTExM2ItNDBlNC1hOTZkLTMwMDA1NzczOTNmNiJ9fV0sIlNjYW5uZWRDb3VudCI6NH0=" + } + }, + { + "ID": "aa96630c78d71cf7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DS018850G4K7TPT7JOUC21VBCFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "294b202f50d45394", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "2EE8JV1Q4243JJ8KP80VV7UTJJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e0811b826d8531b7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FI6RTIS8GVMAE1IOKQMPESG637VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "db40cea3cddf6ff2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:28 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "A0PBAVQVJB77488PTFE98RSBL3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "100d9b9801d841bd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "136" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "LGR1ISFIV2CQAP8LC222RNRQIJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c49c5ea9ab0410be", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "154" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2290630932" + ], + "X-Amzn-Requestid": [ + "14UVLTBAIL8RS1FUT5FM2C6MJJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI5MGNhYTRlYS0zZmE1LTQ5YzQtYmM5OC04MmQ5NWI3NGZkOGUifSwibmFtZSI6eyJTIjoidGVzdFB1dE1hcCJ9LCJiIjp7IkJPT0wiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "403d7659f61ca458", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3I1AEMAR0C0VGF1VHPQA23HUV3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a56eb79dee3fdfa1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "269" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "60125511" + ], + "X-Amzn-Requestid": [ + "FUMMCF27F62JB1H59F4H337U5JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOnRydWV9LCJTdCI6eyJOVUxMIjp0cnVlfSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiNzY2NjAyNmEtMDZhOC00MTA5LThjZTMtNjFkOTMxZjRkODgzIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RQdXRTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJOVUxMIjp0cnVlfX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "0b198a3237353e59", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "137" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "U6DDD3K5AG2GHFGJME7BK4UOKBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7b696192390e8392", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "97" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "155" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1343285193" + ], + "X-Amzn-Requestid": [ + "HONLI45S603N96VNECUJM0J9VJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiIxOGIyNmNjMy04YmM3LTQ3OWEtYjI2MS00NjlhNGUzZGM2MTMifSwibmFtZSI6eyJTIjoidGVzdFB1dE1hcCJ9LCJiIjp7IkJPT0wiOmZhbHNlfX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "81ede8b90d0437dd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QBGMH3VRBRIUNUM1505NNGKC5BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "829cec1b946265ca", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "270" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "397784339" + ], + "X-Amzn-Requestid": [ + "22SE1AU0NOM4HS79KF4GL2V0BVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiUyI6ImY2MzAwNTRmLWJlYzktNGNlMy05NDI3LWZhNjVkZDhlYTllYiJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0U3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "278055e9ae726301", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "272" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "TR0OTA135QQKIKCN142CGPTR0NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "eeed73be3bc98892", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "437" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "SHNDR5MBU9TI4OABHIRCL0CA1BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "9fca379f46ea00a2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "137" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "S5FCOEUJKMN8D8386V168KATR3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b538bd122a813078", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "155" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "731408603" + ], + "X-Amzn-Requestid": [ + "VDFJK7DGNM7T0M8TI79EELFB47VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiJjZThhZWI3YS1lYjAwLTQ2YWQtODBiMy1kYzZhM2I4YzA5ZDEifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "d73b4b0f44dcec8d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "290" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TIK6CPQP6P52GTQV84TDRIE0J7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "009f20cafdae34fc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "290" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "V6GM44CVJ802GEOID6DUABNMVBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "fcd96f7d46cf6282", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FP2QLKQH98BB1KN4847B1GHPVBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8664a9d5be05a6b1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2224649275" + ], + "X-Amzn-Requestid": [ + "364JM25C23G2VG5UPO2HEJS1N7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiNmQ5MzU0M2UtMmJhMS00OTc1LWFkZTktMDAxYTM4NTE4NDY3In0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvblN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "310355141b6b74a8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "406" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3K801H284AGNOU3NFSI3O3H5AVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "974e90d0e3c0ca5d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "406" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "TVPUE3AIN26RBIM9CN1MJQO8URVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Replace.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Replace.replay new file mode 100644 index 000000000..ee2938b5a --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Replace.replay @@ -0,0 +1,2610 @@ +{ + "Initial": "AQAAAA7gDNV6AzvDXgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "e8cedc50cb47d069", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "RJJU14TC5024GVJ1MDA5I7I2IBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "0f28a569b41d4253", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "665" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "179093716" + ], + "X-Amzn-Requestid": [ + "MNGTKRKIQI2HNCOACRBJHI57VBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7IkV0YWciOnsiUyI6ImUxNDY5M2QzLTcwYzQtNDIyMi05ZDNkLTRlZDZhMjgwNDQ2MSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwicyI6eyJTIjoiYSJ9fSx7IkV0YWciOnsiUyI6IjE4YjI2Y2MzLThiYzctNDc5YS1iMjYxLTQ2OWE0ZTNkYzYxMyJ9LCJuYW1lIjp7IlMiOiJ0ZXN0UHV0TWFwIn0sImIiOnsiQk9PTCI6ZmFsc2V9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiI2ZWY0NmIxMy1kZWE3LTQ5NTctOTkwMi0zMTgwNDQzY2M0MDAifSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7Ik5VTEwiOnRydWV9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7IlMiOiJmNjMwMDU0Zi1iZWM5LTRjZTMtOTQyNy1mYTY1ZGQ4ZWE5ZWIifSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFB1dFN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV0sIlNjYW5uZWRDb3VudCI6NH0=" + } + }, + { + "ID": "15c17817605c8be6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "KB4V3AIP51J1NLOFON0BCF9AN3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6e320cc9f920d8e6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "86F2D49V39BUF3CPIATQGV9T9BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f3166d241ca2bbb5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "4DA6GTOL23SI1KSG9TU23ICVS3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f47c12b28a7a70b9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "ART4NGBJOV52R3H0V57MHA04O7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6ea07b1c8e34e451", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "148" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "U1B1A587IETMNEA5F3A90HCMSRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "10f6eeb37af9747c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "235" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HTREM20OPIESV80SN8MUEHQV1BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fa8297fa65144dfa", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "101" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "166" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4044164622" + ], + "X-Amzn-Requestid": [ + "6CFLDHB3ST0VIF1D585HTQ2E77VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmVwbGFjZU1hcCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI2ZDcyYmZkMC1lYWFhLTRjNGUtOTI5MC02MzcxYjMwZjExN2UifSwicyI6eyJTIjoiYiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "e4a868a9548c863a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VEJSEGVTHRHERFDOCLR2DGE78BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5a16d4a6f715a40e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "339" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3N9JNNKJO509SS3F8G4MJ5RM8BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "410b173317bf7051", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "270" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "393047138" + ], + "X-Amzn-Requestid": [ + "4B0MDNLFTQ08M3KI8JI8FP66ABVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImIifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VTdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiYjJhM2U4ZDQtYjE2NC00NGZhLThiMzAtM2VhODdjNDFiOWQwIn19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "6f5e1b88e473f5fc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "MKNTL7D39CISCUKGOON6KQ2RDJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "41141c2390426abd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "149" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SN6UFJVRUV0SPFPPS2STLG3UVFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4fd0db6691dc63ec", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "167" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1069692851" + ], + "X-Amzn-Requestid": [ + "K2N9L00VHIM5FOFCLINMAL4HJ3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMDIyNGI2MjAtOTAyZi00NDFiLWE4NmQtMzJjMmVlYzdkNzUzIn0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "843938b7df0342b8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "314" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "J62FSHAS8196GEJC1UKV01HM27VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3284d24d638e1a0e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "314" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "CDPE4JUU72QSSP4NCNEDI4BLGFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "d9455d6088e3020e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CA0M2UBD8AKKF1EVV6EBC81FSRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f69f7d7a4730752e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3427288787" + ], + "X-Amzn-Requestid": [ + "15LU3MFR8CS7DKM43PG6KJ44TBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjhmYjU3YmIyLWViMGMtNGI2ZC1hNTRhLTZhMDg0OWYyZTFjNiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "740b322f2786db3a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "418" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "O2M4DB1UPRI36N8OHFBRVTNCI7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0b6c044f0ce9e067", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "418" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "AJU0NQENTBMR32O9DRJPCQ8MORVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "9aab81486b308f4a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "JF2TMADFOQLP9OG0ISP4F4IQONVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "6492b34ca900c555", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "688" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "624353285" + ], + "X-Amzn-Requestid": [ + "LH2RKMDL0U234RP5UQSBGGVNT7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6NCwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3RSZXBsYWNlTWFwIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjZkNzJiZmQwLWVhYWEtNGM0ZS05MjkwLTYzNzFiMzBmMTE3ZSJ9LCJzIjp7IlMiOiJiIn19LHsibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjMyNjNkYTc1LTMzMjItNDI2Yy04ZWNjLTYyOThhZjU3ZDc4YiJ9LCJzIjp7IlMiOiJhIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJiIn0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RSZXBsYWNlU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImIyYTNlOGQ0LWIxNjQtNDRmYS04YjMwLTNlYTg3YzQxYjlkMCJ9fSx7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoiYSJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25TdHJ1Y3QifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMWU5YTM4NmQtYzdkNC00MWJmLWI3OWUtN2NjNWE3MmNjNzNmIn19XSwiU2Nhbm5lZENvdW50Ijo0fQ==" + } + }, + { + "ID": "eae157c9a49686aa", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "IPRJHVU118V056D5DCMLAG6ML7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1ac47926b66cd2d5", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "BLLV0M8SR9M0OEM4P3PJOT76MJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "57002d2b644fc6c2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8DS4C44O6TKTEHG2RLFQLKV68JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "95e9737f8306b606", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "9BQ46V90T5L7KMQO3JM0PMMFNNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2e7a786787b8e2e6", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "136" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FBK19C6ELR309H2N7D3U8D70Q7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b4d2d6dbafc68c4f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "223" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JI7L2V7Q7BL9LNN7KI1S4GIOKFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ccd7ff3390a68cd8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "101" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "154" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2364073044" + ], + "X-Amzn-Requestid": [ + "THVDUVCB1UULE704N41AFNTKOBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiI0MzM3YzU2Yi1lNGI3LTQzYzEtODdmZC00NjNhOThiY2JkYzQifSwibmFtZSI6eyJTIjoidGVzdFJlcGxhY2VNYXAifSwicyI6eyJTIjoiYiJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "6771de270449b0cb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "252" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "O3K75RU6KR7U9UNEFEV7GT048BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b19782c008e8eda7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "339" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TGIF9KUT10EV4Q00T4T93N725VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a157f2a8096787cc", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "104" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "270" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:31 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3114854738" + ], + "X-Amzn-Requestid": [ + "HKPLUU9LFUC86UNR9HN1RF8O7VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImIifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiMWEyN2FiODgtY2VlNS00ZWNmLWFjOGUtNDFjODYyNWZhM2UzIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RSZXBsYWNlU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19XX0sIlVucHJvY2Vzc2VkS2V5cyI6e319" + } + }, + { + "ID": "7130845f39ea9eb4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "440V4BO5UC9JPV7AUAN3I6RJQVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "ee166c1a9029345d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "137" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "AOT4MLH4D2QB078GARG5MB31NNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ed76def1abf76915", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "155" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "932126899" + ], + "X-Amzn-Requestid": [ + "2FC3O508N0T1CO3DAMCLDKG1T3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJFdGFnIjp7IlMiOiJhMTU1ZjI2Mi1kNGZiLTQ3YzQtYmIyZi02Y2NjMWVlY2VmNzUifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uTWFwIn0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "cd2e15654295069c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "290" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "AK1GSIPNS5Q89U9S4NTE6U9GI7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2ed10a389c3f30b2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "290" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "7QSJT4BT5VM5NMUUUUSP7QJ0URVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "2bd602b60bab2cdd", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "D32G6IQ7NK0IDAVC0OSRS4RUR7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b6b7ab7069c04301", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "363015207" + ], + "X-Amzn-Requestid": [ + "KDBUVL7KG2AQNU0T3L56UDANH3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiN2U1MWVhZDYtNjc2ZS00OWJlLTg3NjItNGU4MzE3Yjk5MGY1In0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvblN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "4754c675258d03ec", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "406" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "DMH1FCGRTTKP458D082UFGAM5RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cb56a375129baa90", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "406" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:32 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "14RBGA1FSV7QN8LV276E9DI49NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/SerializeRevision.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/SerializeRevision.replay new file mode 100644 index 000000000..2906b54c3 --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/SerializeRevision.replay @@ -0,0 +1,414 @@ +{ + "Initial": "AQAAAA7gDNWKGhoItgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "501b79e99eafb1ae", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "4MR2JTH8VTCMNPHL6QTJ4FCBVJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "60de86ccdf59a5fb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "310" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3789796451" + ], + "X-Amzn-Requestid": [ + "NLAUS704MANMR20KG69QO22H23VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MywiSXRlbXMiOlt7ImEiOnsiUyI6Im9uZSJ9LCJuYW1lIjp7IlMiOiJxa2YxIn0sIkV0YWciOnsiUyI6ImJiYWY3YzFjLWI1ZGYtNGY2Mi05NjM5LWJkNDNmNTExYzVhNyJ9fSx7ImEiOnsiUyI6InRocmVlIn0sIkV0YWciOnsiUyI6ImZlZDYzOWU0LTI3YTYtNDU1MS1iNzk5LTU2YThhM2M5OThlOCJ9LCJuYW1lIjp7IlMiOiJxa2YzIn19LHsiYSI6eyJTIjoidHdvIn0sIm5hbWUiOnsiUyI6InFrZjIifSwiRXRhZyI6eyJTIjoiYjAzNjkzYTItMjM1ZS00NTliLTg4MjQtMDY4OGVjNmRlMDE1In19XSwiU2Nhbm5lZENvdW50IjozfQ==" + } + }, + { + "ID": "49c1170210cda7a8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "5KHBSQ61SMLBMVTO0NQMDOJHNRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ee1d4f0929358b3d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "O9JL2S8R4DC54PE0RO318GEM0BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "76750be869d7c98a", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "ULQC4CUBT1LSI0H8KRND99IQSNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ccd2f9be451255f8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:46 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3IB9E3K7P9IQ72T6QJ1JRAQRIJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Update.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Update.replay new file mode 100644 index 000000000..de893154b --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestConformance/Update.replay @@ -0,0 +1,4196 @@ +{ + "Initial": "AQAAAA7gDNWAIxJ7LQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "9cd3ec1c61591ea7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "IIMVN2LLE60SDA8PSF12JACHI3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "962d2812ca33c051", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "355" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1259264719" + ], + "X-Amzn-Requestid": [ + "6TA6L0C7TRCFGAN9CALU9JER5FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6MiwiSXRlbXMiOlt7Im5hbWUiOnsiUyI6InRlc3REZWxldGVNYXAifSwiRXRhZyI6eyJTIjoiZTZhNTgwNDItMjVlNS00Yjk0LWFhYzgtYWM3MDk3YTgzYzQwIn0sImIiOnsiQk9PTCI6dHJ1ZX19LHsiQiI6eyJCT09MIjp0cnVlfSwiU3QiOnsiTlVMTCI6dHJ1ZX0sIlUiOnsiTiI6IjAifSwiRiI6eyJOIjoiMCJ9LCJJIjp7Ik4iOiIwIn0sIkV0YWciOnsiUyI6IjY0ZDNmYTU1LTU4ZWMtNDBmMi04ODIyLTRlYWU0ZjAzYzFiOSJ9LCJNIjp7Ik5VTEwiOnRydWV9LCJuYW1lIjp7IlMiOiJ0ZXN0RGVsZXRlU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX19XSwiU2Nhbm5lZENvdW50IjoyfQ==" + } + }, + { + "ID": "211846c0dfc9a1d0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7GGL5I34PMUD6QO0LMQFK13QTNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f7ffe9cd23f5b68c", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "8K6CR2S3REQEA9FLCVFK4FCOCRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "fc9292618ad0527b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "191" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6JGQ0G9B1IG0UDERU4IH3BS5RJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "bd11b4d15c15a71e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "462" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OFNJ9DR28RPMA6GMURFBDMPMFNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "831d8969c2cc03ba", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "209" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2438568632" + ], + "X-Amzn-Requestid": [ + "I9A9N8JAVM7JJL627TH9RN4UM7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJYIn0sImMiOnsiUyI6IkMifSwibSI6eyJOIjoiMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiZDc4ZWQ4Yy0wYzk4LTRmZjgtYmM2ZS04OTJhMWI5OTMwYmQifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXAifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "0ce0a28318a91136", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "150" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "09KC7OIE2K11R5CT700GQHO22RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "49ee4adbb3bf0338", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "383" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "50G54KU2NGOCM8DI468OQ0JR73VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8c8dc34ee1abc994", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "182" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2047912064" + ], + "X-Amzn-Requestid": [ + "U50D8G0I5Q7DE0896J2109PHJFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJYIn0sIm0iOnsiTiI6IjMifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiNzY5ZjViYjktYWY0Yy00YTAzLThjODItY2ZhYzA1Y2ZiMmRhIn0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBXcnQifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "824d8b1a8857b6c0", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "180" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0DIG0I8LQSD2UBA5BAA4FVAJ9RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "395ebd2cc982c783", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "397" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "I0MJRPU3FCRJHPJ3O6N7N7NG6VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "eb6439a07cffd5db", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "214" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3637060764" + ], + "X-Amzn-Requestid": [ + "I0IBAHM4SERIOP1R0HGVH6A7LJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJBIn0sImkiOnsiTiI6IjMuNSJ9LCJtIjp7Ik4iOiIzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjUxMTczMzk4LTk0ZDktNDU5MS05NTU2LWU5OGQxOWIyNzAxMyJ9LCJuIjp7Ik4iOiIyLjUifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcEluYyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "8415941b0d902aa1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "A0UPVDQUBPDLSSTJCS4RSJMS6BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1a2ec69cd419715e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "422" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "INA0PAUL4NLBPNM5DRTEBVTFKNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7c7eaec7716a63ac", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "259" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3827269111" + ], + "X-Amzn-Requestid": [ + "4DEN4CUJ40IUVSFJ02JESMTJJJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0ciJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAuNSJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJjZjczNzU1OS1lYWJmLTRlZTQtOWI1YS1kMTk5NzUwZWM4NzIifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdCJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "a9eb223585c521df", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "255" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "89S85BR7LFC42NQS63OM9MAIPBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3863cffcd3e7adc3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "389" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6N84AGBJH559U4AHH4GGCELHVRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "58d5824648348117", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "106" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "260" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1569461822" + ], + "X-Amzn-Requestid": [ + "O8RORNQD48KJ3PUBO93861QLUNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0ciJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiOWMyYjQ3M2QtOTdhNC00ZThkLTg5OGEtNmU5Mzc0NWNiNGI2In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVTdHJ1Y3RXcnQifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "b6aa1246dc6be5cf", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "257" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0V7FBO5K6O24EBUR2NEEMB93CBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "41f42041647fce40", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "367" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7BTD81MMIKRD98TF8JOLFC7877VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e2410604a593a1f8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "106" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "275" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2442725281" + ], + "X-Amzn-Requestid": [ + "8U4D39A9TSG9BMEN5NQBPL305BVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0In0sIlUiOnsiTiI6IjQifSwiRiI6eyJOIjoiMC41In0sIkkiOnsiTiI6IjEifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZjYyZmVmZGEtNTRmZC00Njk1LTk0OWMtMmEzYWQzZjI4ZDU4In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVTdHJ1Y3RJbmMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "1e95f9a3b2a5d7a8", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "63EFLI008TS03Q2SL759P14BAJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "571b3d7c3bf31307", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "149" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V8JQG45PQUOOPO6KJ85UTM4MIRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "806048f031804778", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "167" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1455223659" + ], + "X-Amzn-Requestid": [ + "TO716THN99AHA3A960DIB8SI6RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiMWFiMGVkZmUtMTY0YS00OWZjLThiZjMtYjVlNGM5NGY3NDk1In0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "1113fbe2705e3d31", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "353" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "OMOMJC3A37UGKES2FVHG24BQBVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "08efd8132ed2f495", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "353" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "C6NBGJ2RCDGIGCIQ8B6GH0B01JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "65ae76652af9ef21", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "CAUF5MK2ORGTH2JS33G6FQ1D83VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3359c577c9a67672", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "86636633" + ], + "X-Amzn-Requestid": [ + "8J1T99DKRU8IPN3K4IGGVT7GJBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJOVUxMIjp0cnVlfSwiTSI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjQ2ZjQ2YWM2LWE1YzYtNGI5NS1hYjE3LTBjOWE0Yzc1YWVjOCJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "8684d0ecabb34331", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "356" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "VD8I9VJB2CKSDUI6GGUIGG024RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "0a9cabaefd1d5dd9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "356" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "VSJJS08SCCMV782K0GN5P4U02RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "ebe6a23a8071133f", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "599" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3022004566" + ], + "X-Amzn-Requestid": [ + "JI2B05U6OE5LVR73KKSC14BP5RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6Im5hbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwNzk3OTdFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkl0ZW1Db3VudCI6MCwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoibmFtZSIsIktleVR5cGUiOiJIQVNIIn1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMSIsIlRhYmxlSWQiOiI5N2U0OTNmNC1jZjU3LTQ2YmItOTc4Ny1iOGU4ZDk3ZjUwMDciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTEiLCJUYWJsZVNpemVCeXRlcyI6MCwiVGFibGVTdGF0dXMiOiJBQ1RJVkUiLCJXYXJtVGhyb3VnaHB1dCI6eyJSZWFkVW5pdHNQZXJTZWNvbmQiOjUsIlN0YXR1cyI6IkFDVElWRSIsIldyaXRlVW5pdHNQZXJTZWNvbmQiOjV9fX0=" + } + }, + { + "ID": "61aa3e6f488c8089", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Scan" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1441" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1413684269" + ], + "X-Amzn-Requestid": [ + "1I7BERRT6BI0S2VQ8BGOIE35CBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJDb3VudCI6OCwiSXRlbXMiOlt7IkIiOnsiQk9PTCI6ZmFsc2V9LCJTdCI6eyJTIjoic3RyIn0sIlUiOnsiTiI6IjQifSwiRiI6eyJOIjoiMC41In0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImNmNzM3NTU5LWVhYmYtNGVlNC05YjVhLWQxOTk3NTBlYzg3MiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0In19LHsiRG9jc3RvcmVSZXZpc2lvbiI6eyJTIjoiZDhmMGJhZjAtNTUxYy00MjM3LWFlM2UtYzU0NThmNGNlMzI0In0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvbk1hcCJ9LCJzIjp7IlMiOiJjIn19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJzdHIifSwiVSI6eyJOIjoiNCJ9LCJGIjp7Ik4iOiIwIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6IjljMmI0NzNkLTk3YTQtNGU4ZC04OThhLTZlOTM3NDVjYjRiNiJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0V3J0In19LHsiQiI6eyJCT09MIjpmYWxzZX0sIlN0Ijp7IlMiOiJzdCJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAuNSJ9LCJJIjp7Ik4iOiIxIn0sIkV0YWciOnsiTlVMTCI6dHJ1ZX0sIk0iOnsiTlVMTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6ImY2MmZlZmRhLTU0ZmQtNDY5NS05NDljLTJhM2FkM2YyOGQ1OCJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlU3RydWN0SW5jIn19LHsiYSI6eyJTIjoiQSJ9LCJpIjp7Ik4iOiIzLjUifSwibSI6eyJOIjoiMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiI1MTE3MzM5OC05NGQ5LTQ1OTEtOTU1Ni1lOThkMTliMjcwMTMifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBJbmMifX0seyJhIjp7IlMiOiJYIn0sImMiOnsiUyI6IkMifSwibSI6eyJOIjoiMyJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJiZDc4ZWQ4Yy0wYzk4LTRmZjgtYmM2ZS04OTJhMWI5OTMwYmQifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXAifX0seyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwicyI6eyJTIjoiYyJ9LCJVIjp7Ik4iOiIwIn0sIkYiOnsiTiI6IjAifSwiSSI6eyJOIjoiMCJ9LCJFdGFnIjp7Ik5VTEwiOnRydWV9LCJNIjp7Ik5VTEwiOnRydWV9LCJEb2NzdG9yZVJldmlzaW9uIjp7IlMiOiJjNjgwNzE1Ny05YzU2LTQ4YjMtYmU4YS1kOWQ1MzczMmFjYmYifSwibmFtZSI6eyJTIjoidGVzdFJldmlzaW9uU3RydWN0In19LHsiYSI6eyJTIjoiWCJ9LCJtIjp7Ik4iOiIzIn0sIkRvY3N0b3JlUmV2aXNpb24iOnsiUyI6Ijc2OWY1YmI5LWFmNGMtNGEwMy04YzgyLWNmYWMwNWNmYjJkYSJ9LCJuYW1lIjp7IlMiOiJ0ZXN0VXBkYXRlTWFwV3J0In19XSwiU2Nhbm5lZENvdW50Ijo4fQ==" + } + }, + { + "ID": "8343f8e9fa02c8d3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "74" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "3B49NFUCALUE5C3C4ERMJ9PPLNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9c59f7102437888d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "17M2OO6FBINTHOQTFL8GBJIL1VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f32c339fce228036", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "Q49USAMU9TJI2OI9F233MFN6MBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "eb2588f6015a5c7e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "70" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V1J98D4SN99GED1GN30034ICC3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "47c4d4edb09adac4", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "74" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HOGJOKFVAUP5QA3IMRG45FKSC7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8692fc73b33ab6e9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "HD5FHCDKRR88QFVMM3V9UDFCVNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b290aa6f05ff5f5e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "SVCLTTP9S0KTFFO3G44JI6VHRRVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9dac6e1786e51def", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DeleteItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QBGNUEUTF98UG2Q2TGOS60447RVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a1c8e93f945f9566", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "179" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "V7U9PRLO2KR1C230L8L79UVHTBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d64e579c5221e567", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "450" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "6JFGUI2JTSGS1MCNCPATAKEMR3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "63a4347d1046bc99", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "100" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "197" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1876192146" + ], + "X-Amzn-Requestid": [ + "BIQG5167AGU5RDUIGB9EBS63ORVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJYIn0sIkV0YWciOnsiUyI6ImFmMWM1MzQzLThkNTItNDRkMS1iNjg5LTNlZGFkMzQxODA2MSJ9LCJjIjp7IlMiOiJDIn0sIm0iOnsiTiI6IjMifSwibiI6eyJOIjoiMi41In0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXAifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "2adaecb822a93050", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "138" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "C1VRHD3U52IUIK33P00PPCEKRJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "21e6a9d1011c262d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "371" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "FU77ATPLQ1S89DE2M95KQ8P5UFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "c2264048067dd74b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "170" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "241678941" + ], + "X-Amzn-Requestid": [ + "PV94ALLDVKRJ9K246KG7N8M00NVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJYIn0sIkV0YWciOnsiUyI6ImEyMzQ1MjA2LWM1ZWMtNGMxYi04MzhjLTYxMjAyNTk0YjljYyJ9LCJtIjp7Ik4iOiIzIn0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVNYXBXcnQifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "5e3271a57b8dd865", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7F4HK4HFVP1EHS5KO23R1GCFTVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8e43a256133f7db1", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "385" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "J01CB1TSAER6RQIO9M21SMIF9JVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1e2a27296707c68d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "202" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1533044712" + ], + "X-Amzn-Requestid": [ + "N3GDE0P5URJE09HJNUTH1AI7A7VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJhIjp7IlMiOiJBIn0sImkiOnsiTiI6IjMuNSJ9LCJFdGFnIjp7IlMiOiI4ZDUxZjNiMi05NTM5LTQ5MDAtOTAyOS02YTlmOGI2NmEyOGMifSwibSI6eyJOIjoiMyJ9LCJuIjp7Ik4iOiIyLjUifSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZU1hcEluYyJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "b0debf082855f54e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "254" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "22BSDMLKN8V9LLMGIC8K6J9DPFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "19881f961e5fc3db", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "410" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "B7P9RQ8MNTH0FFMSGEKKNVHFCJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1985615b6cd161c3", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "103" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "259" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "329599007" + ], + "X-Amzn-Requestid": [ + "HAVBINC7M14OULAJSBATPB8607VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0ciJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAuNSJ9LCJFdGFnIjp7IlMiOiJhZDIzZDM1Zi1lOTYxLTQ0NzktYjJiMC1kOTlhYzBmOTFmMmYifSwiTSI6eyJOVUxMIjp0cnVlfSwiRG9jc3RvcmVSZXZpc2lvbiI6eyJOVUxMIjp0cnVlfSwibmFtZSI6eyJTIjoidGVzdFVwZGF0ZVN0cnVjdCJ9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "f8b0d6a8d4f1f6a2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "255" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "N2AU8ALSV4L0DQ26RPGUAGSFUNVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6ab85148a1a8457b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "377" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "QRMAVK2LBVHH9N3MHCDRIR888VVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "99ee4292bcb85551", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "106" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "260" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1691378609" + ], + "X-Amzn-Requestid": [ + "Q620NC2FLQBQAH6L1I5O0DIPIBVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0ciJ9LCJVIjp7Ik4iOiI0In0sIkYiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiNzUzNmVhMGEtMjNmMC00YTU0LWFhNDgtNWVkMTE4MzIwNDliIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVTdHJ1Y3RXcnQifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "bb283e6c15b1f258", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "257" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "M8KE32RFOIQ0PI5BBE1H96D477VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f447a59e2a4f0c26", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "355" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "Q9OU0UG56KLEN5TE92QVHJVAOJVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "77a8ed1eb61ce08e", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "106" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "275" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2575693816" + ], + "X-Amzn-Requestid": [ + "KFKE9UIAVUEROBDKSAM1NEIVFFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6InN0In0sIlUiOnsiTiI6IjQifSwiRiI6eyJOIjoiMC41In0sIkkiOnsiTiI6IjEifSwiRXRhZyI6eyJTIjoiMDA3OWQ5OWMtZTg2Zi00ZjA3LWJjZmQtMjFhNjkwZTI0YjgyIn0sIk0iOnsiTlVMTCI6dHJ1ZX0sIkRvY3N0b3JlUmV2aXNpb24iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RVcGRhdGVTdHJ1Y3RJbmMifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "06dd55ac10682fbb", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "243" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "LUB0D3DH006LK7D3ERTFPSR0TFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "df81acaecefc958b", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "137" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "0AC6M7BRN2C2H0Q7A7QAD8SCRFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "98b4227db6fa79e7", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "155" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "4020243122" + ], + "X-Amzn-Requestid": [ + "EBMBTVGVJD37C7CVICPTMIJTKFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJuYW1lIjp7IlMiOiJ0ZXN0UmV2aXNpb25NYXAifSwiRXRhZyI6eyJTIjoiZjc3ZTU2NGEtNzMxYi00OTlhLWIwZDEtYzFlN2IxYWRkZDllIn0sInMiOnsiUyI6ImEifX1dfSwiVW5wcm9jZXNzZWRLZXlzIjp7fX0=" + } + }, + { + "ID": "45161368854fce88", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "341" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "TA459A9UPUE5JKNS37OOO0ALKVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ac4a2af5096d9b46", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "341" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "I14L90LR7EKG8L4RJJM7GJARORVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + }, + { + "ID": "609381088dd07d79", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.PutItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "JPOGDU52B63S11QBUDQNVVV4A3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "cfa4014e266e8aa9", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "105" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.BatchGetItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "271" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3156053070" + ], + "X-Amzn-Requestid": [ + "SQIL62CU3G79I169DBMLBVKGK3VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJSZXNwb25zZXMiOnsiZG9jc3RvcmUtdGVzdC0xIjpbeyJCIjp7IkJPT0wiOmZhbHNlfSwiU3QiOnsiUyI6ImEifSwiVSI6eyJOIjoiMCJ9LCJGIjp7Ik4iOiIwIn0sIkkiOnsiTiI6IjAifSwiRXRhZyI6eyJTIjoiMjhlY2EyYmUtNjM0Yy00NWY2LWFiYjMtNWYxYjRiMjJlNGY4In0sIk0iOnsiTlVMTCI6dHJ1ZX0sIm5hbWUiOnsiUyI6InRlc3RSZXZpc2lvblN0cnVjdCJ9LCJEb2NzdG9yZVJldmlzaW9uIjp7Ik5VTEwiOnRydWV9fV19LCJVbnByb2Nlc3NlZEtleXMiOnt9fQ==" + } + }, + { + "ID": "371f7f62d4cdeeaa", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "344" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "2745614147" + ], + "X-Amzn-Requestid": [ + "7QTDL45RTVLHG34GNCN06GSUDFVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "dd56f7f0bfe322f2", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "344" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.UpdateItem" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:40 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "396270901" + ], + "X-Amzn-Requestid": [ + "EPSU15B5NT4SDB4FAME3OPRF5FVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLmR5bmFtb2RiLnYyMDEyMDgxMCNDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSBjb25kaXRpb25hbCByZXF1ZXN0IGZhaWxlZCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/testdata/TestQueryErrors.replay b/go-cloud/docstore/awsdynamodb/v2/testdata/TestQueryErrors.replay new file mode 100644 index 000000000..acd142a1e --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/testdata/TestQueryErrors.replay @@ -0,0 +1,170 @@ +{ + "Initial": "AQAAAA7gDNWRNrNOBAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*", + ".*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "611877f1e2ef6a08", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.DescribeTable" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1609" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "3233200316" + ], + "X-Amzn-Requestid": [ + "J8TTGCDD5AG4PKIR4Q8VDM3JKVVV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJUYWJsZSI6eyJBdHRyaWJ1dGVEZWZpbml0aW9ucyI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIkF0dHJpYnV0ZVR5cGUiOiJTIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJBdHRyaWJ1dGVUeXBlIjoiTiJ9LHsiQXR0cmlidXRlTmFtZSI6IlRpbWUiLCJBdHRyaWJ1dGVUeXBlIjoiUyJ9XSwiQ3JlYXRpb25EYXRlVGltZSI6MS43MjMwNzYwODA2OTVFOSwiRGVsZXRpb25Qcm90ZWN0aW9uRW5hYmxlZCI6ZmFsc2UsIkdsb2JhbFNlY29uZGFyeUluZGV4ZXMiOlt7IkluZGV4QXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMi9pbmRleC9nbG9iYWwiLCJJbmRleE5hbWUiOiJnbG9iYWwiLCJJbmRleFNpemVCeXRlcyI6MTA3LCJJbmRleFN0YXR1cyI6IkFDVElWRSIsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiUGxheWVyIiwiS2V5VHlwZSI6IkhBU0gifSx7IkF0dHJpYnV0ZU5hbWUiOiJUaW1lIiwiS2V5VHlwZSI6IlJBTkdFIn1dLCJQcm9qZWN0aW9uIjp7IlByb2plY3Rpb25UeXBlIjoiQUxMIn0sIlByb3Zpc2lvbmVkVGhyb3VnaHB1dCI6eyJOdW1iZXJPZkRlY3JlYXNlc1RvZGF5IjowLCJSZWFkQ2FwYWNpdHlVbml0cyI6NSwiV3JpdGVDYXBhY2l0eVVuaXRzIjo1fSwiV2FybVRocm91Z2hwdXQiOnsiUmVhZFVuaXRzUGVyU2Vjb25kIjo1LCJTdGF0dXMiOiJBQ1RJVkUiLCJXcml0ZVVuaXRzUGVyU2Vjb25kIjo1fX1dLCJJdGVtQ291bnQiOjEsIktleVNjaGVtYSI6W3siQXR0cmlidXRlTmFtZSI6IkdhbWUiLCJLZXlUeXBlIjoiSEFTSCJ9LHsiQXR0cmlidXRlTmFtZSI6IlBsYXllciIsIktleVR5cGUiOiJSQU5HRSJ9XSwiTG9jYWxTZWNvbmRhcnlJbmRleGVzIjpbeyJJbmRleEFybiI6ImFybjphd3M6ZHluYW1vZGI6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3Njp0YWJsZS9kb2NzdG9yZS10ZXN0LTIvaW5kZXgvbG9jYWwiLCJJbmRleE5hbWUiOiJsb2NhbCIsIkluZGV4U2l6ZUJ5dGVzIjoxMDcsIkl0ZW1Db3VudCI6MSwiS2V5U2NoZW1hIjpbeyJBdHRyaWJ1dGVOYW1lIjoiR2FtZSIsIktleVR5cGUiOiJIQVNIIn0seyJBdHRyaWJ1dGVOYW1lIjoiU2NvcmUiLCJLZXlUeXBlIjoiUkFOR0UifV0sIlByb2plY3Rpb24iOnsiUHJvamVjdGlvblR5cGUiOiJBTEwifX1dLCJQcm92aXNpb25lZFRocm91Z2hwdXQiOnsiTnVtYmVyT2ZEZWNyZWFzZXNUb2RheSI6MCwiUmVhZENhcGFjaXR5VW5pdHMiOjUsIldyaXRlQ2FwYWNpdHlVbml0cyI6NX0sIlRhYmxlQXJuIjoiYXJuOmF3czpkeW5hbW9kYjp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OnRhYmxlL2RvY3N0b3JlLXRlc3QtMiIsIlRhYmxlSWQiOiIwZDRmOTk4My1kOGE5LTRhZjEtYTY0NC05YmE3M2NlMGYyMjciLCJUYWJsZU5hbWUiOiJkb2NzdG9yZS10ZXN0LTIiLCJUYWJsZVNpemVCeXRlcyI6MTA3LCJUYWJsZVN0YXR1cyI6IkFDVElWRSIsIldhcm1UaHJvdWdocHV0Ijp7IlJlYWRVbml0c1BlclNlY29uZCI6NSwiU3RhdHVzIjoiQUNUSVZFIiwiV3JpdGVVbml0c1BlclNlY29uZCI6NX19fQ==" + } + }, + { + "ID": "fc88fad3379ac04d", + "Request": { + "Method": "POST", + "URL": "https://dynamodb.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "identity" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "175" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "DynamoDB_20120810.Query" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "Q0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "165" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 23:53:53 GMT" + ], + "Server": [ + "Server" + ], + "X-Amz-Crc32": [ + "1880536678" + ], + "X-Amzn-Requestid": [ + "9LDH5NPTFP2O74MFKBP0HJDR77VV4KQNSO5AEMVJF66Q9ASUAAJG" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uLmNvcmFsLnZhbGlkYXRlI1ZhbGlkYXRpb25FeGNlcHRpb24iLCJtZXNzYWdlIjoiT25lIG9yIG1vcmUgcGFyYW1ldGVyIHZhbHVlcyB3ZXJlIGludmFsaWQ6IENvbmRpdGlvbiBwYXJhbWV0ZXIgdHlwZSBkb2VzIG5vdCBtYXRjaCBzY2hlbWEgdHlwZSJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/docstore/awsdynamodb/v2/urls.go b/go-cloud/docstore/awsdynamodb/v2/urls.go new file mode 100644 index 000000000..303332f7a --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/urls.go @@ -0,0 +1,127 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "context" + "errors" + "fmt" + "net/url" + "sync" + + "github.com/aws/aws-sdk-go-v2/aws" + dyn "github.com/aws/aws-sdk-go-v2/service/dynamodb" + gcaws "github.com/DataDog/iceberg-go/go-cloud/aws" + "github.com/DataDog/iceberg-go/go-cloud/docstore" +) + +func init() { + docstore.DefaultURLMux().RegisterCollection(Scheme, new(lazySessionOpener)) +} + +type lazySessionOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazySessionOpener) OpenCollectionURL(ctx context.Context, u *url.URL) (*docstore.Collection, error) { + o.init.Do(func() { + + o.opener = &URLOpener{} + }) + if o.err != nil { + return nil, fmt.Errorf("open collection %s: %v", u, o.err) + } + return o.opener.OpenCollectionURL(ctx, u) +} + +// Scheme is the URL scheme dynamodb registers its URLOpener under on +// docstore.DefaultMux. +const Scheme = "dynamodb" + +// URLOpener opens dynamodb URLs like +// "dynamodb://mytable?partition_key=partkey&sort_key=sortkey". +// +// The URL Host is used as the table name. See +// https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html +// for more details. +// +// The following query parameters are supported: +// +// - partition_key (required): the path to the partition key of a table or an index. +// - sort_key: the path to the sort key of a table or an index. +// - allow_scans: if "true", allow table scans to be used for queries +// - consistent_read: if "true", a strongly consistent read is used whenever possible. +// +// See https://godoc.org/gocloud.dev/aws#ConfigFromURLParams for supported query +// parameters for overriding the aws.Session from the URL. +type URLOpener struct { +} + +// OpenCollectionURL opens the collection at the URL's path. See the package doc for more details. +func (o *URLOpener) OpenCollectionURL(_ context.Context, u *url.URL) (*docstore.Collection, error) { + db, tableName, partitionKey, sortKey, opts, err := o.processURL(u) + if err != nil { + return nil, err + } + return OpenCollection(db, tableName, partitionKey, sortKey, opts) +} + +func (o *URLOpener) processURL(u *url.URL) (db *dyn.Client, tableName, partitionKey, sortKey string, opts *Options, err error) { + q := u.Query() + + partitionKey = q.Get("partition_key") + if partitionKey == "" { + return nil, "", "", "", nil, fmt.Errorf("open collection %s: partition_key is required to open a table", u) + } + q.Del("partition_key") + sortKey = q.Get("sort_key") + q.Del("sort_key") + opts = &Options{ + AllowScans: q.Get("allow_scans") == "true", + RevisionField: q.Get("revision_field"), + ConsistentRead: q.Get("consistent_read") == "true", + } + q.Del("allow_scans") + q.Del("revision_field") + q.Del("consistent_read") + + tableName = u.Host + if tableName == "" { + return nil, "", "", "", nil, fmt.Errorf("open collection %s: URL's host cannot be empty (the table name)", u) + } + if u.Path != "" { + return nil, "", "", "", nil, fmt.Errorf("open collection %s: URL path must be empty, only the host is needed", u) + } + + cfg, err := gcaws.V2ConfigFromURLParams(context.Background(), q) + if err != nil { + return nil, "", "", "", nil, fmt.Errorf("open collection %s: %v", u, err) + } + db, err = Dial(cfg) + if err != nil { + return nil, "", "", "", nil, fmt.Errorf("open collection %s: %v", u, err) + } + return db, tableName, partitionKey, sortKey, opts, nil +} + +// Dial gets an AWS DynamoDB service client. +func Dial(p aws.Config) (*dyn.Client, error) { + if p.Credentials == nil { + return nil, errors.New("getting Dynamo service: no AWS session provided") + } + return dyn.NewFromConfig(p), nil +} diff --git a/go-cloud/docstore/awsdynamodb/v2/urls_test.go b/go-cloud/docstore/awsdynamodb/v2/urls_test.go new file mode 100644 index 000000000..3a3b32fbd --- /dev/null +++ b/go-cloud/docstore/awsdynamodb/v2/urls_test.go @@ -0,0 +1,58 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awsdynamodb + +import ( + "net/url" + "testing" +) + +func TestProcessURL(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"dynamodb://docstore-test?partition_key=_kind", false}, + // OK. + {"dynamodb://docstore-test?partition_key=_kind&sort_key=_id", false}, + // OK, overriding region. + {"dynamodb://docstore-test?partition_key=_kind®ion=" + region, false}, + // OK, allow_scans. + {"dynamodb://docstore-test?partition_key=_kind&allow_scans=true" + region, false}, + // Passing revision field. + {"dynamodb://docstore-test?partition_key=_kind&revision_field=123", false}, + // Passing consistent read field. + {"dynamodb://docstore-test?partition_key=_kind&consistent_read=true", false}, + // Unknown parameter. + {"dynamodb://docstore-test?partition_key=_kind¶m=value", true}, + // With path. + {"dynamodb://docstore-test/subcoll?partition_key=_kind", true}, + // Missing partition_key. + {"dynamodb://docstore-test?sort_key=_id", true}, + } + + o := &URLOpener{} + for _, test := range tests { + u, err := url.Parse(test.URL) + if err != nil { + t.Fatal(err) + } + _, _, _, _, _, err = o.processURL(u) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + } +} diff --git a/go-cloud/docstore/doc.go b/go-cloud/docstore/doc.go new file mode 100644 index 000000000..485c07587 --- /dev/null +++ b/go-cloud/docstore/doc.go @@ -0,0 +1,281 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 docstore provides a portable way of interacting with a document store. +// Subpackages contain driver implementations of docstore for supported +// services. +// +// See https://gocloud.dev/howto/docstore/ for a detailed how-to guide. +// +// # Collections +// +// In docstore, documents are grouped into collections, and each document has a key +// that is unique in its collection. You can add, retrieve, modify and delete +// documents by key, and you can query a collection to retrieve documents that match +// certain criteria. +// +// # Representing Documents +// +// A document is a set of named fields, each with a value. A field's value can be a scalar, +// a list, or a nested document. +// +// Docstore allows you to represent documents as either map[string]interface{} or +// struct pointers. When you represent a document as a map, the fields are map keys +// and the values are map values. Lists are represented with slices. For example, +// here is a document about a book described as a map: +// +// doc := map[string]interface{}{ +// "Title": "The Master and Margarita", +// "Author": map[string]interface{}{ +// "First": "Mikhail", +// "Last": "Bulgakov", +// }, +// "PublicationYears": []int{1967, 1973}, +// } +// +// Note that the value of "PublicationYears" is a list, and the value of "Author" is +// itself a document. +// +// Here is the same document represented with structs: +// +// type Book struct { +// Title string +// Author Name +// PublicationYears []int +// } +// +// type Name struct { +// First, Last string +// } +// +// doc := &Book{ +// Title: "The Master and Margarita", +// Author: Name{ +// First: "Mikhail", +// Last: "Bulgakov", +// }, +// PublicationYears: []int{1967, 1973}, +// } +// +// You must use a pointer to a struct to represent a document, although structs +// nested inside a document, like the Name struct above, need not be pointers. +// +// Maps are best for applications where you don't know the structure of the +// documents. Using structs is preferred because it enforces some structure on your +// data. +// +// By default, Docstore treats a struct's exported fields as the fields of the +// document. You can alter this default mapping by using a struct tag beginning +// with "docstore:". Docstore struct tags support renaming, omitting fields +// unconditionally, or omitting them only when they are empty, exactly like +// encoding/json. For example, this is the Book struct with different field +// names: +// +// type Book struct { +// Title string `docstore:"title"` +// Author Name `docstore:"author"` +// PublicationYears []int `docstore:"pub_years,omitempty"` +// NumPublications int `docstore:"-"` +// } +// +// This struct describes a document with field names "title", "author" and +// "pub_years". The pub_years field is omitted from the stored document if it has +// length zero. The NumPublications field is never stored because it can easily be +// computed from the PublicationYears field. +// +// Given a document field "Foo" and a struct type document, Docstore's decoder +// will look through the destination struct's field to find (in order of +// preference): +// - An exported field with a tag of "Foo"; +// - An exported field named "Foo". +// +// Note that unlike encoding/json, Docstore does case-sensitive matching during +// decoding to match the behavior of decoders in most docstore services. +// +// # Representing Data +// +// Values stored in document fields can be any of a wide range of types. All +// primitive types except for complex numbers are supported, as well as slices and +// maps (the map key type must be a string, an integer, or a type that implements +// encoding.TextMarshaler). In addition, any type that implements +// encoding.BinaryMarshaler or encoding.TextMarshaler is permitted. This set of types +// closely matches the encoding/json package (see https://golang.org/pkg/encoding/json). +// +// Times deserve special mention. Docstore can store and retrieve values of type +// time.Time, with two caveats. First, the timezone will not be preserved. Second, +// Docstore guarantees only that time.Time values are represented to millisecond +// precision. Many services will do better, but if you need to be sure that times +// are stored with nanosecond precision, convert the time.Time to another type before +// storing and re-create when you retrieve it. For instance, if you store Unix +// time in nanoseconds using time's UnixNano method, you can get the original +// time back (in the local timezone) with the time.Unix function. +// +// # Representing Keys +// +// The key of a docstore document is its unique identifier, usually a field. +// Keys never appear alone in the docstore API, only as part of a document. For +// instance, to retrieve a document by key, you pass the Collection.Get method +// a document as a struct pointer or map with the key field populated, and docstore +// populates the rest of that argument with the stored contents. Docstore +// doesn't take zero-value key. +// +// When you open a collection using an OpenCollection method of the +// service-specific driver or a URL, you specify how to extract the key from a +// document. +// Usually, you provide the name of the key field, as in the example below: +// +// coll, err := memdocstore.OpenCollection("SSN", nil) +// +// Here, the "SSN" field of the document is used as the key. Some drivers let you +// supply a function to extract the key from the document, which can be useful if the +// key is composed of more than one field. +// +// # Actions +// +// Docstore supports six actions on documents as methods on the Collection type: +// - Get retrieves a document. +// - Create creates a new document. +// - Replace replaces an existing document. +// - Put puts a document into a collection, replacing it if it is already present. +// - Update applies a set of modifications to a document. +// - Delete deletes a document. +// +// Each action acts atomically on a single document. You can execute actions +// individually or you can group them into an action list, like so: +// +// err := coll.Actions().Put(doc1).Replace(doc2).Get(doc3).Do(ctx) +// +// When you use an action list, docstore will try to optimize the execution of the +// actions. For example, multiple Get actions may be combined into a single "batch +// get" RPC. For the most part, actions in a list execute in an undefined order +// (perhaps concurrently) and independently, but read and write operations on the same +// document are executed in the user-specified order. See the documentation of +// ActionList for details. +// +// # Revisions +// +// Docstore supports document revisions to distinguish different versions of a +// document and enable optimistic locking. By default, Docstore stores the +// revision in the field named "DocstoreRevision" (stored in the constant +// DefaultRevisionField). Providers give you the option of changing that field +// name. +// +// When you pass a document with a revision field to a write action, Docstore +// will give it a revision at creation time or update the revision value when +// modifying the document. If you don't want Docstore to handle any revision +// logic, simply do not have the revision field in your document. +// +// When you pass a document with a non-nil revision to Put, Replace, Update or +// Delete, Docstore will also compare the revision of the stored document to +// that of the given document before making the change. It returns an error with +// code FailedPrecondition on mismatch. (See https://gocloud.dev/gcerrors for +// information about error codes.) If modification methods are called on a +// document struct or map a nil revision field, then no revision checks are +// performed, and changes are forced blindly, but a new revision will still be +// given for the document. For example, if you call Get to retrieve a document +// with a revision, then later perform a write action with that same document, +// it will fail if the document was changed since the Get. +// +// Since different services use different types for revisions, revision fields +// of unspecified type must be handled. When defining a document struct, +// define the field to be of type interface{}. For example, +// +// type User { +// Name string +// DocstoreRevision interface{} +// } +// +// # Queries +// +// Docstore supports querying within a collection. Call the Query method on +// Collection to obtain a Query value, then build your query by calling Query methods +// like Where, Limit and so on. Finally, call the Get method on the query to execute it. +// The result is an iterator, whose use is described below. +// +// iter := coll.Query().Where("size", ">", 10).Limit(5).Get(ctx) +// +// The Where method defines a filter condition, much like a WHERE clause in SQL. +// Conditions are of the form "field op value", where field is any document field +// path (including dot-separated paths), op is one of "=", ">", "<", ">=" or "<=", +// and value can be any value. +// +// iter := coll.Query().Where("Author.Last", "=", "Bulgakov").Limit(3).Get(ctx) +// +// Dot-separated paths work as you'd expect for nested structs and maps, addressing +// the nested struct field or map key. For nested slices, some providers (notably +// MongoDB) treat s.f, where s is a sequence, as the slice of e.f for each e in s. +// However, others do not support field selectors inside slices, so docstore does +// not support them -- while you may find that they work with some providers, you +// cannot rely on that if you need fully portable code. +// +// You can make multiple Where calls. In some cases, parts of a Where clause may be +// processed in the driver rather than natively by the backing service, which may have +// performance implications for large result sets. See the driver package +// documentation for details. +// +// Use the DocumentIterator returned from Query.Get by repeatedly calling its Next +// method until it returns io.EOF. Always call Stop when you are finished with an +// iterator. It is wise to use a defer statement for this. +// +// iter := coll.Query().Where("size", ">", 10).Limit(5).Get(ctx) +// defer iter.Stop() +// for { +// m := map[string]interface{}{} +// err := iter.Next(ctx, m) +// if err == io.EOF { +// break +// } +// if err != nil { +// return err +// } +// fmt.Println(m) +// } +// +// # Errors +// +// The errors returned from this package can be inspected in several ways: +// +// The Code function from https://gocloud.dev/gcerrors will return an error code, also +// defined in that package, when invoked on an error. +// +// The Collection.ErrorAs method can retrieve the underlying driver error from +// the returned error. See the specific driver's package doc for the supported +// types. +// +// # OpenTelemetry Integration +// +// OpenTelemetry supports tracing, metrics, and logs collection for multiple languages and +// backend providers. See https://opentelemetry.io. +// +// This API collects OpenTelemetry traces and metrics for the following methods: +// - ActionList.Do +// - Query.Get (for the first query only; drivers may make additional calls while iterating over results) +// +// All trace and metric names begin with the package import path. +// The traces add the method name. +// For example, "gocloud.dev/docstore/ActionList.Do". +// The metrics are "completed_calls", a count of completed method calls by driver, +// method and status (error code); and "latency", a distribution of method latency +// by driver and method. +// For example, "gocloud.dev/docstore/latency". +// +// To enable trace collection in your application, see the documentation at +// https://opentelemetry.io/docs/instrumentation/go/getting-started/. +// To enable metric collection in your application, see the documentation at +// https://opentelemetry.io/docs/instrumentation/go/manual/. +// +// # GORM-like Code Generation +// +// You may find https://github.com/bartventer/docstore-gen useful. +package docstore // import "gocloud.dev/docstore" diff --git a/go-cloud/docstore/docstore.go b/go-cloud/docstore/docstore.go new file mode 100644 index 000000000..4cdbe0cc3 --- /dev/null +++ b/go-cloud/docstore/docstore.go @@ -0,0 +1,719 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 docstore + +import ( + "context" + "encoding/base64" + "fmt" + "log" + "reflect" + "runtime" + "sort" + "strings" + "sync" + "unicode/utf8" + + "go.opentelemetry.io/otel/trace" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + gcdkotel "github.com/DataDog/iceberg-go/go-cloud/internal/otel" +) + +// A Document is a set of field-value pairs. One or more fields, called the key +// fields, must uniquely identify the document in the collection. You specify the key +// fields when you open a collection. +// A field name must be a valid UTF-8 string that does not contain a '.'. +// +// A Document can be represented as a map[string]int or a pointer to a struct. For +// structs, the exported fields are the document fields. +type Document = interface{} + +// A Collection represents a set of documents. It provides an easy and portable +// way to interact with document stores. +// To create a Collection, use constructors found in driver subpackages. +type Collection struct { + driver driver.Collection + tracer *gcdkotel.Tracer + mu sync.Mutex + closed bool +} + +const pkgName = "gocloud.dev/docstore" + +var ( + + // OpenTelemetryViews are predefined views for OpenTelemetry metrics. + // The views include counts and latency distributions for API method calls. + // See the explanations at https://opentelemetry.io/docs/specs/otel/metrics/data-model/ for usage. + OpenTelemetryViews = gcdkotel.Views(pkgName) +) + +// NewCollection is intended for use by drivers only. Do not use in application code. +var NewCollection = newCollection + +// newCollection makes a Collection. +func newCollection(d driver.Collection) *Collection { + providerName := gcdkotel.ProviderName(d) + c := &Collection{ + driver: d, + tracer: gcdkotel.NewTracer(pkgName, providerName), + } + _, file, lineno, ok := runtime.Caller(1) + runtime.SetFinalizer(c, func(c *Collection) { + c.mu.Lock() + closed := c.closed + c.mu.Unlock() + if !closed { + var caller string + if ok { + caller = fmt.Sprintf(" (%s:%d)", file, lineno) + } + log.Printf("A docstore.Collection was never closed%s", caller) + } + }) + return c +} + +// DefaultRevisionField is the default name of the document field used for document revision +// information, to implement optimistic locking. +// See the Revisions section of the package documentation. +const DefaultRevisionField = "DocstoreRevision" + +func (c *Collection) revisionField() string { + if r := c.driver.RevisionField(); r != "" { + return r + } + return DefaultRevisionField +} + +// A FieldPath is a dot-separated sequence of UTF-8 field names. Examples: +// +// room +// room.size +// room.size.width +// +// A FieldPath can be used select top-level fields or elements of sub-documents. +// There is no way to select a single list element. +type FieldPath string + +// Actions returns an ActionList that can be used to perform +// actions on the collection's documents. +func (c *Collection) Actions() *ActionList { + return &ActionList{coll: c} +} + +// An ActionList is a group of actions that affect a single collection. +// +// The writes in an action list (Put, Create, Replace, Update and Delete actions) +// must refer to distinct documents and are unordered with respect to each other. +// Each write happens independently of the others: all actions will be executed, even +// if some fail. +// +// The Gets in an action list must also refer to distinct documents and are unordered +// and independent of each other. +// +// A Get and a write may refer to the same document. Each write may be paired with +// only one Get in this way. The Get and write will be executed in the order +// specified in the list: a Get before a write will see the old value of the +// document; a Get after the write will see the new value if the service is strongly +// consistent, but may see the old value if the service is eventually consistent. +type ActionList struct { + coll *Collection + actions []*Action + enableAtomicWrites bool + beforeDo func(asFunc func(interface{}) bool) error +} + +// An Action is a read or write on a single document. +// Use the methods of ActionList to create and execute Actions. +type Action struct { + kind driver.ActionKind + doc Document + fieldpaths []FieldPath // paths to retrieve, for Get + mods Mods // modifications to make, for Update + inAtomicWrite bool // if this action is a part of atomic writes +} + +func (l *ActionList) add(a *Action) *ActionList { + l.actions = append(l.actions, a) + return l +} + +// Create adds an action that creates a new document to the given ActionList, and +// returns the ActionList. The document must not already exist; an error with code +// AlreadyExists is returned if it does. (See gocloud.dev/gcerrors for more on error +// codes.) +// +// If the document doesn't have key fields, or the key fields are empty, meaning +// 0, a nil interface value, or any empty array or string, key fields with +// unique values will be created and doc will be populated with them if there is +// a way to assign those keys, see each driver for details on the requirement of +// generating keys. +// +// The revision field of the document must be absent or nil. +// +// Except for setting the revision field and possibly setting the key fields, the doc +// argument is not modified. +func (l *ActionList) Create(doc Document) *ActionList { + return l.add(&Action{kind: driver.Create, doc: doc, inAtomicWrite: l.enableAtomicWrites}) +} + +// Replace adds an action that replaces a document to the given ActionList, and +// returns the ActionList. The key fields of the doc argument must be set. The +// document must already exist; an error with code NotFound is returned if it does +// not (or possibly FailedPrecondition, if the doc argument has a non-nil revision). +// (See gocloud.dev/gcerrors for more on error codes.) +// +// See the Revisions section of the package documentation for how revisions are +// handled. +func (l *ActionList) Replace(doc Document) *ActionList { + return l.add(&Action{kind: driver.Replace, doc: doc, inAtomicWrite: l.enableAtomicWrites}) +} + +// Put adds an action that adds or replaces a document to the given ActionList, and returns the ActionList. +// The key fields must be set. +// +// If the revision field is non-nil, then Put behaves exactly like Replace, returning +// an error if the document does not exist. Otherwise, Put will create the document +// if it does not exist. +// +// See the Revisions section of the package documentation for how revisions are +// handled. +func (l *ActionList) Put(doc Document) *ActionList { + return l.add(&Action{kind: driver.Put, doc: doc, inAtomicWrite: l.enableAtomicWrites}) +} + +// Delete adds an action that deletes a document to the given ActionList, and returns +// the ActionList. Only the key and revision fields of doc are used. +// See the Revisions section of the package documentation for how revisions are +// handled. +// If doc has no revision and the document doesn't exist, nothing happens and no +// error is returned. +func (l *ActionList) Delete(doc Document) *ActionList { + // Rationale for not returning an error if the document does not exist: + // Returning an error might be informative and could be ignored, but if the + // semantics of an action list are to stop at first error, then we might abort a + // list of Deletes just because one of the docs was not present, and that seems + // wrong, or at least something you'd want to turn off. + return l.add(&Action{kind: driver.Delete, doc: doc, inAtomicWrite: l.enableAtomicWrites}) +} + +// Get adds an action that retrieves a document to the given ActionList, and +// returns the ActionList. +// Only the key fields of doc are used. +// If fps is omitted, doc will contain all the fields of the retrieved document. +// If fps is present, only the given field paths are retrieved. It is undefined +// whether other fields of doc at the time of the call are removed, unchanged, +// or zeroed, so for portable behavior doc should contain only the key fields. +// If you plan to write the document back and let Docstore to perform optimistic +// locking, include the revision field in fps. See more about revision at +// https://godoc.org/gocloud.dev/docstore#hdr-Revisions. +func (l *ActionList) Get(doc Document, fps ...FieldPath) *ActionList { + return l.add(&Action{ + kind: driver.Get, + doc: doc, + fieldpaths: fps, + }) +} + +// Update atomically applies Mods to doc, which must exist. +// Only the key and revision fields of doc are used. +// It is an error to pass an empty Mods to Update. +// +// A modification will create a field if it doesn't exist. +// +// No field path in mods can be a prefix of another. (It makes no sense +// to, say, set foo but increment foo.bar.) +// +// See the Revisions section of the package documentation for how revisions are +// handled. +// +// It is undefined whether updating a sub-field of a non-map field will succeed. +// For instance, if the current document is {a: 1} and Update is called with the +// mod "a.b": 2, then either Update will fail, or it will succeed with the result +// {a: {b: 2}}. +// +// Update does not modify its doc argument, except to set the new revision. To obtain +// the updated document, call Get after calling Update. +func (l *ActionList) Update(doc Document, mods Mods) *ActionList { + return l.add(&Action{ + kind: driver.Update, + doc: doc, + mods: mods, + inAtomicWrite: l.enableAtomicWrites, + }) +} + +// Mods is a map from field paths to modifications. +// At present, a modification is one of: +// - nil, to delete the field +// - an Increment value, to add a number to the field +// - any other value, to set the field to that value +// +// See ActionList.Update. +type Mods map[FieldPath]interface{} + +// Increment returns a modification that results in a field being incremented. It +// should only be used as a value in a Mods map, like so: +// +// docstore.Mods{"count": docstore.Increment(1)} +// +// The amount must be an integer or floating-point value. +func Increment(amount interface{}) interface{} { + return driver.IncOp{amount} +} + +// An ActionListError is returned by ActionList.Do. It contains all the errors +// encountered while executing the ActionList, and the positions of the corresponding +// actions. +type ActionListError []struct { + Index int + Err error +} + +// TODO(jba): use xerrors formatting. + +func (e ActionListError) Error() string { + var s []string + for _, x := range e { + s = append(s, fmt.Sprintf("at %d: %v", x.Index, x.Err)) + } + return strings.Join(s, "; ") +} + +// Unwrap returns the error in e, if there is exactly one. If there is more than one +// error, Unwrap returns nil, since there is no way to determine which should be +// returned. +func (e ActionListError) Unwrap() error { + if len(e) == 1 { + return e[0].Err + } + // Return nil when e is nil, or has more than one error. + // When there are multiple errors, it doesn't make sense to return any of them. + return nil +} + +// BeforeDo takes a callback function that will be called before the ActionList is +// executed by the underlying service. It may be invoked multiple times for a single +// call to ActionList.Do, because the driver may split the action list into several +// service calls. If any callback invocation returns an error, ActionList.Do returns +// an error. +// +// The callback takes a parameter, asFunc, that converts its argument to +// driver-specific types. See https://gocloud.dev/concepts/as for background +// information. +func (l *ActionList) BeforeDo(f func(asFunc func(interface{}) bool) error) *ActionList { + l.beforeDo = f + return l +} + +// Do executes the action list. +// +// If Do returns a non-nil error, it will be of type ActionListError. If any action +// fails, the returned error will contain the position in the ActionList of each +// failed action. +// +// All the actions will be executed. Docstore tries to execute the actions as +// efficiently as possible. Sometimes this makes it impossible to attribute failures +// to specific actions; in such cases, the returned ActionListError will have entries +// whose Index field is negative. +func (l *ActionList) Do(ctx context.Context) error { + return l.do(ctx, true) +} + +// do implements Do with optional OpenTelemetry tracing, so it can be used internally. +func (l *ActionList) do(ctx context.Context, withTracing bool) (err error) { + if err := l.coll.checkClosed(); err != nil { + return ActionListError{{-1, errClosed}} + } + + if withTracing { + var span trace.Span + ctx, span = l.coll.tracer.Start(ctx, "ActionList.Do") + defer func() { l.coll.tracer.End(ctx, span, err) }() + } + + das, err := l.toDriverActions() + if err != nil { + return err + } + dopts := &driver.RunActionsOptions{BeforeDo: l.beforeDo} + alerr := ActionListError(l.coll.driver.RunActions(ctx, das, dopts)) + if len(alerr) == 0 { + return nil // Explicitly return nil, because alerr is not of type error. + } + for i := range alerr { + alerr[i].Err = wrapError(l.coll.driver, alerr[i].Err) + } + return alerr +} + +func (l *ActionList) toDriverActions() ([]*driver.Action, error) { + var das []*driver.Action + var alerr ActionListError + // Create a set of (document key, is Get action) pairs for detecting duplicates: + // an action list can have at most one get and at most one write for each key. + type keyAndKind struct { + key interface{} + isGet bool + } + seen := map[keyAndKind]bool{} + for i, a := range l.actions { + d, err := l.coll.toDriverAction(a) + // Check for duplicate key. + if err == nil && d.Key != nil { + kk := keyAndKind{d.Key, d.Kind == driver.Get} + if seen[kk] { + err = gcerr.Newf(gcerr.InvalidArgument, nil, "duplicate key in action list: %v", d.Key) + } else { + seen[kk] = true + } + } + if err != nil { + alerr = append(alerr, struct { + Index int + Err error + }{i, wrapError(l.coll.driver, err)}) + } else { + d.Index = i + das = append(das, d) + } + } + if len(alerr) > 0 { + return nil, alerr + } + return das, nil +} + +func (c *Collection) toDriverAction(a *Action) (*driver.Action, error) { + ddoc, err := driver.NewDocument(a.doc) + if err != nil { + return nil, err + } + key, err := c.driver.Key(ddoc) + if err != nil { + if gcerrors.Code(err) != gcerr.InvalidArgument { + err = gcerr.Newf(gcerr.InvalidArgument, err, "bad document key") + } + return nil, err + } + if key == nil || driver.IsEmptyValue(reflect.ValueOf(key)) { + if a.kind != driver.Create { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "missing document key") + } + // set the key to nil so that the following code does not need to check for + // empty. + key = nil + } + if reflect.ValueOf(key).Kind() == reflect.Ptr { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "keys cannot be pointers") + } + rev, _ := ddoc.GetField(c.revisionField()) + if a.kind == driver.Create && rev != nil { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "cannot create a document with a revision field") + } + kind := a.kind + if kind == driver.Put && rev != nil { + // A Put with a revision field is equivalent to a Replace. + kind = driver.Replace + } + d := &driver.Action{Kind: kind, Doc: ddoc, Key: key, InAtomicWrite: a.inAtomicWrite} + if a.fieldpaths != nil { + d.FieldPaths, err = parseFieldPaths(a.fieldpaths) + if err != nil { + return nil, err + } + } + if a.kind == driver.Update { + d.Mods, err = toDriverMods(a.mods) + if err != nil { + return nil, err + } + } + return d, nil +} + +func parseFieldPaths(fps []FieldPath) ([][]string, error) { + res := make([][]string, len(fps)) + for i, s := range fps { + fp, err := parseFieldPath(s) + if err != nil { + return nil, err + } + res[i] = fp + } + return res, nil +} + +func toDriverMods(mods Mods) ([]driver.Mod, error) { + // Convert mods from a map to a slice of (fieldPath, value) pairs. + // The map is easier for users to write, but the slice is easier + // to process. + if len(mods) == 0 { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "no mods passed to Update") + } + + // Sort keys so tests are deterministic. + // After sorting, a key might not immediately follow its prefix. Consider the + // sorted list of keys "a", "a+b", "a.b". "a" is prefix of "a.b", but since '+' + // sorts before '.', it is not adjacent to it. All we can assume is that the + // prefix is before the key. + var keys []string + for k := range mods { + keys = append(keys, string(k)) + } + sort.Strings(keys) + + var dmods []driver.Mod + for _, k := range keys { + k := FieldPath(k) + v := mods[k] + fp, err := parseFieldPath(k) + if err != nil { + return nil, err + } + for _, d := range dmods { + if fpHasPrefix(fp, d.FieldPath) { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, + "field path %q is a prefix of %q", strings.Join(d.FieldPath, "."), k) + } + } + if inc, ok := v.(driver.IncOp); ok && !isIncNumber(inc.Amount) { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, + "Increment amount %v of type %[1]T must be an integer or floating-point number", inc.Amount) + } + dmods = append(dmods, driver.Mod{FieldPath: fp, Value: v}) + } + return dmods, nil +} + +// fpHasPrefix reports whether the field path fp begins with prefix. +func fpHasPrefix(fp, prefix []string) bool { + if len(fp) < len(prefix) { + return false + } + for i, p := range prefix { + if fp[i] != p { + return false + } + } + return true +} + +func isIncNumber(x interface{}) bool { + switch reflect.TypeOf(x).Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return true + case reflect.Float32, reflect.Float64: + return true + default: + return false + } +} + +func (l *ActionList) String() string { + var as []string + for _, a := range l.actions { + as = append(as, a.String()) + } + return "[" + strings.Join(as, ", ") + "]" +} + +// AtomicWrites causes all following writes in the list to execute as a single atomic operation. +func (l *ActionList) AtomicWrites() *ActionList { + l.enableAtomicWrites = true + return l +} + +func (a *Action) String() string { + buf := &strings.Builder{} + fmt.Fprintf(buf, "%s(%v", a.kind, a.doc) + for _, fp := range a.fieldpaths { + fmt.Fprintf(buf, ", %s", fp) + } + for _, m := range a.mods { + fmt.Fprintf(buf, ", %v", m) + } + fmt.Fprint(buf, ")") + return buf.String() +} + +// Create is a convenience for building and running a single-element action list. +// See ActionList.Create. +func (c *Collection) Create(ctx context.Context, doc Document) error { + if err := c.Actions().Create(doc).Do(ctx); err != nil { + return err.(ActionListError).Unwrap() + } + return nil +} + +// Replace is a convenience for building and running a single-element action list. +// See ActionList.Replace. +func (c *Collection) Replace(ctx context.Context, doc Document) error { + if err := c.Actions().Replace(doc).Do(ctx); err != nil { + return err.(ActionListError).Unwrap() + } + return nil +} + +// Put is a convenience for building and running a single-element action list. +// See ActionList.Put. +func (c *Collection) Put(ctx context.Context, doc Document) error { + if err := c.Actions().Put(doc).Do(ctx); err != nil { + return err.(ActionListError).Unwrap() + } + return nil +} + +// Delete is a convenience for building and running a single-element action list. +// See ActionList.Delete. +func (c *Collection) Delete(ctx context.Context, doc Document) error { + if err := c.Actions().Delete(doc).Do(ctx); err != nil { + return err.(ActionListError).Unwrap() + } + return nil +} + +// Get is a convenience for building and running a single-element action list. +// See ActionList.Get. +func (c *Collection) Get(ctx context.Context, doc Document, fps ...FieldPath) error { + if err := c.Actions().Get(doc, fps...).Do(ctx); err != nil { + return err.(ActionListError).Unwrap() + } + return nil +} + +// Update is a convenience for building and running a single-element action list. +// See ActionList.Update. +func (c *Collection) Update(ctx context.Context, doc Document, mods Mods) error { + if err := c.Actions().Update(doc, mods).Do(ctx); err != nil { + return err.(ActionListError).Unwrap() + } + return nil +} + +func parseFieldPath(fp FieldPath) ([]string, error) { + if len(fp) == 0 { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "empty field path") + } + if !utf8.ValidString(string(fp)) { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "invalid UTF-8 field path %q", fp) + } + parts := strings.Split(string(fp), ".") + for _, p := range parts { + if p == "" { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "empty component in field path %q", fp) + } + } + return parts, nil +} + +// RevisionToString converts a document revision to a string. The returned +// string should be treated as opaque; its only use is to provide a serialized +// form that can be passed around (e.g., as a hidden field on a web form) +// and then turned back into a revision using StringToRevision. The string is safe +// for use in URLs and HTTP forms. +func (c *Collection) RevisionToString(rev interface{}) (string, error) { + if rev == nil { + return "", gcerr.Newf(gcerr.InvalidArgument, nil, "RevisionToString: nil revision") + } + bytes, err := c.driver.RevisionToBytes(rev) + if err != nil { + return "", wrapError(c.driver, err) + } + return base64.RawURLEncoding.EncodeToString(bytes), nil +} + +// StringToRevision converts a string obtained with RevisionToString +// to a revision. +func (c *Collection) StringToRevision(s string) (interface{}, error) { + if s == "" { + return "", gcerr.Newf(gcerr.InvalidArgument, nil, "StringToRevision: empty string") + } + bytes, err := base64.RawURLEncoding.DecodeString(s) + if err != nil { + return nil, err + } + rev, err := c.driver.BytesToRevision(bytes) + if err != nil { + return "", wrapError(c.driver, err) + } + return rev, nil +} + +// As converts i to driver-specific types. +// See https://gocloud.dev/concepts/as/ for background information, the "As" +// examples in this package for examples, and the driver package +// documentation for the specific types supported for that driver. +func (c *Collection) As(i interface{}) bool { + if i == nil { + return false + } + return c.driver.As(i) +} + +var errClosed = gcerr.Newf(gcerr.FailedPrecondition, nil, "docstore: Collection has been closed") + +// Close releases any resources used for the collection. +func (c *Collection) Close() error { + c.mu.Lock() + prev := c.closed + c.closed = true + c.mu.Unlock() + if prev { + return errClosed + } + return wrapError(c.driver, c.driver.Close()) +} + +func (c *Collection) checkClosed() error { + c.mu.Lock() + defer c.mu.Unlock() + if c.closed { + return errClosed + } + return nil +} + +func wrapError(c driver.Collection, err error) error { + if err == nil { + return nil + } + if gcerr.DoNotWrap(err) { + return err + } + if _, ok := err.(*gcerr.Error); ok { + return err + } + return gcerr.New(c.ErrorCode(err), err, 2, "docstore") +} + +// ErrorAs converts i to driver-specific types. See +// https://gocloud.dev/concepts/as/ for background information and the +// driver package documentation for the specific types supported for +// that driver. +// +// When the error is an ActionListError, ErrorAs works on individual errors in +// the slice, not the slice itself. +// +// ErrorAs panics if i is nil or not a pointer. +// ErrorAs returns false if err == nil. +func (c *Collection) ErrorAs(err error, i interface{}) bool { + return gcerr.ErrorAs(err, i, c.driver.ErrorAs) +} diff --git a/go-cloud/docstore/docstore_test.go b/go-cloud/docstore/docstore_test.go new file mode 100644 index 000000000..9c9f7cafb --- /dev/null +++ b/go-cloud/docstore/docstore_test.go @@ -0,0 +1,190 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 docstore + +import ( + "context" + "reflect" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +type Book struct { + Title string `docstore:"key"` + Author Name `docstore:"author"` + PublicationYears []int `docstore:"pub_years,omitempty"` + NumPublications int `docstore:"-"` +} + +type Name struct { + First, Last string +} + +func TestIsIncNumber(t *testing.T) { + for _, x := range []interface{}{int(1), 'x', uint(1), byte(1), float32(1), float64(1), time.Duration(1)} { + if !isIncNumber(x) { + t.Errorf("%v: got false, want true", x) + } + } + for _, x := range []interface{}{1 + 1i, "3", time.Time{}} { + if isIncNumber(x) { + t.Errorf("%v: got true, want false", x) + } + } +} + +func TestActionsDo(t *testing.T) { + c := newCollection(fakeDriverCollection{}) + defer c.Close() + dn := map[string]interface{}{"key": nil} + d1 := map[string]interface{}{"key": 1} + d2 := map[string]interface{}{"key": 2} + dsn := &Book{} + ds1 := &Book{Title: "The Master and Margarita"} + ds2 := &Book{Title: "The Martian"} + + for _, test := range []struct { + alist *ActionList + want []int // error indexes; nil if no error + }{ + {c.Actions().Get(d1).Get(d2).Get(ds1).Get(ds2), nil}, + {c.Actions().Get(d1).Put(d1).Put(ds1).Get(ds1), nil}, + {c.Actions().Get(d2).Replace(d1).Put(d2).Get(d1), nil}, + {c.Actions().Get(ds2).Replace(ds1).Put(ds2).Get(ds1), nil}, + // Missing keys. + {c.Actions().Put(dn).Put(dsn), []int{0, 1}}, + {c.Actions().Get(dn).Replace(dn).Create(dn).Update(dn, Mods{"a": 1}), []int{0, 1, 3}}, + {c.Actions().Get(dsn).Replace(dsn).Create(dsn).Update(dsn, Mods{"a": 1}), []int{0, 1, 3}}, + // Duplicate documents. + {c.Actions().Create(dn).Create(dn).Create(dsn).Create(dsn), nil}, // each Create without a key is a separate document + {c.Actions().Create(d2).Create(ds2).Get(d2).Get(ds2).Create(d2).Put(ds2), []int{4, 5}}, + {c.Actions().Get(d1).Get(ds1).Get(d1).Get(ds1), []int{2, 3}}, + {c.Actions().Put(d1).Put(ds1).Get(d1).Get(ds1).Get(d1).Get(ds1), []int{4, 5}}, + {c.Actions().Get(d1).Get(ds1).Put(d1).Put(d2).Put(ds1).Put(ds2).Put(d1).Replace(ds1), []int{6, 7}}, + {c.Actions().Create(dn).Create(d1).Create(dsn).Create(ds1).Get(d1).Get(ds1), nil}, + // Get with field paths. + {c.Actions().Get(d1, "a.b", "c"), nil}, + {c.Actions().Get(ds1, "name.Last", "pub_years"), nil}, + {c.Actions().Get(d1, ".c").Get(ds1, "").Get(ds2, "\xa0\xa1"), []int{0, 1, 2}}, // bad field path + // Mods. + {c.Actions().Update(d1, nil).Update(ds1, nil), []int{0, 1}}, // empty mod + {c.Actions().Update(d1, Mods{"a.b.c": 1, "a.b": 2, "a.b+c": 3}), []int{0}}, // a.b is a prefix of a.b.c + {c.Actions().Update(d1, Mods{"": 1}).Update(ds1, Mods{".f": 2}), []int{0, 1}}, // invalid field path + {c.Actions().Update(d1, Mods{"a": Increment(true)}).Update(ds1, Mods{"name": Increment("b")}), []int{0, 1}}, // invalid incOp + } { + err := test.alist.Do(context.Background()) + if err == nil { + if len(test.want) > 0 { + t.Errorf("%s: got nil, want error", test.alist) + } + continue + } + var got []int + for _, e := range err.(ActionListError) { + if gcerrors.Code(e.Err) != gcerrors.InvalidArgument { + t.Errorf("%s: got %v, want InvalidArgument", test.alist, e.Err) + } + got = append(got, e.Index) + } + if !cmp.Equal(got, test.want) { + t.Errorf("%s: got %v, want %v", test.alist, got, test.want) + } + } +} + +func TestClosedErrors(t *testing.T) { + // Check that all collection methods return errClosed if the collection is closed. + ctx := context.Background() + c := NewCollection(fakeDriverCollection{}) + if err := c.Close(); err != nil { + t.Fatalf("got %v, want nil", err) + } + + check := func(err error) { + t.Helper() + if alerr, ok := err.(ActionListError); ok { + err = alerr.Unwrap() + } + if err != errClosed { + t.Errorf("got %v, want errClosed", err) + } + } + + doc := map[string]interface{}{"key": "k"} + check(c.Close()) + check(c.Actions().Create(doc).Do(ctx)) + check(c.Create(ctx, doc)) + check(c.Replace(ctx, doc)) + check(c.Put(ctx, doc)) + check(c.Get(ctx, doc)) + check(c.Delete(ctx, doc)) + check(c.Update(ctx, doc, Mods{"a": 1})) + iter := c.Query().Get(ctx) + check(iter.Next(ctx, doc)) + + // Check that DocumentIterator.Next returns errClosed if Close is called + // in the middle of the iteration. + c = NewCollection(fakeDriverCollection{}) + iter = c.Query().Get(ctx) + c.Close() + check(iter.Next(ctx, doc)) +} + +func TestSerializeRevisionErrors(t *testing.T) { + c := NewCollection(fakeDriverCollection{}) + _, err := c.RevisionToString(nil) + if got := gcerrors.Code(err); got != gcerrors.InvalidArgument { + t.Errorf("got %v, want InvalidArgument", got) + } + _, err = c.StringToRevision("") + if got := gcerrors.Code(err); got != gcerrors.InvalidArgument { + t.Errorf("got %v, want InvalidArgument", got) + } +} + +type fakeDriverCollection struct { + driver.Collection +} + +func (fakeDriverCollection) Key(doc driver.Document) (interface{}, error) { + key, err := doc.GetField("key") + // TODO(#2589): remove this check once we check for empty key. + if err != nil || driver.IsEmptyValue(reflect.ValueOf(key)) { + return nil, err + } + return key, nil +} + +func (fakeDriverCollection) RevisionField() string { return DefaultRevisionField } + +func (fakeDriverCollection) Close() error { return nil } + +func (fakeDriverCollection) RunActions(ctx context.Context, actions []*driver.Action, opts *driver.RunActionsOptions) driver.ActionListError { + return nil +} + +func (fakeDriverCollection) RunGetQuery(context.Context, *driver.Query) (driver.DocumentIterator, error) { + return fakeDriverDocumentIterator{}, nil +} + +type fakeDriverDocumentIterator struct { + driver.DocumentIterator +} + +func (fakeDriverDocumentIterator) Next(context.Context, driver.Document) error { return nil } diff --git a/go-cloud/docstore/driver/actionkind_string.go b/go-cloud/docstore/driver/actionkind_string.go new file mode 100644 index 000000000..60732d5ae --- /dev/null +++ b/go-cloud/docstore/driver/actionkind_string.go @@ -0,0 +1,28 @@ +// Code generated by "stringer -type=ActionKind"; DO NOT EDIT. + +package driver + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[Create-0] + _ = x[Replace-1] + _ = x[Put-2] + _ = x[Get-3] + _ = x[Delete-4] + _ = x[Update-5] +} + +const _ActionKind_name = "CreateReplacePutGetDeleteUpdate" + +var _ActionKind_index = [...]uint8{0, 6, 13, 16, 19, 25, 31} + +func (i ActionKind) String() string { + if i < 0 || i >= ActionKind(len(_ActionKind_index)-1) { + return "ActionKind(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _ActionKind_name[_ActionKind_index[i]:_ActionKind_index[i+1]] +} diff --git a/go-cloud/docstore/driver/codec.go b/go-cloud/docstore/driver/codec.go new file mode 100644 index 000000000..875fee5ec --- /dev/null +++ b/go-cloud/docstore/driver/codec.go @@ -0,0 +1,782 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// TODO(jba): support struct tags. +// TODO(jba): for efficiency, enable encoding of only a subset of field paths. + +package driver + +import ( + "encoding" + "fmt" + "reflect" + "strconv" + + "github.com/DataDog/iceberg-go/go-cloud/docstore/internal/fields" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "google.golang.org/protobuf/proto" +) + +var ( + binaryMarshalerType = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem() + binaryUnmarshalerType = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem() + textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() + protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem() +) + +// An Encoder encodes Go values in some other form (e.g. JSON, protocol buffers). +// The encoding protocol is designed to avoid losing type information by passing +// values using interface{}. An Encoder is responsible for storing the value +// it is encoding. +// +// Because all drivers must support the same set of values, the encoding methods +// (with the exception of EncodeStruct) do not return errors. EncodeStruct is special +// because it is an escape hatch for arbitrary structs, not all of which may be +// encodable. +type Encoder interface { + // These methods all encode and store a single Go value. + EncodeNil() + EncodeBool(bool) + EncodeString(string) + EncodeInt(int64) + EncodeUint(uint64) + EncodeFloat(float64) + EncodeBytes([]byte) + + // EncodeList is called when a slice or array is encountered (except for a + // []byte, which is handled by EncodeBytes). Its argument is the length of the + // slice or array. The encoding algorithm will call the returned Encoder that + // many times to encode the successive values of the list. After each such call, + // ListIndex will be called with the index of the element just encoded. + // + // For example, []string{"a", "b"} will result in these calls: + // enc2 := enc.EncodeList(2) + // enc2.EncodeString("a") + // enc2.ListIndex(0) + // enc2.EncodeString("b") + // enc2.ListIndex(1) + EncodeList(n int) Encoder + ListIndex(i int) + + // EncodeMap is called when a map is encountered. Its argument is the number of + // fields in the map. The encoding algorithm will call the returned Encoder that + // many times to encode the successive values of the map. After each such call, + // MapKey will be called with the key of the element just encoded. + // + // For example, map[string}int{"A": 1, "B": 2} will result in these calls: + // enc2 := enc.EncodeMap(2) + // enc2.EncodeInt(1) + // enc2.MapKey("A") + // enc2.EncodeInt(2) + // enc2.MapKey("B") + // + // EncodeMap is also called for structs. The map then consists of the exported + // fields of the struct. For struct{A, B int}{1, 2}, if EncodeStruct returns + // false, the same sequence of calls as above will occur. + EncodeMap(n int) Encoder + MapKey(string) + + // If the encoder wants to encode a value in a special way it should do so here + // and return true along with any error from the encoding. Otherwise, it should + // return false. + EncodeSpecial(v reflect.Value) (bool, error) +} + +// Encode encodes the value using the given Encoder. It traverses the value, +// iterating over arrays, slices, maps and the exported fields of structs. If it +// encounters a non-nil pointer, it encodes the value that it points to. +// Encode treats a few interfaces specially: +// +// If the value implements encoding.BinaryMarshaler, Encode invokes MarshalBinary +// on it and encodes the resulting byte slice. +// +// If the value implements encoding.TextMarshaler, Encode invokes MarshalText on it +// and encodes the resulting string. +// +// If the value implements proto.Message, Encode invokes proto.Marshal on it and encodes +// the resulting byte slice. Here proto is the package "google.golang.org/protobuf/proto". +// +// Not every map key type can be encoded. Only strings, integers (signed or +// unsigned), and types that implement encoding.TextMarshaler are permitted as map +// keys. These restrictions match exactly those of the encoding/json package. +func Encode(v reflect.Value, e Encoder) error { + return wrap(encode(v, e), gcerr.InvalidArgument) +} + +func encode(v reflect.Value, enc Encoder) error { + if !v.IsValid() { + enc.EncodeNil() + return nil + } + done, err := enc.EncodeSpecial(v) + if done { + return err + } + if v.Type().Implements(binaryMarshalerType) { + bytes, err := v.Interface().(encoding.BinaryMarshaler).MarshalBinary() + if err != nil { + return err + } + enc.EncodeBytes(bytes) + return nil + } + if v.Type().Implements(protoMessageType) { + if v.IsNil() { + enc.EncodeNil() + } else { + bytes, err := proto.Marshal(v.Interface().(proto.Message)) + if err != nil { + return err + } + enc.EncodeBytes(bytes) + } + return nil + } + if reflect.PtrTo(v.Type()).Implements(protoMessageType) { + bytes, err := proto.Marshal(v.Addr().Interface().(proto.Message)) + if err != nil { + return err + } + enc.EncodeBytes(bytes) + return nil + } + if v.Type().Implements(textMarshalerType) { + bytes, err := v.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return err + } + enc.EncodeString(string(bytes)) + return nil + } + switch v.Kind() { + case reflect.Bool: + enc.EncodeBool(v.Bool()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + enc.EncodeInt(v.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + enc.EncodeUint(v.Uint()) + case reflect.Float32, reflect.Float64: + enc.EncodeFloat(v.Float()) + case reflect.String: + enc.EncodeString(v.String()) + case reflect.Slice: + if v.IsNil() { + enc.EncodeNil() + return nil + } + fallthrough + case reflect.Array: + return encodeList(v, enc) + case reflect.Map: + return encodeMap(v, enc) + case reflect.Ptr: + if v.IsNil() { + enc.EncodeNil() + return nil + } + return encode(v.Elem(), enc) + case reflect.Interface: + if v.IsNil() { + enc.EncodeNil() + return nil + } + return encode(v.Elem(), enc) + + case reflect.Struct: + fields, err := fieldCache.Fields(v.Type()) + if err != nil { + return err + } + return encodeStructWithFields(v, fields, enc) + + default: + return gcerr.Newf(gcerr.InvalidArgument, nil, "cannot encode type %s", v.Type()) + } + return nil +} + +// Encode an array or non-nil slice. +func encodeList(v reflect.Value, enc Encoder) error { + // Byte slices encode specially. + if v.Type().Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 { + enc.EncodeBytes(v.Bytes()) + return nil + } + n := v.Len() + enc2 := enc.EncodeList(n) + for i := 0; i < n; i++ { + if err := encode(v.Index(i), enc2); err != nil { + return err + } + enc2.ListIndex(i) + } + return nil +} + +// Encode a map. +func encodeMap(v reflect.Value, enc Encoder) error { + if v.IsNil() { + enc.EncodeNil() + return nil + } + keys := v.MapKeys() + enc2 := enc.EncodeMap(len(keys)) + for _, k := range keys { + sk, err := stringifyMapKey(k) + if err != nil { + return err + } + if err := encode(v.MapIndex(k), enc2); err != nil { + return err + } + enc2.MapKey(sk) + } + return nil +} + +// k is the key of a map. Encode it as a string. +// Only strings, integers (signed or unsigned), and types that implement +// encoding.TextMarshaler are supported. +func stringifyMapKey(k reflect.Value) (string, error) { + // This is basically reflectWithString.resolve, from encoding/json/encode.go. + if k.Kind() == reflect.String { + return k.String(), nil + } + if tm, ok := k.Interface().(encoding.TextMarshaler); ok { + b, err := tm.MarshalText() + if err != nil { + return "", err + } + return string(b), nil + } + switch k.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(k.Int(), 10), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return strconv.FormatUint(k.Uint(), 10), nil + default: + return "", gcerr.Newf(gcerr.InvalidArgument, nil, "cannot encode key %v of type %s", k, k.Type()) + } +} + +func encodeStructWithFields(v reflect.Value, fields fields.List, e Encoder) error { + e2 := e.EncodeMap(len(fields)) + for _, f := range fields { + fv, ok := fieldByIndex(v, f.Index) + if !ok { + // if !ok, then f is a field in an embedded pointer to struct, and that embedded pointer + // is nil in v. In other words, the field exists in the struct type, but not this particular + // struct value. So we just ignore it. + continue + } + if f.ParsedTag.(tagOptions).omitEmpty && IsEmptyValue(fv) { + continue + } + if err := encode(fv, e2); err != nil { + return err + } + e2.MapKey(f.Name) + } + return nil +} + +// fieldByIndex retrieves the field of v at the given index if present. +// v must be a struct. index must refer to a valid field of v's type. +// The second return value is false if there is a nil embedded pointer +// along the path denoted by index. +// +// From encoding/json/encode.go. +func fieldByIndex(v reflect.Value, index []int) (reflect.Value, bool) { + for _, i := range index { + if v.Kind() == reflect.Ptr { + if v.IsNil() { + return reflect.Value{}, false + } + v = v.Elem() + } + v = v.Field(i) + } + return v, true +} + +//////////////////////////////////////////////////////////////// + +// TODO(jba): consider a fast path: if we are decoding into a struct, assume the same struct +// was used to encode. Then we can build a map from field names to functions, where each +// function avoids all the tests of Decode and contains just the code for setting the field. + +// TODO(jba): provide a way to override the check on missing fields. + +// A Decoder decodes data that was produced by Encode back into Go values. +// Each Decoder instance is responsible for decoding one value. +type Decoder interface { + // The AsXXX methods each report whether the value being decoded can be represented as + // a particular Go type. If so, the method should return the value as that type, and true; + // otherwise it should return the zero value and false. + AsString() (string, bool) + AsInt() (int64, bool) + AsUint() (uint64, bool) + AsFloat() (float64, bool) + AsBytes() ([]byte, bool) + AsBool() (bool, bool) + AsNull() bool + + // ListLen should return the length of the value being decoded and true, if the + // value can be decoded into a slice or array. Otherwise, ListLen should return + // (0, false). + ListLen() (int, bool) + + // If ListLen returned true, then DecodeList will be called. It should iterate + // over the value being decoded in sequence from index 0, invoking the callback + // for each element with the element's index and a Decoder for the element. + // If the callback returns false, DecodeList should return immediately. + DecodeList(func(int, Decoder) bool) + + // MapLen should return the number of fields of the value being decoded and true, + // if the value can be decoded into a map or struct. Otherwise, it should return + // (0, false). + MapLen() (int, bool) + + // DecodeMap iterates over the fields of the value being decoded, invoke the + // callback on each with field name, a Decoder for the field value, and a bool + // to indicate whether or not to use exact match for the field names. It will + // be called when MapLen returns true or decoding a struct. If the callback + // returns false, DecodeMap should return immediately. + DecodeMap(func(string, Decoder, bool) bool) + + // AsInterface should decode the value into the Go value that best represents it. + AsInterface() (interface{}, error) + + // If the decoder wants to decode a value in a special way it should do so here + // and return true, the decoded value, and any error from the decoding. + // Otherwise, it should return false. + AsSpecial(reflect.Value) (bool, interface{}, error) + + // String should return a human-readable representation of the Decoder, for error messages. + String() string +} + +// Decode decodes the value held in the Decoder d into v. +// Decode creates slices, maps and pointer elements as needed. +// It treats values that implement encoding.BinaryUnmarshaler, +// encoding.TextUnmarshaler and proto.Message specially; see Encode. +func Decode(v reflect.Value, d Decoder) error { + return wrap(decode(v, d), gcerr.InvalidArgument) +} + +func decode(v reflect.Value, d Decoder) error { + if !v.CanSet() { + return fmt.Errorf("while decoding: cannot set %+v", v) + } + // A Null value sets anything nullable to nil. + // If the value isn't nullable, we keep going. + // TODO(jba): should we treat decoding a null into a non-nullable as an error, or + // ignore it like encoding/json does? + if d.AsNull() { + switch v.Kind() { + case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: + v.Set(reflect.Zero(v.Type())) + return nil + } + } + + if done, val, err := d.AsSpecial(v); done { + if err != nil { + return err + } + if reflect.TypeOf(val).AssignableTo(v.Type()) { + v.Set(reflect.ValueOf(val)) + return nil + } + return decodingError(v, d) + } + + // Handle implemented interfaces first. + if reflect.PtrTo(v.Type()).Implements(binaryUnmarshalerType) { + if b, ok := d.AsBytes(); ok { + return v.Addr().Interface().(encoding.BinaryUnmarshaler).UnmarshalBinary(b) + } + return decodingError(v, d) + } + if reflect.PtrTo(v.Type()).Implements(protoMessageType) { + if b, ok := d.AsBytes(); ok { + return proto.Unmarshal(b, v.Addr().Interface().(proto.Message)) + } + return decodingError(v, d) + } + if reflect.PtrTo(v.Type()).Implements(textUnmarshalerType) { + if s, ok := d.AsString(); ok { + return v.Addr().Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(s)) + } + return decodingError(v, d) + } + + switch v.Kind() { + case reflect.Bool: + if b, ok := d.AsBool(); ok { + v.SetBool(b) + return nil + } + + case reflect.String: + if s, ok := d.AsString(); ok { + v.SetString(s) + return nil + } + + case reflect.Float32, reflect.Float64: + if f, ok := d.AsFloat(); ok { + v.SetFloat(f) + return nil + } + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + i, ok := d.AsInt() + if !ok { + // Accept a floating-point number with integral value. + f, ok := d.AsFloat() + if !ok { + return decodingError(v, d) + } + i = int64(f) + if float64(i) != f { + return gcerr.Newf(gcerr.InvalidArgument, nil, "float %f does not fit into %s", f, v.Type()) + } + } + if v.OverflowInt(i) { + return overflowError(i, v.Type()) + } + v.SetInt(i) + return nil + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + u, ok := d.AsUint() + if !ok { + // Accept a floating-point number with integral value. + f, ok := d.AsFloat() + if !ok { + return decodingError(v, d) + } + u = uint64(f) + if float64(u) != f { + return gcerr.Newf(gcerr.InvalidArgument, nil, "float %f does not fit into %s", f, v.Type()) + } + } + if v.OverflowUint(u) { + return overflowError(u, v.Type()) + } + v.SetUint(u) + return nil + + case reflect.Slice, reflect.Array: + return decodeList(v, d) + + case reflect.Map: + return decodeMap(v, d) + + case reflect.Ptr: + // If the pointer is nil, set it to a zero value. + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + return decode(v.Elem(), d) + + case reflect.Struct: + return decodeStruct(v, d) + + case reflect.Interface: + if v.NumMethod() == 0 { // empty interface + // If v holds a pointer, set the pointer. + if !v.IsNil() && v.Elem().Kind() == reflect.Ptr { + return decode(v.Elem(), d) + } + // Otherwise, create a fresh value. + x, err := d.AsInterface() + if err != nil { + return err + } + v.Set(reflect.ValueOf(x)) + return nil + } + // Any other kind of interface is an error??? + } + + return decodingError(v, d) +} + +func decodeList(v reflect.Value, d Decoder) error { + // If we're decoding into a byte slice or array, and the decoded value + // supports that, then do the decoding. + if v.Type().Elem().Kind() == reflect.Uint8 { + if b, ok := d.AsBytes(); ok { + if v.Kind() == reflect.Slice { + v.SetBytes(b) + return nil + } + // It's an array; copy the data in. + err := prepareLength(v, len(b)) + if err != nil { + return err + } + reflect.Copy(v, reflect.ValueOf(b)) + return nil + } + // Fall through to decode the []byte as an ordinary slice. + } + dlen, ok := d.ListLen() + if !ok { + return decodingError(v, d) + } + err := prepareLength(v, dlen) + if err != nil { + return err + } + d.DecodeList(func(i int, vd Decoder) bool { + if err != nil || i >= dlen { + return false + } + err = decode(v.Index(i), vd) + return err == nil + }) + return err +} + +// v must be a slice or array. We want it to be of length wantLen. Prepare it as +// necessary (details described in the code below), and return its resulting length. +// If an array is too short, return an error. This behavior differs from +// encoding/json, which just populates a short array with whatever it can and drops +// the rest. That can lose data. +func prepareLength(v reflect.Value, wantLen int) error { + vLen := v.Len() + if v.Kind() == reflect.Slice { + // Construct a slice of the right size, avoiding allocation if possible. + switch { + case vLen < wantLen: // v too short + if v.Cap() >= wantLen { // extend its length if there's room + v.SetLen(wantLen) + } else { // else make a new one + v.Set(reflect.MakeSlice(v.Type(), wantLen, wantLen)) + } + case vLen > wantLen: // v too long; truncate it + v.SetLen(wantLen) + } + } else { // array + switch { + case vLen < wantLen: // v too short + return gcerr.Newf(gcerr.InvalidArgument, nil, "array length %d is too short for incoming list of length %d", + vLen, wantLen) + case vLen > wantLen: // v too long; set extra elements to zero + z := reflect.Zero(v.Type().Elem()) + for i := wantLen; i < vLen; i++ { + v.Index(i).Set(z) + } + } + } + return nil +} + +// Since a map value is not settable via reflection, this function always creates a +// new element for each corresponding map key. Existing values of v are overwritten. +// This happens even if the map value is something like a pointer to a struct, where +// we could in theory populate the existing struct value instead of discarding it. +// This behavior matches encoding/json. +func decodeMap(v reflect.Value, d Decoder) error { + mapLen, ok := d.MapLen() + if !ok { + return decodingError(v, d) + } + t := v.Type() + if v.IsNil() { + v.Set(reflect.MakeMapWithSize(t, mapLen)) + } + et := t.Elem() + var err error + kt := v.Type().Key() + d.DecodeMap(func(key string, vd Decoder, _ bool) bool { + if err != nil { + return false + } + el := reflect.New(et).Elem() + err = decode(el, vd) + if err != nil { + return false + } + vk, e := unstringifyMapKey(key, kt) + if e != nil { + err = e + return false + } + v.SetMapIndex(vk, el) + return err == nil + }) + return err +} + +// Given a map key encoded as a string, and the type of the map key, convert the key +// into the type. +// For example, if we are decoding the key "3" for a map[int]interface{}, then key is "3" +// and keyType is reflect.Int. +func unstringifyMapKey(key string, keyType reflect.Type) (reflect.Value, error) { + // This code is mostly from the middle of decodeState.object in encoding/json/decode.go. + // Except for literalStore, which I don't understand. + // TODO(jba): understand literalStore. + switch { + case keyType.Kind() == reflect.String: + return reflect.ValueOf(key).Convert(keyType), nil + case reflect.PtrTo(keyType).Implements(textUnmarshalerType): + tu := reflect.New(keyType) + if err := tu.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(key)); err != nil { + return reflect.Value{}, err + } + return tu.Elem(), nil + case keyType.Kind() == reflect.Interface && keyType.NumMethod() == 0: + // TODO: remove this case? encoding/json doesn't support it. + return reflect.ValueOf(key), nil + default: + switch keyType.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + n, err := strconv.ParseInt(key, 10, 64) + if err != nil { + return reflect.Value{}, err + } + if reflect.Zero(keyType).OverflowInt(n) { + return reflect.Value{}, overflowError(n, keyType) + } + return reflect.ValueOf(n).Convert(keyType), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + n, err := strconv.ParseUint(key, 10, 64) + if err != nil { + return reflect.Value{}, err + } + if reflect.Zero(keyType).OverflowUint(n) { + return reflect.Value{}, overflowError(n, keyType) + } + return reflect.ValueOf(n).Convert(keyType), nil + default: + return reflect.Value{}, gcerr.Newf(gcerr.InvalidArgument, nil, "invalid key type %s", keyType) + } + } +} + +func decodeStruct(v reflect.Value, d Decoder) error { + fs, err := fieldCache.Fields(v.Type()) + if err != nil { + return err + } + d.DecodeMap(func(key string, d2 Decoder, exactMatch bool) bool { + if err != nil { + return false + } + var f *fields.Field + if exactMatch { + f = fs.MatchExact(key) + } else { + f = fs.MatchFold(key) + } + if f == nil { + err = gcerr.Newf(gcerr.InvalidArgument, nil, "no field matching %q in %s", key, v.Type()) + return false + } + fv, ok := fieldByIndexCreate(v, f.Index) + if !ok { + err = gcerr.Newf(gcerr.InvalidArgument, nil, + "setting field %q in %s: cannot create embedded pointer field of unexported type", + key, v.Type()) + return false + } + err = decode(fv, d2) + return err == nil + }) + return err +} + +// fieldByIndexCreate retrieves the the field of v at the given index if present, +// creating embedded struct pointers where necessary. +// v must be a struct. index must refer to a valid field of v's type. +// The second return value is false If there is a nil embedded pointer of unexported +// type along the path denoted by index. (We cannot create such pointers.) +func fieldByIndexCreate(v reflect.Value, index []int) (reflect.Value, bool) { + for _, i := range index { + if v.Kind() == reflect.Ptr { + if v.IsNil() { + if !v.CanSet() { + return reflect.Value{}, false + } + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + v = v.Field(i) + } + return v, true +} + +func decodingError(v reflect.Value, d Decoder) error { + return gcerr.New(gcerr.InvalidArgument, nil, 2, fmt.Sprintf("cannot set type %s to %v", v.Type(), d)) +} + +func overflowError(x interface{}, t reflect.Type) error { + return gcerr.New(gcerr.InvalidArgument, nil, 2, fmt.Sprintf("value %v overflows type %s", x, t)) +} + +func wrap(err error, code gcerr.ErrorCode) error { + if _, ok := err.(*gcerr.Error); !ok && err != nil { + err = gcerr.New(code, err, 2, err.Error()) + } + return err +} + +var fieldCache = fields.NewCache(parseTag, nil, nil) + +// IsEmptyValue returns whether or not v is a zero value of its type. +// Copied from encoding/json, go 1.12. +func IsEmptyValue(v reflect.Value) bool { + switch k := v.Kind(); k { + 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.Ptr: + return v.IsNil() + } + return false +} + +// Options for struct tags. +type tagOptions struct { + omitEmpty bool // do not encode value if empty +} + +// parseTag interprets docstore struct field tags. +func parseTag(t reflect.StructTag) (name string, keep bool, other interface{}, err error) { + var opts []string + name, keep, opts = fields.ParseStandardTag("docstore", t) + tagOpts := tagOptions{} + for _, opt := range opts { + switch opt { + case "omitempty": + tagOpts.omitEmpty = true + default: + return "", false, nil, gcerr.Newf(gcerr.InvalidArgument, nil, "unknown tag option: %q", opt) + } + } + return name, keep, tagOpts, nil +} diff --git a/go-cloud/docstore/driver/codec_test.go b/go-cloud/docstore/driver/codec_test.go new file mode 100644 index 000000000..5ab5c3e78 --- /dev/null +++ b/go-cloud/docstore/driver/codec_test.go @@ -0,0 +1,700 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 driver + +import ( + "errors" + "fmt" + "reflect" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "google.golang.org/protobuf/proto" + tspb "google.golang.org/protobuf/types/known/timestamppb" +) + +type myString string + +type te struct{ X byte } + +func (e te) MarshalText() ([]byte, error) { + return []byte{e.X}, nil +} + +func (e *te) UnmarshalText(b []byte) error { + if len(b) != 1 { + return errors.New("te.UnmarshalText: need exactly 1 byte") + } + e.X = b[0] + return nil +} + +type special int + +func (special) MarshalBinary() ([]byte, error) { panic("should never be called") } +func (*special) UnmarshalBinary([]byte) error { panic("should never be called") } + +type badSpecial int + +type Embed1 struct { + E1 string +} +type Embed2 struct { + E2 string +} + +type embed3 struct { + E3 string +} + +type embed4 struct { + E4 string +} + +type MyStruct struct { + A int + B *bool + C []*te + D []time.Time + T *tspb.Timestamp + Embed1 + *Embed2 + embed3 + *embed4 + Omit int `docstore:"-"` + OmitEmpty int `docstore:",omitempty"` + Rename int `docstore:"rename"` +} + +func TestEncode(t *testing.T) { + var seven int32 = 7 + var nullptr *int + tm := time.Now() + tmb, err := tm.MarshalBinary() + if err != nil { + t.Fatal(err) + } + tru := true + ts := &tspb.Timestamp{Seconds: 25, Nanos: 300} + tsb, err := proto.Marshal(ts) + if err != nil { + t.Fatal(err) + } + for _, test := range []struct { + in, want interface{} + }{ + {nil, nil}, + {0, int64(0)}, + {uint64(999), uint64(999)}, + {float32(3.5), float64(3.5)}, + {"", ""}, + {"x", "x"}, + {true, true}, + {nullptr, nil}, + {seven, int64(seven)}, + {&seven, int64(seven)}, + {[]byte{1, 2}, []byte{1, 2}}, + {[2]byte{3, 4}, []interface{}{uint64(3), uint64(4)}}, + {[]int(nil), nil}, + {[]int{}, []interface{}{}}, + {[]int{1, 2}, []interface{}{int64(1), int64(2)}}, + { + [][]string{{"a", "b"}, {"c", "d"}}, + []interface{}{ + []interface{}{"a", "b"}, + []interface{}{"c", "d"}, + }, + }, + {[...]int{1, 2}, []interface{}{int64(1), int64(2)}}, + {[]interface{}{nil, false}, []interface{}{nil, false}}, + {map[string]int(nil), nil}, + {map[string]int{}, map[string]interface{}{}}, + { + map[string]int{"a": 1, "b": 2}, + map[string]interface{}{"a": int64(1), "b": int64(2)}, + }, + {tm, tmb}, + {ts, tsb}, + {te{'A'}, "A"}, + {special(17), 17}, + {myString("x"), "x"}, + {[]myString{"x"}, []interface{}{"x"}}, + {map[myString]myString{"a": "x"}, map[string]interface{}{"a": "x"}}, + { + map[int]bool{17: true}, + map[string]interface{}{"17": true}, + }, + { + map[uint]bool{18: true}, + map[string]interface{}{"18": true}, + }, + { + map[te]bool{{'B'}: true}, + map[string]interface{}{"B": true}, + }, + { + MyStruct{ + A: 1, + B: &tru, + C: []*te{{'T'}}, + D: []time.Time{tm}, + T: ts, + Embed1: Embed1{E1: "E1"}, + Embed2: &Embed2{E2: "E2"}, + embed3: embed3{E3: "E3"}, + embed4: &embed4{E4: "E4"}, + Omit: 3, + OmitEmpty: 4, + Rename: 5, + }, + map[string]interface{}{ + "A": int64(1), + "B": true, + "C": []interface{}{"T"}, + "D": []interface{}{tmb}, + "T": tsb, + "E1": "E1", + "E2": "E2", + "E3": "E3", + "E4": "E4", + "OmitEmpty": int64(4), + "rename": int64(5), + }, + }, + { + MyStruct{}, + map[string]interface{}{ + "A": int64(0), + "B": nil, + "C": nil, + "D": nil, + "T": nil, + "E1": "", + "E3": "", + "rename": int64(0), + }, + }, + } { + enc := &testEncoder{} + if err := Encode(reflect.ValueOf(test.in), enc); err != nil { + t.Fatal(err) + } + got := enc.val + if diff := cmp.Diff(got, test.want); diff != "" { + t.Errorf("%#v (got=-, want=+):\n%s", test.in, diff) + } + } +} + +type badBinaryMarshaler struct{} + +func (badBinaryMarshaler) MarshalBinary() ([]byte, error) { return nil, errors.New("bad") } +func (*badBinaryMarshaler) UnmarshalBinary([]byte) error { return errors.New("bad") } + +type badTextMarshaler struct{} + +func (badTextMarshaler) MarshalText() ([]byte, error) { return nil, errors.New("bad") } +func (*badTextMarshaler) UnmarshalText([]byte) error { return errors.New("bad") } + +func TestEncodeErrors(t *testing.T) { + for _, test := range []struct { + desc string + val interface{} + }{ + {"MarshalBinary fails", badBinaryMarshaler{}}, + {"MarshalText fails", badTextMarshaler{}}, + {"bad type", make(chan int)}, + {"bad type in list", []interface{}{func() {}}}, + {"bad type in map", map[string]interface{}{"a": func() {}}}, + {"bad type in struct", &struct{ C chan int }{}}, + {"bad map key type", map[float32]int{1: 1}}, + {"MarshalText for map key fails", map[badTextMarshaler]int{{}: 1}}, + } { + enc := &testEncoder{} + if err := Encode(reflect.ValueOf(test.val), enc); err == nil { + t.Errorf("%s: got nil, want error", test.desc) + } else if c := gcerrors.Code(err); c != gcerrors.InvalidArgument { + t.Errorf("%s: got code %s, want InvalidArgument", test.desc, c) + } + } +} + +type testEncoder struct { + val interface{} +} + +func (e *testEncoder) EncodeNil() { e.val = nil } +func (e *testEncoder) EncodeBool(x bool) { e.val = x } +func (e *testEncoder) EncodeString(x string) { e.val = x } +func (e *testEncoder) EncodeInt(x int64) { e.val = x } +func (e *testEncoder) EncodeUint(x uint64) { e.val = x } +func (e *testEncoder) EncodeFloat(x float64) { e.val = x } +func (e *testEncoder) EncodeBytes(x []byte) { e.val = x } + +var ( + typeOfSpecial = reflect.TypeOf(special(0)) + typeOfBadSpecial = reflect.TypeOf(badSpecial(0)) +) + +func (e *testEncoder) EncodeSpecial(v reflect.Value) (bool, error) { + // special would normally encode as a []byte, because it implements BinaryMarshaler. + // Encode it as an int instead. + if v.Type() == typeOfSpecial { + e.val = int(v.Interface().(special)) + return true, nil + } + return false, nil +} + +func (e *testEncoder) ListIndex(int) { panic("impossible") } +func (e *testEncoder) MapKey(string) { panic("impossible") } + +func (e *testEncoder) EncodeList(n int) Encoder { + s := make([]interface{}, n) + e.val = s + return &listEncoder{s: s} +} + +func (e *testEncoder) EncodeMap(n int) Encoder { + m := make(map[string]interface{}, n) + e.val = m + return &mapEncoder{m: m} +} + +type listEncoder struct { + s []interface{} + testEncoder +} + +func (e *listEncoder) ListIndex(i int) { e.s[i] = e.val } + +type mapEncoder struct { + m map[string]interface{} + testEncoder +} + +func (e *mapEncoder) MapKey(k string) { e.m[k] = e.val } + +func TestDecode(t *testing.T) { + two := 2 + tru := true + fa := false + ptru := &tru + pfa := &fa + tm := time.Now() + tmb, err := tm.MarshalBinary() + if err != nil { + t.Fatal(err) + } + ts := &tspb.Timestamp{Seconds: 25, Nanos: 300} + tsb, err := proto.Marshal(ts) + if err != nil { + t.Fatal(err) + } + + for _, test := range []struct { + in interface{} // pointer that will be set + val interface{} // value to set it to + want interface{} + exactMatch bool + }{ + {new(interface{}), nil, nil, true}, + {new(int), int64(7), int(7), true}, + {new(uint8), uint64(250), uint8(250), true}, + {new(bool), true, true, true}, + {new(string), "x", "x", true}, + {new(float32), 4.25, float32(4.25), true}, + {new(*int), int64(2), &two, true}, + {new(*int), nil, (*int)(nil), true}, + {new([]byte), []byte("foo"), []byte("foo"), true}, + {new([]string), []interface{}{"a", "b"}, []string{"a", "b"}, true}, + {new([]**bool), []interface{}{true, false}, []**bool{&ptru, &pfa}, true}, + {&[1]int{1}, []interface{}{2}, [1]int{2}, true}, + {&[2]int{1, 2}, []interface{}{3}, [2]int{3, 0}, true}, // zero extra elements + {&[]int{1, 2}, []interface{}{3}, []int{3}, true}, // truncate slice + { + // extend slice + func() *[]int { s := make([]int, 1, 2); return &s }(), + []interface{}{5, 6}, + []int{5, 6}, + true, + }, + { + new(map[string]string), + map[string]interface{}{"a": "b"}, + map[string]string{"a": "b"}, + true, + }, + { + new(map[int]bool), + map[string]interface{}{"17": true}, + map[int]bool{17: true}, + true, + }, + { + new(map[te]bool), + map[string]interface{}{"B": true}, + map[te]bool{{'B'}: true}, + true, + }, + { + new(map[interface{}]bool), + map[string]interface{}{"B": true}, + map[interface{}]bool{"B": true}, + true, + }, + { + new(map[string][]bool), + map[string]interface{}{ + "a": []interface{}{true, false}, + "b": []interface{}{false, true}, + }, + map[string][]bool{ + "a": {true, false}, + "b": {false, true}, + }, + true, + }, + {new(special), 17, special(17), true}, + {new(myString), "x", myString("x"), true}, + {new([]myString), []interface{}{"x"}, []myString{"x"}, true}, + {new(time.Time), tmb, tm, true}, + {new(*time.Time), tmb, &tm, true}, + {new(*tspb.Timestamp), tsb, ts, true}, + {new([]time.Time), []interface{}{tmb}, []time.Time{tm}, true}, + {new([]*time.Time), []interface{}{tmb}, []*time.Time{&tm}, true}, + { + new(map[myString]myString), + map[string]interface{}{"a": "x"}, + map[myString]myString{"a": "x"}, + true, + }, + { + new(map[string]time.Time), + map[string]interface{}{"t": tmb}, + map[string]time.Time{"t": tm}, + true, + }, + { + new(map[string]*time.Time), + map[string]interface{}{"t": tmb}, + map[string]*time.Time{"t": &tm}, + true, + }, + {new(te), "A", te{'A'}, true}, + {new(**te), "B", func() **te { x := &te{'B'}; return &x }(), true}, + + { + &MyStruct{embed4: &embed4{}}, + map[string]interface{}{ + "A": int64(1), + "B": true, + "C": []interface{}{"T"}, + "D": []interface{}{tmb}, + "T": tsb, + "E1": "E1", + "E2": "E2", + "E3": "E3", + "E4": "E4", + }, + MyStruct{ + A: 1, B: &tru, C: []*te{{'T'}}, D: []time.Time{tm}, T: ts, + Embed1: Embed1{E1: "E1"}, + Embed2: &Embed2{E2: "E2"}, + embed3: embed3{E3: "E3"}, + embed4: &embed4{E4: "E4"}, + }, + true, + }, + { + &MyStruct{embed4: &embed4{}}, + map[string]interface{}{ + "a": int64(1), + "b": true, + "c": []interface{}{"T"}, + "d": []interface{}{tmb}, + "t": tsb, + "e1": "E1", + "e2": "E2", + "e3": "E3", + "e4": "E4", + }, + MyStruct{ + A: 1, B: &tru, C: []*te{{'T'}}, D: []time.Time{tm}, T: ts, + Embed1: Embed1{E1: "E1"}, + Embed2: &Embed2{E2: "E2"}, + embed3: embed3{E3: "E3"}, + embed4: &embed4{E4: "E4"}, + }, + false, + }, + } { + dec := &testDecoder{test.val, test.exactMatch} + if err := Decode(reflect.ValueOf(test.in).Elem(), dec); err != nil { + t.Fatalf("%T: %v", test.in, err) + } + got := reflect.ValueOf(test.in).Elem().Interface() + diff := cmp.Diff(got, test.want, cmp.Comparer(proto.Equal), cmp.AllowUnexported(MyStruct{})) + if diff != "" { + t.Errorf("%T (got=-, want=+): %s", test.in, diff) + } + } +} + +func TestDecodeErrors(t *testing.T) { + for _, test := range []struct { + desc string + in, val interface{} + }{ + { + "bad type", + new(int), + "foo", + }, + { + "bad type in list", + new([]int), + []interface{}{1, "foo"}, + }, + { + "array too short", + new([1]bool), + []interface{}{true, false}, + }, + { + "bad map key type", + new(map[float64]interface{}), + map[string]interface{}{"a": 1}, + }, + { + "unknown struct field", + new(MyStruct), + map[string]interface{}{"bad": 1}, + }, + { + "nil embedded, unexported pointer to struct", + new(MyStruct), + map[string]interface{}{"E4": "E4"}, + }, + { + "int overflow", + new(int8), + 257, + }, + { + "uint overflow", + new(uint8), + uint(257), + }, + { + "non-integral float (int)", + new(int), + 1.5, + }, + { + "non-integral float (uint)", + new(uint), + 1.5, + }, + { + "bad special", + new(badSpecial), + badSpecial(0), + }, + { + "bad binary unmarshal", + new(badBinaryMarshaler), + []byte{1}, + }, + { + "binary unmarshal with non-byte slice", + new(time.Time), + 1, + }, + { + "bad text unmarshal", + new(badTextMarshaler), + "foo", + }, + { + "text unmarshal with non-string", + new(badTextMarshaler), + 1, + }, + { + "bad text unmarshal in map key", + new(map[badTextMarshaler]int), + map[string]interface{}{"a": 1}, + }, + { + "bad int map key", + new(map[int]int), + map[string]interface{}{"a": 1}, + }, + { + "overflow in int map key", + new(map[int8]int), + map[string]interface{}{"256": 1}, + }, + { + "bad uint map key", + new(map[uint]int), + map[string]interface{}{"a": 1}, + }, + { + "overflow in uint map key", + new(map[uint8]int), + map[string]interface{}{"256": 1}, + }, + { + "case mismatch when decoding with exact match", + &MyStruct{embed4: &embed4{}}, + map[string]interface{}{ + "a": int64(1), + "b": true, + "e1": "E1", + "e2": "E2", + }, + }, + } { + dec := &testDecoder{test.val, true} + err := Decode(reflect.ValueOf(test.in).Elem(), dec) + if e, ok := err.(*gcerr.Error); !ok || err == nil || e.Code != gcerr.InvalidArgument { + t.Errorf("%s: got %v, want InvalidArgument Error", test.desc, err) + } + } +} + +func TestDecodeFail(t *testing.T) { + // Verify that failure to decode a value results in an error. + for _, in := range []interface{}{ + new(interface{}), new(bool), new(string), new(int), new(uint), new(float32), + new([]byte), new([]int), new(map[string]interface{}), + } { + dec := &failDecoder{} + err := Decode(reflect.ValueOf(in).Elem(), dec) + if e, ok := err.(*gcerr.Error); !ok || err == nil || e.Code != gcerr.InvalidArgument { + t.Errorf("%T: got %v, want InvalidArgument Error", in, err) + } + } +} + +type testDecoder struct { + val interface{} // assume encoded by testEncoder. + exactMatch bool +} + +func (d testDecoder) String() string { + return fmt.Sprintf("%+v of type %T", d.val, d.val) +} + +func (d testDecoder) AsNull() bool { + return d.val == nil +} + +func (d testDecoder) AsBool() (bool, bool) { x, ok := d.val.(bool); return x, ok } +func (d testDecoder) AsString() (string, bool) { x, ok := d.val.(string); return x, ok } + +func (d testDecoder) AsInt() (int64, bool) { + switch v := d.val.(type) { + case int64: + return v, true + case int: + return int64(v), true + default: + return 0, false + } +} + +func (d testDecoder) AsUint() (uint64, bool) { + switch v := d.val.(type) { + case uint64: + return v, true + case uint: + return uint64(v), true + default: + return 0, false + } +} + +func (d testDecoder) AsFloat() (float64, bool) { x, ok := d.val.(float64); return x, ok } +func (d testDecoder) AsBytes() ([]byte, bool) { x, ok := d.val.([]byte); return x, ok } + +func (d testDecoder) ListLen() (int, bool) { + l, ok := d.val.([]interface{}) + if !ok { + return 0, false + } + return len(l), true +} + +func (d testDecoder) DecodeList(f func(i int, vd Decoder) bool) { + for i, v := range d.val.([]interface{}) { + if !f(i, testDecoder{v, d.exactMatch}) { + break + } + } +} + +func (d testDecoder) MapLen() (int, bool) { + if m, ok := d.val.(map[string]interface{}); ok { + return len(m), true + } + return 0, false +} + +func (d testDecoder) DecodeMap(f func(key string, vd Decoder, exactMatch bool) bool) { + for k, v := range d.val.(map[string]interface{}) { + if !f(k, testDecoder{v, d.exactMatch}, d.exactMatch) { + break + } + } +} + +func (d testDecoder) AsInterface() (interface{}, error) { + return d.val, nil +} + +func (d testDecoder) AsSpecial(v reflect.Value) (bool, interface{}, error) { + switch v.Type() { + case typeOfSpecial: + return true, special(d.val.(int)), nil + case typeOfBadSpecial: + return true, nil, errors.New("bad special") + default: + return false, nil, nil + } +} + +// All of failDecoder's methods return failure. +type failDecoder struct{} + +func (failDecoder) String() string { return "failDecoder" } +func (failDecoder) AsNull() bool { return false } +func (failDecoder) AsBool() (bool, bool) { return false, false } +func (failDecoder) AsString() (string, bool) { return "", false } +func (failDecoder) AsInt() (int64, bool) { return 0, false } +func (failDecoder) AsUint() (uint64, bool) { return 0, false } +func (failDecoder) AsFloat() (float64, bool) { return 0, false } +func (failDecoder) AsBytes() ([]byte, bool) { return nil, false } +func (failDecoder) ListLen() (int, bool) { return 0, false } +func (failDecoder) DecodeList(func(i int, vd Decoder) bool) { panic("impossible") } +func (failDecoder) MapLen() (int, bool) { return 0, false } +func (failDecoder) DecodeMap(func(string, Decoder, bool) bool) { panic("impossible") } +func (failDecoder) AsSpecial(v reflect.Value) (bool, interface{}, error) { return false, nil, nil } +func (failDecoder) AsInterface() (interface{}, error) { return nil, errors.New("fail") } diff --git a/go-cloud/docstore/driver/compare.go b/go-cloud/docstore/driver/compare.go new file mode 100644 index 000000000..5afc472ab --- /dev/null +++ b/go-cloud/docstore/driver/compare.go @@ -0,0 +1,84 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// Useful comparison functions. + +package driver + +import ( + "fmt" + "math/big" + "reflect" + "time" +) + +// CompareTimes returns -1, 1 or 0 depending on whether t1 is before, after or +// equal to t2. +func CompareTimes(t1, t2 time.Time) int { + switch { + case t1.Before(t2): + return -1 + case t1.After(t2): + return 1 + default: + return 0 + } +} + +// CompareNumbers returns -1, 1 or 0 depending on whether n1 is less than, +// greater than or equal to n2. n1 and n2 must be signed integer, unsigned +// integer, or floating-point values, but they need not be the same type. +// +// If both types are integers or both floating-point, CompareNumbers behaves +// like Go comparisons on those types. If one operand is integer and the other +// is floating-point, CompareNumbers correctly compares the mathematical values +// of the numbers, without loss of precision. +func CompareNumbers(n1, n2 interface{}) (int, error) { + v1, ok := n1.(reflect.Value) + if !ok { + v1 = reflect.ValueOf(n1) + } + v2, ok := n2.(reflect.Value) + if !ok { + v2 = reflect.ValueOf(n2) + } + f1, err := toBigFloat(v1) + if err != nil { + return 0, err + } + f2, err := toBigFloat(v2) + if err != nil { + return 0, err + } + return f1.Cmp(f2), nil +} + +func toBigFloat(x reflect.Value) (*big.Float, error) { + var f big.Float + switch x.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + f.SetInt64(x.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + f.SetUint64(x.Uint()) + case reflect.Float32, reflect.Float64: + f.SetFloat64(x.Float()) + default: + typ := "nil" + if x.IsValid() { + typ = fmt.Sprint(x.Type()) + } + return nil, fmt.Errorf("%v of type %s is not a number", x, typ) + } + return &f, nil +} diff --git a/go-cloud/docstore/driver/compare_test.go b/go-cloud/docstore/driver/compare_test.go new file mode 100644 index 000000000..8a1bce053 --- /dev/null +++ b/go-cloud/docstore/driver/compare_test.go @@ -0,0 +1,91 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 driver + +import ( + "math" + "testing" + "time" +) + +func TestCompareTimes(t *testing.T) { + t1 := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC) + t2 := t1.Add(1) + for _, test := range []struct { + in1, in2 time.Time + want int + }{ + {t1, t2, -1}, + {t2, t1, 1}, + {t1, t1, 0}, + } { + got := CompareTimes(test.in1, test.in2) + if got != test.want { + t.Errorf("CompareTimes(%v, %v) == %d, want %d", test.in1, test.in2, got, test.want) + } + } +} + +func TestCompareNumbers(t *testing.T) { + check := func(n1, n2 interface{}, want int) { + t.Helper() + got, err := CompareNumbers(n1, n2) + if err != nil { + t.Fatalf("CompareNumbers(%T(%[1]v), %T(%[2]v)): %v", n1, n2, err) + } + if got != want { + t.Errorf("CompareNumbers(%T(%[1]v), %T(%[2]v)) = %d, want %d", n1, n2, got, want) + } + } + + for _, test := range []struct { + in1, in2 interface{} + want int + }{ + // simple cases + {1, 1, 0}, + {1, 2, -1}, + {1.0, 1.0, 0}, + {1.0, 2.0, -1}, + + // mixed int types + {int8(1), int64(1), 0}, + {int8(2), int64(1), 1}, + {uint(1), int(1), 0}, + {uint(2), int(1), 1}, + + // mixed int and float + {1, 1.0, 0}, + {1, 1.1, -1}, + {2, 1.1, 1}, + + // large numbers + {int64(math.MaxInt64), int64(math.MaxInt64), 0}, + {uint64(math.MaxUint64), uint64(math.MaxUint64), 0}, + {float64(math.MaxFloat64), float64(math.MaxFloat64), 0}, + {int64(math.MaxInt64), int64(math.MaxInt64 - 1), 1}, + {int64(math.MaxInt64), float64(math.MaxInt64 - 1), -1}, // float is bigger because it gets rounded up + {int64(math.MaxInt64), uint64(math.MaxUint64), -1}, + + // special floats + {int64(math.MaxInt64), math.Inf(1), -1}, + {int64(math.MinInt64), math.Inf(-1), 1}, + } { + check(test.in1, test.in2, test.want) + if test.want != 0 { + check(test.in2, test.in1, -test.want) + } + } +} diff --git a/go-cloud/docstore/driver/document.go b/go-cloud/docstore/driver/document.go new file mode 100644 index 000000000..0349c2dd2 --- /dev/null +++ b/go-cloud/docstore/driver/document.go @@ -0,0 +1,206 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 driver + +import ( + "reflect" + + "github.com/DataDog/iceberg-go/go-cloud/docstore/internal/fields" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +// A Document is a lightweight wrapper around either a map[string]interface{} or a +// struct pointer. It provides operations to get and set fields and field paths. +type Document struct { + Origin interface{} // the argument to NewDocument + m map[string]interface{} // nil if it's a *struct + s reflect.Value // the struct reflected + fields fields.List // for structs +} + +// NewDocument creates a new document from doc, which must be a non-nil +// map[string]interface{} or struct pointer. +func NewDocument(doc interface{}) (Document, error) { + if doc == nil { + return Document{}, gcerr.Newf(gcerr.InvalidArgument, nil, "document cannot be nil") + } + if m, ok := doc.(map[string]interface{}); ok { + if m == nil { + return Document{}, gcerr.Newf(gcerr.InvalidArgument, nil, "document map cannot be nil") + } + return Document{Origin: doc, m: m}, nil + } + v := reflect.ValueOf(doc) + t := v.Type() + if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct { + return Document{}, gcerr.Newf(gcerr.InvalidArgument, nil, "expecting *struct or map[string]interface{}, got %s", t) + } + t = t.Elem() + if v.IsNil() { + return Document{}, gcerr.Newf(gcerr.InvalidArgument, nil, "document struct pointer cannot be nil") + } + fields, err := fieldCache.Fields(t) + if err != nil { + return Document{}, err + } + return Document{Origin: doc, s: v.Elem(), fields: fields}, nil +} + +// GetField returns the value of the named document field. +func (d Document) GetField(field string) (interface{}, error) { + if d.m != nil { + x, ok := d.m[field] + if !ok { + return nil, gcerr.Newf(gcerr.NotFound, nil, "field %q not found in map", field) + } + return x, nil + } + v, err := d.structField(field) + if err != nil { + return nil, err + } + return v.Interface(), nil +} + +// getDocument gets the value of the given field path, which must be a document. +// If create is true, it creates intermediate documents as needed. +func (d Document) getDocument(fp []string, create bool) (Document, error) { + if len(fp) == 0 { + return d, nil + } + x, err := d.GetField(fp[0]) + if err != nil { + if create && gcerrors.Code(err) == gcerrors.NotFound { + // TODO(jba): create the right type for the struct field. + x = map[string]interface{}{} + if err := d.SetField(fp[0], x); err != nil { + return Document{}, err + } + } else { + return Document{}, err + } + } + d2, err := NewDocument(x) + if err != nil { + return Document{}, err + } + return d2.getDocument(fp[1:], create) +} + +// Get returns the value of the given field path in the document. +func (d Document) Get(fp []string) (interface{}, error) { + d2, err := d.getDocument(fp[:len(fp)-1], false) + if err != nil { + return nil, err + } + return d2.GetField(fp[len(fp)-1]) +} + +func (d Document) structField(name string) (reflect.Value, error) { + // We do case-insensitive match here to cover the MongoDB's lowercaseFields + // option. + f := d.fields.MatchFold(name) + if f == nil { + return reflect.Value{}, gcerr.Newf(gcerr.NotFound, nil, "field %q not found in struct type %s", name, d.s.Type()) + } + fv, ok := fieldByIndex(d.s, f.Index) + if !ok { + return reflect.Value{}, gcerr.Newf(gcerr.InvalidArgument, nil, "nil embedded pointer; cannot get field %q from %s", + name, d.s.Type()) + } + return fv, nil +} + +// Set sets the value of the field path in the document. +// This creates sub-maps as necessary, if possible. +func (d Document) Set(fp []string, val interface{}) error { + d2, err := d.getDocument(fp[:len(fp)-1], true) + if err != nil { + return err + } + return d2.SetField(fp[len(fp)-1], val) +} + +// SetField sets the field to value in the document. +func (d Document) SetField(field string, value interface{}) error { + if d.m != nil { + d.m[field] = value + return nil + } + v, err := d.structField(field) + if err != nil { + return err + } + if !v.CanSet() { + return gcerr.Newf(gcerr.InvalidArgument, nil, "cannot set field %s in struct of type %s: not addressable", + field, d.s.Type()) + } + v.Set(reflect.ValueOf(value)) + return nil +} + +// FieldNames returns names of the top-level fields of d. +func (d Document) FieldNames() []string { + var names []string + if d.m != nil { + for k := range d.m { + names = append(names, k) + } + } else { + for _, f := range d.fields { + names = append(names, f.Name) + } + } + return names +} + +// Encode encodes the document using the given Encoder. +func (d Document) Encode(e Encoder) error { + if d.m != nil { + return encodeMap(reflect.ValueOf(d.m), e) + } + return encodeStructWithFields(d.s, d.fields, e) +} + +// Decode decodes the document using the given Decoder. +func (d Document) Decode(dec Decoder) error { + if d.m != nil { + return decodeMap(reflect.ValueOf(d.m), dec) + } + return decodeStruct(d.s, dec) +} + +// HasField returns whether or not d has a certain field. +func (d Document) HasField(field string) bool { + return d.hasField(field, true) +} + +// HasFieldFold is like HasField but matches case-insensitively for struct +// field. +func (d Document) HasFieldFold(field string) bool { + return d.hasField(field, false) +} + +func (d Document) hasField(field string, exactMatch bool) bool { + if d.m != nil { + _, ok := d.m[field] + return ok + } + if exactMatch { + return d.fields.MatchExact(field) != nil + } + return d.fields.MatchFold(field) != nil +} diff --git a/go-cloud/docstore/driver/document_test.go b/go-cloud/docstore/driver/document_test.go new file mode 100644 index 000000000..e8bd37c96 --- /dev/null +++ b/go-cloud/docstore/driver/document_test.go @@ -0,0 +1,290 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 driver + +import ( + "fmt" + "sort" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +type S struct { + I int + M map[string]interface{} +} + +func TestNewDocument(t *testing.T) { + for _, test := range []struct { + in interface{} + wantErr bool + wantMap bool + }{ + {in: nil, wantErr: true}, + {in: map[string]interface{}{}, wantMap: true}, + {in: map[string]interface{}(nil), wantErr: true}, + {in: S{}, wantErr: true}, + {in: &S{}, wantMap: false}, + {in: (*S)(nil), wantErr: true}, + {in: map[string]bool{}, wantErr: true}, + } { + got, err := NewDocument(test.in) + if err != nil { + if !test.wantErr { + t.Errorf("%#v: got %v, did not want error", test.in, err) + } + if c := gcerrors.Code(err); c != gcerrors.InvalidArgument { + t.Errorf("%#v: got error code %s, want InvalidArgument", test.in, c) + } + continue + } + if test.wantErr { + t.Errorf("%#v: got nil, want error", test.in) + continue + } + if g := (got.m != nil); g != test.wantMap { + t.Errorf("%#v: got map: %t, want map: %t", test.in, g, test.wantMap) + } + } +} + +func TestGet(t *testing.T) { + in := map[string]interface{}{ + "S": &S{ + I: 2, + M: map[string]interface{}{ + "J": 3, + "T": &S{I: 4}, + }, + }, + } + doc, err := NewDocument(in) + if err != nil { + t.Fatal(err) + } + + for _, test := range []struct { + fp string + want interface{} + }{ + {"S.I", 2}, + {"S.i", 2}, + {"S.M.J", 3}, + {"S.m.J", 3}, + {"S.M.T.I", 4}, + {"S.m.T.i", 4}, + } { + fp := strings.Split(test.fp, ".") + got, err := doc.Get(fp) + if err != nil { + t.Fatal(err) + } + if !cmp.Equal(got, test.want) { + t.Errorf("%s: got %v, want %v", got, test.fp, test.want) + } + } +} + +func TestSet(t *testing.T) { + in := map[string]interface{}{ + "S": &S{ + I: 2, + M: map[string]interface{}{ + "J": 3, + "T": &S{I: 4}, + }, + }, + } + doc, err := NewDocument(in) + if err != nil { + t.Fatal(err) + } + for _, test := range []struct { + fp string + val interface{} + }{ + {"S.I", -1}, + {"S.i", -2}, + {"S.M.J", -3}, + {"S.m.J", -4}, + {"S.M.T.I", -5}, + {"S.m.T.i", -6}, + {"new.field", -7}, + } { + fp := strings.Split(test.fp, ".") + if err := doc.Set(fp, test.val); err != nil { + t.Fatalf("%q: %v", test.fp, err) + } + got, err := doc.Get(fp) + if err != nil { + t.Fatalf("%s: %v", test.fp, err) + } + if !cmp.Equal(got, test.val) { + t.Errorf("got %v, want %v", got, test.val) + } + } +} + +func TestGetField(t *testing.T) { + type S struct { + A int `docstore:"a"` + B interface{} `docstore:"b"` + } + + want := 1 + for _, in := range []interface{}{ + map[string]interface{}{"a": want, "b": nil}, + &S{A: want, B: nil}, + } { + t.Run(fmt.Sprint(in), func(t *testing.T) { + doc, err := NewDocument(in) + if err != nil { + t.Fatal(err) + } + got, err := doc.GetField("a") + if err != nil { + t.Fatal(err) + } + if got != want { + t.Errorf("got %v, want %v", got, want) + } + + got, err = doc.GetField("b") + if err != nil { + t.Fatal(err) + } + if got != nil { + t.Errorf("got %v, want nil", got) + } + + _, err = doc.GetField("c") + if gcerrors.Code(err) != gcerrors.NotFound { + t.Fatalf("got %v, want NotFound", err) + } + }) + } +} + +func TestFieldNames(t *testing.T) { + type E struct { + C int + } + type S struct { + A int `docstore:"a"` + B int + E + } + + for _, test := range []struct { + in interface{} + want []string + }{ + { + map[string]interface{}{"a": 1, "b": map[string]interface{}{"c": 2}}, + []string{"a", "b"}, + }, + { + &S{}, + []string{"B", "C", "a"}, + }, + } { + doc, err := NewDocument(test.in) + if err != nil { + t.Fatal(err) + } + got := doc.FieldNames() + sort.Strings(got) + if !cmp.Equal(got, test.want) { + t.Errorf("%v: got %v, want %v", test.in, got, test.want) + } + } +} + +func TestHasField(t *testing.T) { + type withRev struct { + Rev interface{} + } + type withoutRev struct { + W withRev + } + + for _, tc := range []struct { + in interface{} + want bool + }{ + { + in: &withRev{}, + want: true, + }, + { + in: &withoutRev{}, + want: false, + }, + { + in: map[string]interface{}{"Rev": nil}, + want: true, + }, + { + in: map[string]interface{}{}, + want: false, + }, + } { + doc, err := NewDocument(tc.in) + if err != nil { + t.Fatal(err) + } + on := doc.HasField("Rev") + if on != tc.want { + t.Errorf("%v: got %v want %v", tc.in, on, tc.want) + } + } +} + +func TestHasFieldFold(t *testing.T) { + type withRev struct { + Rev interface{} + } + type withoutRev struct { + W withRev + } + + for _, tc := range []struct { + in interface{} + want bool + }{ + { + in: &withRev{}, + want: true, + }, + { + in: &withoutRev{}, + want: false, + }, + } { + doc, err := NewDocument(tc.in) + if err != nil { + t.Fatal(err) + } + for _, f := range []string{"Rev", "rev", "REV"} { + on := doc.HasFieldFold(f) + if on != tc.want { + t.Errorf("%v: got %v want %v", tc.in, on, tc.want) + } + } + } +} diff --git a/go-cloud/docstore/driver/driver.go b/go-cloud/docstore/driver/driver.go new file mode 100644 index 000000000..0296033ae --- /dev/null +++ b/go-cloud/docstore/driver/driver.go @@ -0,0 +1,245 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 driver defines interfaces to be implemented by docstore drivers, which +// will be used by the docstore package to interact with the underlying services. +// Application code should use package docstore. +package driver // import "gocloud.dev/docstore/driver" + +import ( + "context" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +// A Collection is a set of documents. +type Collection interface { + // Key returns the document key, or nil if the document doesn't have one, which + // means it is absent or zero value, such as 0, a nil interface value, and any + // empty array or string. + // + // If the collection is able to generate a key for a Create action, then + // it should not return an error if the key is missing. If the collection + // can't generate a missing key, it should return an error. + // + // The returned key must be comparable. + // + // The returned key should not be encoded with the driver's codec; it should + // be the user-supplied Go value. + Key(Document) (interface{}, error) + + // RevisionField returns the name of the field used to hold revisions. + // If the empty string is returned, docstore.DefaultRevisionField will be used. + RevisionField() string + + // RunActions executes a slice of actions. + // + // If unordered is false, it must appear as if the actions were executed in the + // order they appear in the slice, from the client's point of view. The actions + // need not happen atomically, nor does eventual consistency in the service + // need to be taken into account. For example, after a write returns + // successfully, the driver can immediately perform a read on the same document, + // even though the service's semantics does not guarantee that the read will see + // the write. RunActions should return immediately after the first action that fails. + // The returned slice should have a single element. + // + // opts controls the behavior of RunActions and is guaranteed to be non-nil. + RunActions(ctx context.Context, actions []*Action, opts *RunActionsOptions) ActionListError + + // RunGetQuery executes a Query. + // + // Implementations can choose to execute the Query as one single request or + // multiple ones, depending on their service offerings. The portable type + // exposes OpenTelemetry metrics for the call to RunGetQuery (but not for + // subsequent calls to DocumentIterator.Next), so drivers should prefer to + // make at least one RPC during RunGetQuery itself instead of lazily waiting + // for the first call to Next. + RunGetQuery(context.Context, *Query) (DocumentIterator, error) + + // QueryPlan returns the plan for the query. + QueryPlan(*Query) (string, error) + + // RevisionToBytes converts a revision to a byte slice. + RevisionToBytes(interface{}) ([]byte, error) + + // BytesToRevision converts a []byte to a revision. + BytesToRevision([]byte) (interface{}, error) + + // As converts i to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + As(i interface{}) bool + + // ErrorAs allows drivers to expose driver-specific types for returned + // errors. + // + // See https://gocloud.dev/concepts/as/ for background information. + ErrorAs(err error, i interface{}) bool + + // ErrorCode should return a code that describes the error, which was returned by + // one of the other methods in this interface. + ErrorCode(error) gcerrors.ErrorCode + + // Close cleans up any resources used by the Collection. Once Close is called, + // there will be no method calls to the Collection other than As, ErrorAs, and + // ErrorCode. + Close() error +} + +// DeleteQueryer should be implemented by Collections that can handle Query.Delete +// efficiently. If a Collection does not implement this interface, then Query.Delete +// will be implemented by calling RunGetQuery and deleting the returned documents. +type DeleteQueryer interface { + RunDeleteQuery(context.Context, *Query) error +} + +// UpdateQueryer should be implemented by Collections that can handle Query.Update +// efficiently. If a Collection does not implement this interface, then Query.Update +// will be implemented by calling RunGetQuery and updating the returned documents. +type UpdateQueryer interface { + RunUpdateQuery(context.Context, *Query, []Mod) error +} + +// ActionKind describes the type of an action. +type ActionKind int + +// Values for ActionKind. +const ( + Create ActionKind = iota + Replace + Put + Get + Delete + Update +) + +//go:generate stringer -type=ActionKind + +type Action struct { + Kind ActionKind // the kind of action + Doc Document // the document on which to perform the action + Key interface{} // the document key returned by Collection.Key, to avoid recomputing it + FieldPaths [][]string // field paths to retrieve, for Get only + Mods []Mod // modifications to make, for Update only + Index int // the index of the action in the original action list + InAtomicWrite bool // if this action is a part of transaction +} + +// A Mod is a modification to a field path in a document. +// At present, the only modifications supported are: +// - set the value at the field path, or create the field path if it doesn't exist +// - delete the field path (when Value is nil) +type Mod struct { + FieldPath []string + Value interface{} +} + +// IncOp is a value representing an increment modification. +type IncOp struct { + Amount interface{} +} + +// An ActionListError contains all the errors encountered from a call to RunActions, +// and the positions of the corresponding actions. +type ActionListError []struct { + Index int + Err error +} + +// NewActionListError creates an ActionListError from a slice of errors. +// If the ith element err of the slice is non-nil, the resulting ActionListError +// will have an item {i, err}. +func NewActionListError(errs []error) ActionListError { + var alerr ActionListError + for i, err := range errs { + if err != nil { + alerr = append(alerr, struct { + Index int + Err error + }{i, err}) + } + } + return alerr +} + +// RunActionsOptions controls the behavior of RunActions. +type RunActionsOptions struct { + // BeforeDo is a callback that must be called once, sequentially, before each one + // or group of the underlying service's actions is executed. asFunc allows + // drivers to expose driver-specific types. + BeforeDo func(asFunc func(interface{}) bool) error +} + +// A Query defines a query operation to find documents within a collection based +// on a set of requirements. +type Query struct { + // FieldPaths contain a list of field paths the user selects to return in the + // query results. The returned documents should only have these fields + // populated. + FieldPaths [][]string + + // Filters contain a list of filters for the query. If there are more than one + // filter, they should be combined with AND. + Filters []Filter + + // Offset (also commonly referred to as `Skip`) sets the number of results to skip + // before returning results. When Offset <= 0, the driver implementation should + // return all possible results. + Offset int + + // Limit sets the maximum number of results returned by running the query. When + // Limit <= 0, the driver implementation should return all possible results. + Limit int + + // OrderByField is the field to use for sorting the results. + OrderByField string + + // OrderAscending specifies the sort direction. + OrderAscending bool + + // BeforeQuery is a callback that must be called exactly once before the + // underlying service's query is executed. asFunc allows drivers to expose + // driver-specific types. + BeforeQuery func(asFunc func(interface{}) bool) error +} + +// A Filter defines a filter expression used to filter the query result. +// If the value is a number type, the filter uses numeric comparison. +// If the value is a string type, the filter uses UTF-8 string comparison. +// TODO(#1762): support comparison of other types. +type Filter struct { + FieldPath []string // the field path to filter + Op string // the operation, supports `=`, `>`, `>=`, `<`, `<=`, `in`, `not-in` + Value interface{} // the value to compare using the operation +} + +// A DocumentIterator iterates through the results (for Get action). +type DocumentIterator interface { + // Next tries to get the next item in the query result and decodes into Document + // with the driver's codec. + // When there are no more results, it should return io.EOF. + // Once Next returns a non-nil error, it will never be called again. + Next(context.Context, Document) error + + // Stop terminates the iterator before Next return io.EOF, allowing any cleanup + // needed. + Stop() + + // As converts i to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + As(i interface{}) bool +} + +// EqualOp is the name of the equality operator. +// It is defined here to avoid confusion between "=" and "==". +const EqualOp = "=" diff --git a/go-cloud/docstore/driver/util.go b/go-cloud/docstore/driver/util.go new file mode 100644 index 000000000..fec420a14 --- /dev/null +++ b/go-cloud/docstore/driver/util.go @@ -0,0 +1,223 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 driver + +import ( + "reflect" + "sort" + "sync" + + "github.com/google/uuid" +) + +// UniqueString generates a string that is unique with high probability. +// Driver implementations can use it to generate keys for Create actions. +func UniqueString() string { return uuid.New().String() } + +// SplitActions divides the actions slice into sub-slices much like strings.Split. +// The split function should report whether two consecutive actions should be split, +// that is, should be in different sub-slices. The first argument to split is the +// last action of the sub-slice currently under construction; the second argument is +// the action being considered for addition to that sub-slice. +// SplitActions doesn't change the order of the input slice. +func SplitActions(actions []*Action, split func(a, b *Action) bool) [][]*Action { + var ( + groups [][]*Action // the actions, split; the return value + cur []*Action // the group currently being constructed + ) + collect := func() { // called when the current group is known to be finished + if len(cur) > 0 { + groups = append(groups, cur) + cur = nil + } + } + for _, a := range actions { + if len(cur) > 0 && split(cur[len(cur)-1], a) { + collect() + } + cur = append(cur, a) + } + collect() + return groups +} + +// GroupActions separates actions into four sets: writes, gets that must happen before the writes, +// gets that must happen after the writes, and gets that can happen concurrently with the writes. +func GroupActions(actions []*Action) (beforeGets, getList, writeList, writesTxList, afterGets []*Action) { + // maps from key to action + bgets := map[interface{}]*Action{} + agets := map[interface{}]*Action{} + cgets := map[interface{}]*Action{} + writes := map[interface{}]*Action{} + writesTx := map[interface{}]*Action{} + var nilkeys []*Action + for _, a := range actions { + if a.Key == nil { + // Probably a Create. + nilkeys = append(nilkeys, a) + } else if a.Kind == Get { + // If there was a prior write with this key, make sure this get + // happens after the writes. + if _, ok := writes[a.Key]; ok { + agets[a.Key] = a + } else if _, ok := writesTx[a.Key]; ok { + agets[a.Key] = a + } else { + cgets[a.Key] = a + } + } else { + // This is a write. A prior get on the same key was put into cgets; move + // it to bgets because it has to happen before writes. + if g, ok := cgets[a.Key]; ok { + delete(cgets, a.Key) + bgets[a.Key] = g + } + if a.InAtomicWrite { + writesTx[a.Key] = a + } else { + writes[a.Key] = a + } + } + } + + vals := func(m map[interface{}]*Action) []*Action { + var as []*Action + for _, v := range m { + as = append(as, v) + } + // Sort so the order is always the same for replay. + sort.Slice(as, func(i, j int) bool { return as[i].Index < as[j].Index }) + return as + } + + return vals(bgets), vals(cgets), append(vals(writes), nilkeys...), vals(writesTx), vals(agets) +} + +// AsFunc creates and returns an "as function" that behaves as follows: +// If its argument is a pointer to the same type as val, the argument is set to val +// and the function returns true. Otherwise, the function returns false. +func AsFunc(val interface{}) func(interface{}) bool { + rval := reflect.ValueOf(val) + wantType := reflect.PtrTo(rval.Type()) + return func(i interface{}) bool { + if i == nil { + return false + } + ri := reflect.ValueOf(i) + if ri.Type() != wantType { + return false + } + ri.Elem().Set(rval) + return true + } +} + +// GroupByFieldPath collect the Get actions into groups with the same set of +// field paths. +func GroupByFieldPath(gets []*Action) [][]*Action { + // This is quadratic in the worst case, but it's unlikely that there would be + // many Gets with different field paths. + var groups [][]*Action + seen := map[*Action]bool{} + for len(seen) < len(gets) { + var g []*Action + for _, a := range gets { + if !seen[a] { + if len(g) == 0 || fpsEqual(g[0].FieldPaths, a.FieldPaths) { + g = append(g, a) + seen[a] = true + } + } + } + groups = append(groups, g) + } + return groups +} + +// Report whether two lists of field paths are equal. +func fpsEqual(fps1, fps2 [][]string) bool { + // TODO?: We really care about sets of field paths, but that's too tedious to determine. + if len(fps1) != len(fps2) { + return false + } + for i, fp1 := range fps1 { + if !FieldPathsEqual(fp1, fps2[i]) { + return false + } + } + return true +} + +// FieldPathsEqual reports whether two field paths are equal. +func FieldPathsEqual(fp1, fp2 []string) bool { + if len(fp1) != len(fp2) { + return false + } + for i, s1 := range fp1 { + if s1 != fp2[i] { + return false + } + } + return true +} + +// FieldPathEqualsField reports whether a field path equals a field. +// This is a convenience for FieldPathsEqual(fp, []string{s}). +func FieldPathEqualsField(fp []string, s string) bool { + return len(fp) == 1 && fp[0] == s +} + +// Throttle is used to limit the number of outstanding activities, like RPCs. +// It acts like a combination of a semaphore and a WaitGroup. +type Throttle struct { + c chan struct{} // token semaphore + wg sync.WaitGroup +} + +// NewThrottle returns a Throttle that will allow max calls to Acquire that +// are not matched with Release calls before blocking. +// If max is <= 0, there is no throttling: Acquire always returns immediately. +func NewThrottle(max int) *Throttle { + t := &Throttle{} + if max > 0 { + t.c = make(chan struct{}, max) + } + return t +} + +// Acquire blocks until a token is available, then acquires it and returns. +// Acquire is deliberately not sensitive to context.Context, because it assumes +// that whatever acquires a token will be context-sensitive, and thus will release +// the token when the context is done. +func (t *Throttle) Acquire() { + t.wg.Add(1) + if t.c != nil { + t.c <- struct{}{} + } +} + +// Release releases a token obtained by Acquire. +func (t *Throttle) Release() { + if t.c != nil { + <-t.c + } + t.wg.Done() +} + +// Wait blocks goroutine until the number of calls to Release matches the number of +// calls to Acquire. +func (t *Throttle) Wait() { + t.wg.Wait() +} diff --git a/go-cloud/docstore/driver/util_test.go b/go-cloud/docstore/driver/util_test.go new file mode 100644 index 000000000..e465e46c1 --- /dev/null +++ b/go-cloud/docstore/driver/util_test.go @@ -0,0 +1,211 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 driver + +import ( + "fmt" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" +) + +func TestSplitActions(t *testing.T) { + in := []*Action{ + {Kind: Get}, + {Kind: Get}, + {Kind: Put}, + {Kind: Update}, + {Kind: Get}, + {Kind: Create}, + } + + for _, test := range []struct { + desc string + split func(a, b *Action) bool + want [][]*Action + }{ + { + "always false", + func(a, b *Action) bool { return false }, + [][]*Action{in}, + }, + { + "always true", + func(a, b *Action) bool { return true }, + [][]*Action{ + {{Kind: Get}}, + {{Kind: Get}}, + {{Kind: Put}}, + {{Kind: Update}}, + {{Kind: Get}}, + {{Kind: Create}}, + }, + }, + { + "Get vs. other", + func(a, b *Action) bool { return (a.Kind == Get) != (b.Kind == Get) }, + [][]*Action{ + {{Kind: Get}, {Kind: Get}}, + {{Kind: Put}, {Kind: Update}}, + {{Kind: Get}}, + {{Kind: Create}}, + }, + }, + } { + got := SplitActions(in, test.split) + if diff := cmp.Diff(got, test.want, cmpopts.IgnoreFields(Action{}, "Doc")); diff != "" { + t.Errorf("%s: %s", test.desc, diff) + } + } +} + +func TestGroupActions(t *testing.T) { + for _, test := range []struct { + in []*Action + want [][]int // in the same order as the return args + }{ + { + in: []*Action{{Kind: Get, Key: 1}}, + want: [][]int{nil, {0}, nil, nil, nil}, + }, + { + in: []*Action{ + {Kind: Get, Key: 1}, + {Kind: Get, Key: 3}, + {Kind: Put, Key: 1}, + {Kind: Replace, Key: 2}, + {Kind: Get, Key: 2}, + }, + want: [][]int{{0}, {1}, {2, 3}, nil, {4}}, + }, + { + in: []*Action{{Kind: Create}, {Kind: Create}, {Kind: Create}}, + want: [][]int{nil, nil, {0, 1, 2}, nil, nil}, + }, + { + in: []*Action{ + {Kind: Get, Key: 1}, + {Kind: Get, Key: 3}, + {Kind: Put, Key: 1, InAtomicWrite: true}, + {Kind: Replace, Key: 2, InAtomicWrite: true}, + {Kind: Get, Key: 2}, + }, + want: [][]int{{0}, {1}, nil, {2, 3}, {4}}, + }, + { + in: []*Action{ + {Kind: Get, Key: 1}, + {Kind: Get, Key: 3}, + {Kind: Put, Key: 1, InAtomicWrite: true}, + {Kind: Replace, Key: 2}, + {Kind: Put, Key: 2, InAtomicWrite: true}, + {Kind: Get, Key: 2}, + }, + want: [][]int{{0}, {1}, {3}, {2, 4}, {5}}, + }, + { + in: []*Action{ + {Kind: Get, Key: 1}, + {Kind: Get, Key: 3}, + {Kind: Put, Key: 1, InAtomicWrite: true}, + {Kind: Replace, Key: 2, InAtomicWrite: true}, + {Kind: Put, Key: 2, InAtomicWrite: true}, + {Kind: Get, Key: 2}, + }, + want: [][]int{{0}, {1}, nil, {2, 4}, {5}}, + }, + } { + got := make([][]*Action, 5) + got[0], got[1], got[2], got[3], got[4] = GroupActions(test.in) + want := make([][]*Action, 5) + for i, s := range test.want { + for _, x := range s { + want[i] = append(want[i], test.in[x]) + } + } + diff := cmp.Diff(got, want, + cmpopts.IgnoreUnexported(Document{}), + cmpopts.SortSlices(func(a1, a2 *Action) bool { + if a1.Kind != a2.Kind { + return a1.Kind < a2.Kind + } + a1k, _ := a1.Key.(int) + a2k, _ := a2.Key.(int) + return a1k < a2k + })) + if diff != "" { + t.Errorf("%v: %s", test.in, diff) + } + } +} + +func (a *Action) String() string { // for TestGroupActions + return fmt.Sprintf("<%s %v>", a.Kind, a.Key) +} + +func TestAsFunc(t *testing.T) { + x := 1 + as := AsFunc(x) + + var y int + if !as(&y) || y != 1 { + t.Errorf("*int: returned false or wrong value %d", y) + } + + var z float64 + for _, arg := range []interface{}{nil, y, &z} { + if as(arg) { + t.Errorf("%#v: got true, want false", arg) + } + } +} + +func TestGroupByFieldPath(t *testing.T) { + for i, test := range []struct { + in []*Action + want [][]int // indexes into test.in + }{ + { + in: []*Action{{Index: 0}, {Index: 1}, {Index: 2}}, + want: [][]int{{0, 1, 2}}, + }, + { + in: []*Action{{Index: 0}, {Index: 1, FieldPaths: [][]string{{"a"}}}, {Index: 2}}, + want: [][]int{{0, 2}, {1}}, + }, + { + in: []*Action{ + {Index: 0, FieldPaths: [][]string{{"a", "b"}}}, + {Index: 1, FieldPaths: [][]string{{"a"}}}, + {Index: 2}, + {Index: 3, FieldPaths: [][]string{{"a"}, {"b"}}}, + }, + want: [][]int{{0}, {1}, {2}, {3}}, + }, + } { + got := GroupByFieldPath(test.in) + want := make([][]*Action, len(test.want)) + for i, s := range test.want { + want[i] = make([]*Action, len(s)) + for j, x := range s { + want[i][j] = test.in[x] + } + } + if diff := cmp.Diff(got, want, cmpopts.IgnoreUnexported(Document{})); diff != "" { + t.Errorf("#%d: %s", i, diff) + } + } +} diff --git a/go-cloud/docstore/drivertest/driverbenchmark.go b/go-cloud/docstore/drivertest/driverbenchmark.go new file mode 100644 index 000000000..558699a91 --- /dev/null +++ b/go-cloud/docstore/drivertest/driverbenchmark.go @@ -0,0 +1,148 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 drivertest + +import ( + "context" + "fmt" + "strconv" + "sync/atomic" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/docstore" +) + +// RunBenchmarks runs benchmarks for docstore drivers. +func RunBenchmarks(b *testing.B, coll *docstore.Collection) { + b.Helper() + + defer coll.Close() + ClearCollection(b, coll) + b.Run("BenchmarkSingleActionPut", func(b *testing.B) { + benchmarkSingleActionPut(b, 10, coll) + }) + b.Run("BenchmarkSingleActionGet", func(b *testing.B) { + benchmarkSingleActionGet(b, 10, coll) + }) + b.Run("BenchmarkActionListPut", func(b *testing.B) { + benchmarkActionListPut(b, 50, coll) + }) + b.Run("BenchmarkActionListGet", func(b *testing.B) { + benchmarkActionListGet(b, 100, coll) + }) + ClearCollection(b, coll) +} + +func benchmarkSingleActionPut(b *testing.B, n int, coll *docstore.Collection) { + b.Helper() + + ctx := context.Background() + const baseKey = "benchmarksingleaction-put-" + var nextID uint32 + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + for i := 0; i < n; i++ { + key := fmt.Sprintf("%s%d", baseKey, atomic.AddUint32(&nextID, 1)) + doc := docmap{KeyField: key, "S": key} + if err := coll.Put(ctx, doc); err != nil { + b.Error(err) + } + } + } + }) +} + +func benchmarkSingleActionGet(b *testing.B, n int, coll *docstore.Collection) { + b.Helper() + + ctx := context.Background() + const baseKey = "benchmarksingleaction-get-" + docs := make([]docmap, n) + puts := coll.Actions() + for i := 0; i < n; i++ { + docs[i] = docmap{KeyField: baseKey + strconv.Itoa(i), "n": i} + puts.Put(docs[i]) + } + if err := puts.Do(ctx); err != nil { + b.Fatal(err) + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + for _, doc := range docs { + got := docmap{KeyField: doc[KeyField]} + if err := coll.Get(ctx, got); err != nil { + b.Fatal(err) + } + } + } + }) +} + +func benchmarkActionListPut(b *testing.B, n int, coll *docstore.Collection) { + b.Helper() + + ctx := context.Background() + const baseKey = "benchmarkactionlist-put-" + var nextID uint32 + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + actions := coll.Actions() + for i := 0; i < n; i++ { + key := fmt.Sprintf("%s%d", baseKey, atomic.AddUint32(&nextID, 1)) + doc := docmap{KeyField: key, "S": key} + actions.Put(doc) + } + if err := actions.Do(ctx); err != nil { + b.Error(err) + } + } + }) +} + +func benchmarkActionListGet(b *testing.B, n int, coll *docstore.Collection) { + b.Helper() + + ctx := context.Background() + const baseKey = "benchmarkactionlist-get-" + docs := make([]docmap, n) + puts := coll.Actions() + for i := 0; i < n; i++ { + docs[i] = docmap{KeyField: baseKey + strconv.Itoa(i), "n": i} + puts.Put(docs[i]) + } + if err := puts.Do(ctx); err != nil { + b.Fatal(err) + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + gets := coll.Actions() + for _, doc := range docs { + got := docmap{KeyField: doc[KeyField]} + gets.Get(got) + } + if err := gets.Do(ctx); err != nil { + b.Fatal(err) + } + } + }) +} diff --git a/go-cloud/docstore/drivertest/drivertest.go b/go-cloud/docstore/drivertest/drivertest.go new file mode 100644 index 000000000..91a950dd1 --- /dev/null +++ b/go-cloud/docstore/drivertest/drivertest.go @@ -0,0 +1,2347 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 drivertest provides a conformance test for implementations of +// driver. +package drivertest // import "gocloud.dev/docstore/drivertest" + +import ( + "context" + "errors" + "fmt" + "io" + "math" + "reflect" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "google.golang.org/protobuf/proto" + tspb "google.golang.org/protobuf/types/known/timestamppb" +) + +// ByteArray is an array of 2 bytes. +type ByteArray [2]byte + +// CollectionKind describes the kind of testing collection to create. +type CollectionKind int + +const ( + // SingleKey is collection with a single primary key field of type string named + // drivertest.KeyField. + SingleKey CollectionKind = iota + + // TwoKey is a collection that will consist entirely of HighScore structs (see below), + // whose two primary key fields are "Game" and "Player", both strings. Use + // drivertest.HighScoreKey as the key function. + TwoKey + + // AltRev is a collection that behaves like a SingleKey collection, except + // that the revision field should be drivertest.AlternateRevisionField. + AltRev + + // NoRev is a collection whose documents will not have a revision field. + NoRev +) + +// Harness descibes the functionality test harnesses must provide to run +// conformance tests. +type Harness interface { + // MakeCollection makes a driver.Collection for testing. + MakeCollection(context.Context, CollectionKind) (driver.Collection, error) + + // BeforeDoTypes should return a list of values whose types are valid for the as + // function given to BeforeDo. For example, if the driver converts Get actions + // to *GetRequests and write actions to *WriteRequests, then BeforeDoTypes should + // return []interface{}{&GetRequest{}, &WriteRequest{}}. + // TODO(jba): consider splitting these by action kind. + BeforeDoTypes() []interface{} + + // BeforeQueryTypes should return a list of values whose types are valid for the as + // function given to BeforeQuery. + BeforeQueryTypes() []interface{} + + // RevisionsEqual reports whether two revisions are equal. + RevisionsEqual(rev1, rev2 interface{}) bool + + // SupportsAtomicWrites should report if a collection supports atomic writes + SupportsAtomicWrites() bool + + // Close closes resources used by the harness. + Close() +} + +// HarnessMaker describes functions that construct a harness for running tests. +// It is called exactly once per test; Harness.Close() will be called when the test is complete. +type HarnessMaker func(ctx context.Context, t *testing.T) (Harness, error) + +// UnsupportedType is an enum for types not supported by native codecs. We chose +// to describe this negatively (types that aren't supported rather than types +// that are) to make the more inclusive cases easier to write. A driver can +// return nil for CodecTester.UnsupportedTypes, then add values from this enum +// one by one until all tests pass. +type UnsupportedType int + +// These are known unsupported types by one or more driver. Each of them +// corresponses to an unsupported type specific test which if the driver +// actually supports. +const ( + // Native codec doesn't support any unsigned integer type + Uint UnsupportedType = iota + // Native codec doesn't support arrays + Arrays + // Native codec doesn't support full time precision + NanosecondTimes + // Native codec doesn't support [][]byte + BinarySet +) + +// CodecTester describes functions that encode and decode values using both the +// docstore codec for a driver, and that driver's own "native" codec. +type CodecTester interface { + UnsupportedTypes() []UnsupportedType + NativeEncode(interface{}) (interface{}, error) + NativeDecode(value, dest interface{}) error + DocstoreEncode(interface{}) (interface{}, error) + DocstoreDecode(value, dest interface{}) error +} + +// AsTest represents a test of As functionality. +type AsTest interface { + // Name should return a descriptive name for the test. + Name() string + // CollectionCheck will be called to allow verification of Collection.As. + CollectionCheck(coll *docstore.Collection) error + // QueryCheck will be called after calling Query. It should call it.As and + // verify the results. + QueryCheck(it *docstore.DocumentIterator) error + // ErrorCheck is called to allow verification of Collection.ErrorAs. + ErrorCheck(c *docstore.Collection, err error) error +} + +type verifyAsFailsOnNil struct{} + +func (verifyAsFailsOnNil) Name() string { + return "verify As returns false when passed nil" +} + +func (verifyAsFailsOnNil) CollectionCheck(coll *docstore.Collection) error { + if coll.As(nil) { + return errors.New("want Collection.As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) QueryCheck(it *docstore.DocumentIterator) error { + if it.As(nil) { + return errors.New("want DocumentIterator.As to return false when passed nil") + } + return nil +} + +func (v verifyAsFailsOnNil) ErrorCheck(c *docstore.Collection, err error) (ret error) { + defer func() { + if recover() == nil { + ret = errors.New("want ErrorAs to panic when passed nil") + } + }() + c.ErrorAs(err, nil) + return nil +} + +// RunConformanceTests runs conformance tests for driver implementations of docstore. +func RunConformanceTests(t *testing.T, newHarness HarnessMaker, ct CodecTester, asTests []AsTest) { + t.Helper() + + t.Run("TypeDrivenCodec", func(t *testing.T) { testTypeDrivenDecode(t, ct) }) + t.Run("BlindCodec", func(t *testing.T) { testBlindDecode(t, ct) }) + + t.Run("Create", func(t *testing.T) { withRevCollections(t, newHarness, testCreate) }) + t.Run("AtomicWrites", func(t *testing.T) { withRevCollections(t, newHarness, testAtomicWrites) }) + t.Run("AtomicWritesFail", func(t *testing.T) { withRevCollections(t, newHarness, testAtomicWritesFail) }) + t.Run("Put", func(t *testing.T) { withRevCollections(t, newHarness, testPut) }) + t.Run("Replace", func(t *testing.T) { withRevCollections(t, newHarness, testReplace) }) + t.Run("Get", func(t *testing.T) { withRevCollections(t, newHarness, testGet) }) + t.Run("Delete", func(t *testing.T) { withRevCollections(t, newHarness, testDelete) }) + t.Run("Update", func(t *testing.T) { withRevCollections(t, newHarness, testUpdate) }) + t.Run("Data", func(t *testing.T) { withCollection(t, newHarness, SingleKey, testData) }) + t.Run("Proto", func(t *testing.T) { withCollection(t, newHarness, SingleKey, testProto) }) + t.Run("MultipleActions", func(t *testing.T) { withRevCollections(t, newHarness, testMultipleActions) }) + t.Run("GetQueryKeyField", func(t *testing.T) { withRevCollections(t, newHarness, testGetQueryKeyField) }) + t.Run("SerializeRevision", func(t *testing.T) { withCollection(t, newHarness, SingleKey, testSerializeRevision) }) + t.Run("ActionsOnStructNoRev", func(t *testing.T) { + withCollection(t, newHarness, NoRev, testActionsOnStructNoRev) + }) + t.Run("ActionsWithCompositeID", func(t *testing.T) { withCollection(t, newHarness, TwoKey, testActionsWithCompositeID) }) + t.Run("GetQuery", func(t *testing.T) { withCollection(t, newHarness, TwoKey, testGetQuery) }) + + t.Run("ExampleInDoc", func(t *testing.T) { withCollection(t, newHarness, NoRev, testExampleInDoc) }) + + t.Run("BeforeDo", func(t *testing.T) { testBeforeDo(t, newHarness) }) + t.Run("BeforeQuery", func(t *testing.T) { testBeforeQuery(t, newHarness) }) + + asTests = append(asTests, verifyAsFailsOnNil{}) + t.Run("As", func(t *testing.T) { + for _, st := range asTests { + if st.Name() == "" { + t.Fatalf("AsTest.Name is required") + } + t.Run(st.Name(), func(t *testing.T) { + withCollection(t, newHarness, TwoKey, func(t *testing.T, _ Harness, coll *docstore.Collection) { + t.Helper() + + testAs(t, coll, st) + }) + }) + } + }) +} + +// withCollection calls f with a fresh harness and an empty collection of the given kind. +func withCollection(t *testing.T, newHarness HarnessMaker, kind CollectionKind, f func(*testing.T, Harness, *docstore.Collection)) { + t.Helper() + + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + withColl(t, h, kind, f) +} + +// withRevCollections calls f twice: once with the SingleKey collection, using documents and code that expect +// the standard revision field; and once with the AltRev collection, that uses an alternative revisionf field +// name. +func withRevCollections(t *testing.T, newHarness HarnessMaker, f func(*testing.T, *docstore.Collection, string)) { + t.Helper() + + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + if strings.Contains(t.Name(), "AtomicWrites") && !h.SupportsAtomicWrites() { + t.Skip() + } + + t.Run("StdRev", func(t *testing.T) { + withColl(t, h, SingleKey, func(t *testing.T, _ Harness, coll *docstore.Collection) { + t.Helper() + + f(t, coll, docstore.DefaultRevisionField) + }) + }) + t.Run("AltRev", func(t *testing.T) { + withColl(t, h, AltRev, func(t *testing.T, _ Harness, coll *docstore.Collection) { + t.Helper() + + f(t, coll, AlternateRevisionField) + }) + }) +} + +// withColl calls f with h and an empty collection of the given kind. It takes care of closing +// the collection after f returns. +func withColl(t *testing.T, h Harness, kind CollectionKind, f func(*testing.T, Harness, *docstore.Collection)) { + t.Helper() + + ctx := context.Background() + dc, err := h.MakeCollection(ctx, kind) + if err != nil { + t.Fatal(err) + } + coll := docstore.NewCollection(dc) + defer coll.Close() + ClearCollection(t, coll) + f(t, h, coll) +} + +// KeyField is the primary key field for the main test collection. +const KeyField = "name" + +// AlternateRevisionField is used for testing the option to provide a different +// name for the revision field. +const AlternateRevisionField = "Etag" + +type docmap = map[string]interface{} + +func newDoc(doc interface{}) interface{} { + switch v := doc.(type) { + case docmap: + return docmap{KeyField: v[KeyField]} + case *docstruct: + return &docstruct{Name: v.Name} + } + return nil +} + +func key(doc interface{}) interface{} { + switch d := doc.(type) { + case docmap: + return d[KeyField] + case *docstruct: + return d.Name + } + return nil +} + +func setKey(doc, key interface{}) { + switch d := doc.(type) { + case docmap: + d[KeyField] = key + case *docstruct: + d.Name = key + } +} + +func revision(doc interface{}, revField string) interface{} { + switch d := doc.(type) { + case docmap: + return d[revField] + case *docstruct: + if revField == docstore.DefaultRevisionField { + return d.DocstoreRevision + } + return d.Etag + } + return nil +} + +func setRevision(doc, rev interface{}, revField string) { + switch d := doc.(type) { + case docmap: + d[revField] = rev + case *docstruct: + if revField == docstore.DefaultRevisionField { + d.DocstoreRevision = rev + } else { + d.Etag = rev + } + } +} + +type docstruct struct { + Name interface{} `docstore:"name"` + DocstoreRevision interface{} + Etag interface{} + + I int + U uint + F float64 + St string + B bool + M map[string]interface{} +} + +func nonexistentDoc() docmap { return docmap{KeyField: "doesNotExist"} } + +func testCreate(t *testing.T, coll *docstore.Collection, revField string) { + t.Helper() + + ctx := context.Background() + for _, tc := range []struct { + name string + doc interface{} + wantErr gcerrors.ErrorCode + }{ + { + name: "named map", + doc: docmap{KeyField: "testCreateMap", "b": true, revField: nil}, + }, + { + name: "existing", + doc: docmap{KeyField: "testCreateMap", revField: nil}, + wantErr: gcerrors.AlreadyExists, + }, + { + name: "unnamed map", + doc: docmap{"b": true, revField: nil}, + }, + { + name: "named struct", + doc: &docstruct{Name: "testCreateStruct", B: true}, + }, + { + name: "unnamed struct", + doc: &docstruct{B: true}, + }, + { + name: "empty named struct", + doc: &docstruct{Name: "", B: true}, + }, + { + name: "with non-nil revision", + doc: docmap{KeyField: "testCreate2", revField: 0}, + wantErr: gcerrors.InvalidArgument, + }, + } { + t.Run(tc.name, func(t *testing.T) { + if tc.wantErr == gcerrors.OK { + checkNoRevisionField(t, tc.doc, revField) + if err := coll.Create(ctx, tc.doc); err != nil { + t.Fatalf("Create: %v", err) + } + checkHasRevisionField(t, tc.doc, revField) + + got := newDoc(tc.doc) + if err := coll.Get(ctx, got); err != nil { + t.Fatalf("Get: %v", err) + } + if diff := cmpDiff(got, tc.doc); diff != "" { + t.Fatal(diff) + } + } else { + err := coll.Create(ctx, tc.doc) + checkCode(t, err, tc.wantErr) + } + }) + } +} + +func testPut(t *testing.T, coll *docstore.Collection, revField string) { + t.Helper() + + ctx := context.Background() + must := func(err error) { + t.Helper() + if err != nil { + t.Fatal(err) + } + } + var maprev, strmap interface{} + + for _, tc := range []struct { + name string + doc interface{} + rev bool + }{ + { + name: "create map", + doc: docmap{KeyField: "testPutMap", "b": true, revField: nil}, + }, + { + name: "create struct", + doc: &docstruct{Name: "testPutStruct", B: true}, + }, + { + name: "replace map", + doc: docmap{KeyField: "testPutMap", "b": false, revField: nil}, + rev: true, + }, + { + name: "replace struct", + doc: &docstruct{Name: "testPutStruct", B: false}, + rev: true, + }, + } { + t.Run(tc.name, func(t *testing.T) { + checkNoRevisionField(t, tc.doc, revField) + must(coll.Put(ctx, tc.doc)) + checkHasRevisionField(t, tc.doc, revField) + got := newDoc(tc.doc) + must(coll.Get(ctx, got)) + if diff := cmpDiff(got, tc.doc); diff != "" { + t.Fatal(diff) + } + if tc.rev { + switch v := tc.doc.(type) { + case docmap: + maprev = v[revField] + case *docstruct: + if revField == docstore.DefaultRevisionField { + strmap = v.DocstoreRevision + } else { + strmap = v.Etag + } + } + } + }) + } + + // Putting a doc with a revision field is the same as replace, meaning + // it will fail if the document doesn't exist. + for _, tc := range []struct { + name string + doc interface{} + }{ + { + name: "replace map wrong key", + doc: docmap{KeyField: "testPutMap2", revField: maprev}, + }, + { + name: "replace struct wrong key", + doc: &docstruct{Name: "testPutStruct2", DocstoreRevision: strmap, Etag: strmap}, + }, + } { + t.Run(tc.name, func(t *testing.T) { + err := coll.Put(ctx, tc.doc) + if c := gcerrors.Code(err); c != gcerrors.NotFound && c != gcerrors.FailedPrecondition { + t.Errorf("got %v, want NotFound or FailedPrecondition", err) + } + }) + } + + t.Run("revision", func(t *testing.T) { + testRevisionField(t, coll, revField, func(doc interface{}) error { + return coll.Put(ctx, doc) + }) + }) + + err := coll.Put(ctx, &docstruct{Name: ""}) + checkCode(t, err, gcerrors.InvalidArgument) +} + +func testReplace(t *testing.T, coll *docstore.Collection, revField string) { + t.Helper() + + ctx := context.Background() + must := func(err error) { + t.Helper() + if err != nil { + t.Fatal(err) + } + } + + for _, tc := range []struct { + name string + doc1, doc2 interface{} + }{ + { + name: "replace map", + doc1: docmap{KeyField: "testReplaceMap", "s": "a", revField: nil}, + doc2: docmap{KeyField: "testReplaceMap", "s": "b", revField: nil}, + }, + { + name: "replace struct", + doc1: &docstruct{Name: "testReplaceStruct", St: "a"}, + doc2: &docstruct{Name: "testReplaceStruct", St: "b"}, + }, + } { + t.Run(tc.name, func(t *testing.T) { + must(coll.Put(ctx, tc.doc1)) + checkNoRevisionField(t, tc.doc2, revField) + must(coll.Replace(ctx, tc.doc2)) + checkHasRevisionField(t, tc.doc2, revField) + got := newDoc(tc.doc2) + must(coll.Get(ctx, got)) + if diff := cmpDiff(got, tc.doc2); diff != "" { + t.Fatal(diff) + } + }) + } + + // Can't replace a nonexistent doc. + checkCode(t, coll.Replace(ctx, nonexistentDoc()), gcerrors.NotFound) + + t.Run("revision", func(t *testing.T) { + testRevisionField(t, coll, revField, func(doc interface{}) error { + return coll.Replace(ctx, doc) + }) + }) +} + +// Check that doc does not have a revision field (or has a nil one). +func checkNoRevisionField(t *testing.T, doc interface{}, revField string) { + t.Helper() + ddoc, err := driver.NewDocument(doc) + if err != nil { + t.Fatal(err) + } + if rev, _ := ddoc.GetField(revField); rev != nil { + t.Fatal("doc has revision field") + } +} + +// Check that doc has a non-nil revision field. +func checkHasRevisionField(t *testing.T, doc interface{}, revField string) { + t.Helper() + + ddoc, err := driver.NewDocument(doc) + if err != nil { + t.Fatal(err) + } + if rev, err := ddoc.GetField(revField); err != nil || rev == nil { + t.Fatalf("doc missing revision field (error = %v)", err) + } +} + +func testGet(t *testing.T, coll *docstore.Collection, revField string) { + t.Helper() + + ctx := context.Background() + must := func(err error) { + t.Helper() + if err != nil { + t.Fatal(err) + } + } + + for _, tc := range []struct { + name string + doc interface{} + fps []docstore.FieldPath + want interface{} + }{ + // If Get is called with no field paths, the full document is populated. + { + name: "get map", + doc: docmap{ + KeyField: "testGetMap", + "s": "a string", + "i": int64(95), + "f": 32.3, + "m": map[string]interface{}{"a": "one", "b": "two"}, + revField: nil, + }, + }, + { + name: "get struct", + doc: &docstruct{ + Name: "testGetStruct", + St: "a string", + I: 95, + F: 32.3, + M: map[string]interface{}{"a": "one", "b": "two"}, + }, + }, + // If Get is called with field paths, the resulting document has only those fields. + { + name: "get map with field path", + doc: docmap{ + KeyField: "testGetMapFP", + "s": "a string", + "i": int64(95), + "f": 32.3, + "m": map[string]interface{}{"a": "one", "b": "two"}, + revField: nil, + }, + fps: []docstore.FieldPath{"f", "m.b", docstore.FieldPath(revField)}, + want: docmap{ + KeyField: "testGetMapFP", + "f": 32.3, + "m": map[string]interface{}{"b": "two"}, + }, + }, + { + name: "get struct with field path", + doc: &docstruct{ + Name: "testGetStructFP", + St: "a string", + I: 95, + F: 32.3, + M: map[string]interface{}{"a": "one", "b": "two"}, + }, + fps: []docstore.FieldPath{"St", "M.a", docstore.FieldPath(revField)}, + want: &docstruct{ + Name: "testGetStructFP", + St: "a string", + M: map[string]interface{}{"a": "one"}, + }, + }, + { + name: "get struct wrong case", + doc: &docstruct{ + Name: "testGetStructWC", + St: "a string", + I: 95, + F: 32.3, + M: map[string]interface{}{"a": "one", "b": "two"}, + }, + fps: []docstore.FieldPath{"st", "m.a"}, + want: &docstruct{ + Name: "testGetStructWC", + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + must(coll.Put(ctx, tc.doc)) + got := newDoc(tc.doc) + must(coll.Get(ctx, got, tc.fps...)) + if tc.want == nil { + tc.want = tc.doc + } + setRevision(tc.want, revision(got, revField), revField) + if diff := cmpDiff(got, tc.want); diff != "" { + t.Error("Get with field paths:\n", diff) + } + }) + } + + err := coll.Get(ctx, nonexistentDoc()) + checkCode(t, err, gcerrors.NotFound) + + err = coll.Get(ctx, &docstruct{Name: ""}) + checkCode(t, err, gcerrors.InvalidArgument) +} + +func testDelete(t *testing.T, coll *docstore.Collection, revField string) { + t.Helper() + + ctx := context.Background() + var rev interface{} + + for _, tc := range []struct { + name string + doc interface{} + wantErr gcerrors.ErrorCode + }{ + { + name: "delete map", + doc: docmap{KeyField: "testDeleteMap", revField: nil}, + }, + { + name: "delete map wrong rev", + doc: docmap{KeyField: "testDeleteMap", "b": true, revField: nil}, + wantErr: gcerrors.FailedPrecondition, + }, + { + name: "delete struct", + doc: &docstruct{Name: "testDeleteStruct"}, + }, + { + name: "delete struct wrong rev", + doc: &docstruct{Name: "testDeleteStruct", B: true}, + wantErr: gcerrors.FailedPrecondition, + }, + } { + t.Run(tc.name, func(t *testing.T) { + if err := coll.Put(ctx, tc.doc); err != nil { + t.Fatal(err) + } + if tc.wantErr == gcerrors.OK { + rev = revision(tc.doc, revField) + if err := coll.Delete(ctx, tc.doc); err != nil { + t.Fatal(err) + } + // The document should no longer exist. + if err := coll.Get(ctx, tc.doc); err == nil { + t.Error("want error, got nil") + } + } else { + setRevision(tc.doc, rev, revField) + checkCode(t, coll.Delete(ctx, tc.doc), gcerrors.FailedPrecondition) + } + }) + } + // Delete doesn't fail if the doc doesn't exist. + if err := coll.Delete(ctx, nonexistentDoc()); err != nil { + t.Errorf("delete nonexistent doc: want nil, got %v", err) + } + + err := coll.Delete(ctx, &docstruct{Name: ""}) + checkCode(t, err, gcerrors.InvalidArgument) +} + +func testUpdate(t *testing.T, coll *docstore.Collection, revField string) { + t.Helper() + + ctx := context.Background() + for _, tc := range []struct { + name string + doc interface{} + mods docstore.Mods + want interface{} + }{ + { + name: "update map", + doc: docmap{KeyField: "testUpdateMap", "a": "A", "b": "B", "n": 3.5, "i": 1, revField: nil}, + mods: docstore.Mods{ + "a": "X", + "b": nil, + "c": "C", + "n": docstore.Increment(-1), + "i": nil, + "m": 3, + }, + want: docmap{KeyField: "testUpdateMap", "a": "X", "c": "C", "n": 2.5, "m": int64(3)}, + }, + { + name: "update map overwrite only", + doc: docmap{KeyField: "testUpdateMapWrt", "a": "A", revField: nil}, + mods: docstore.Mods{ + "a": "X", + "b": nil, + "m": 3, + }, + want: docmap{KeyField: "testUpdateMapWrt", "a": "X", "m": int64(3)}, + }, + { + name: "update map increment only", + doc: docmap{KeyField: "testUpdateMapInc", "a": "A", "n": 3.5, "i": 1, revField: nil}, + mods: docstore.Mods{ + "n": docstore.Increment(-1), + "i": docstore.Increment(2.5), + "m": docstore.Increment(3), + }, + want: docmap{KeyField: "testUpdateMapInc", "a": "A", "n": 2.5, "i": 3.5, "m": int64(3)}, + }, + { + name: "update struct", + doc: &docstruct{Name: "testUpdateStruct", St: "st", I: 1, F: 3.5}, + mods: docstore.Mods{ + "St": "str", + "I": nil, + "U": 4, + "F": docstore.Increment(-3), + }, + want: &docstruct{Name: "testUpdateStruct", St: "str", U: 4, F: 0.5}, + }, + { + name: "update struct overwrite only", + doc: &docstruct{Name: "testUpdateStructWrt", St: "st", I: 1}, + mods: docstore.Mods{ + "St": "str", + "I": nil, + "U": 4, + }, + want: &docstruct{Name: "testUpdateStructWrt", St: "str", U: 4}, + }, + { + name: "update struct increment only", + doc: &docstruct{Name: "testUpdateStructInc", St: "st", I: 1, F: 3.5}, + mods: docstore.Mods{ + "U": docstore.Increment(4), + "F": docstore.Increment(-3), + }, + want: &docstruct{Name: "testUpdateStructInc", St: "st", U: 4, I: 1, F: 0.5}, + }, + } { + t.Run(tc.name, func(t *testing.T) { + if err := coll.Put(ctx, tc.doc); err != nil { + t.Fatal(err) + } + setRevision(tc.doc, nil, revField) + got := newDoc(tc.doc) + checkNoRevisionField(t, tc.doc, revField) + errs := coll.Actions().Update(tc.doc, tc.mods).Get(got).Do(ctx) + if errs != nil { + t.Fatal(errs) + } + checkHasRevisionField(t, tc.doc, revField) + setRevision(tc.want, revision(got, revField), revField) + if diff := cmp.Diff(got, tc.want, cmpopts.IgnoreUnexported(tspb.Timestamp{})); diff != "" { + t.Error(diff) + } + }) + } + + // Can't update a nonexistent doc. + if err := coll.Update(ctx, nonexistentDoc(), docstore.Mods{"x": "y"}); err == nil { + t.Error("nonexistent document: got nil, want error") + } + + // Bad increment value. + err := coll.Update(ctx, docmap{KeyField: "update invalid"}, docstore.Mods{"x": docstore.Increment("3")}) + checkCode(t, err, gcerrors.InvalidArgument) + + t.Run("revision", func(t *testing.T) { + testRevisionField(t, coll, revField, func(doc interface{}) error { + return coll.Update(ctx, doc, docstore.Mods{"s": "c"}) + }) + }) +} + +// Test that: +// - Writing a document with a revision field succeeds if the document hasn't changed. +// - Writing a document with a revision field fails if the document has changed. +func testRevisionField(t *testing.T, coll *docstore.Collection, revField string, write func(interface{}) error) { + t.Helper() + + ctx := context.Background() + must := func(err error) { + t.Helper() + if err != nil { + t.Fatal(err) + } + } + for _, tc := range []struct { + name string + doc interface{} + }{ + { + name: "map revision", + doc: docmap{KeyField: "testRevisionMap", "s": "a", revField: nil}, + }, + { + name: "struct revision", + doc: &docstruct{Name: "testRevisionStruct", St: "a"}, + }, + } { + t.Run(tc.name, func(t *testing.T) { + must(coll.Put(ctx, tc.doc)) + got := newDoc(tc.doc) + must(coll.Get(ctx, got)) + rev := revision(got, revField) + if rev == nil { + t.Fatal("missing revision field") + } + // A write should succeed, because the document hasn't changed since it was gotten. + if err := write(tc.doc); err != nil { + t.Fatalf("write with revision field got %v, want nil", err) + } + // This write should fail: got's revision field hasn't changed, but the stored document has. + err := write(got) + if c := gcerrors.Code(err); c != gcerrors.FailedPrecondition && c != gcerrors.NotFound { + t.Errorf("write with old revision field: got %v, wanted FailedPrecondition or NotFound", err) + } + }) + } +} + +// Verify that the driver can serialize and deserialize revisions. +func testSerializeRevision(t *testing.T, h Harness, coll *docstore.Collection) { + t.Helper() + + ctx := context.Background() + doc := docmap{KeyField: "testSerializeRevision", "x": 1, docstore.DefaultRevisionField: nil} + if err := coll.Create(ctx, doc); err != nil { + t.Fatal(err) + } + want := doc[docstore.DefaultRevisionField] + if want == nil { + t.Fatal("nil revision") + } + s, err := coll.RevisionToString(want) + if err != nil { + t.Fatal(err) + } + got, err := coll.StringToRevision(s) + if err != nil { + t.Fatal(err) + } + if !h.RevisionsEqual(got, want) { + t.Fatalf("got %v, want %v", got, want) + } +} + +// Test all Go integer types are supported, and they all come back as int64. +func testData(t *testing.T, _ Harness, coll *docstore.Collection) { + t.Helper() + + ctx := context.Background() + for _, test := range []struct { + in, want interface{} + }{ + {int(-1), int64(-1)}, + {int8(-8), int64(-8)}, + {int16(-16), int64(-16)}, + {int32(-32), int64(-32)}, + {int64(-64), int64(-64)}, + {uint(1), int64(1)}, + {uint8(8), int64(8)}, + {uint16(16), int64(16)}, + {uint32(32), int64(32)}, + {uint64(64), int64(64)}, + {float32(3.5), float64(3.5)}, + {[]byte{0, 1, 2}, []byte{0, 1, 2}}, + } { + doc := docmap{KeyField: "testData", "val": test.in} + got := docmap{KeyField: doc[KeyField]} + if errs := coll.Actions().Put(doc).Get(got).Do(ctx); errs != nil { + t.Fatal(errs) + } + want := docmap{ + "val": test.want, + KeyField: doc[KeyField], + } + if len(got) != len(want) { + t.Errorf("%v: got %v, want %v", test.in, got, want) + } else if g := got["val"]; !cmp.Equal(g, test.want) { + t.Errorf("%v: got %v (%T), want %v (%T)", test.in, g, g, test.want, test.want) + } + } + + // TODO: strings: valid vs. invalid unicode +} + +var ( + // A time with non-zero milliseconds, but zero nanoseconds. + milliTime = time.Date(2019, time.March, 27, 0, 0, 0, 5*1e6, time.UTC) + // A time with non-zero nanoseconds. + nanoTime = time.Date(2019, time.March, 27, 0, 0, 0, 5*1e6+7, time.UTC) +) + +// Test that encoding from a struct and then decoding into the same struct works properly. +// The decoding is "type-driven" because the decoder knows the expected type of the value +// it is decoding--it is the type of a struct field. +func testTypeDrivenDecode(t *testing.T, ct CodecTester) { + t.Helper() + + if ct == nil { + t.Skip("no CodecTester") + } + check := func(in, dec interface{}, encode func(interface{}) (interface{}, error), decode func(interface{}, interface{}) error) { + t.Helper() + enc, err := encode(in) + if err != nil { + t.Fatalf("%+v", err) + } + if err := decode(enc, dec); err != nil { + t.Fatalf("%+v", err) + } + if diff := cmp.Diff(in, dec); diff != "" { + t.Error(diff) + } + } + + s := "bar" + dsrt := &docstoreRoundTrip{ + N: nil, + I: 1, + U: 2, + F: 2.5, + St: "foo", + B: true, + L: []int{3, 4, 5}, + A: [2]int{6, 7}, + A2: [2]int8{1, 2}, + At: ByteArray{1, 2}, + Uu: uuid.NameSpaceDNS, + M: map[string]bool{"a": true, "b": false}, + By: []byte{6, 7, 8}, + P: &s, + T: milliTime, + } + + check(dsrt, &docstoreRoundTrip{}, ct.DocstoreEncode, ct.DocstoreDecode) + + // Test native-to-docstore and docstore-to-native round trips with a smaller set + // of types. + nm := &nativeMinimal{ + N: nil, + I: 1, + F: 2.5, + St: "foo", + B: true, + L: []int{3, 4, 5}, + A: [2]int{6, 7}, + A2: [2]int8{6, 7}, + At: ByteArray{1, 2}, + M: map[string]bool{"a": true, "b": false}, + By: []byte{6, 7, 8}, + P: &s, + T: milliTime, + LF: []float64{18.8, -19.9, 20}, + LS: []string{"foo", "bar"}, + } + check(nm, &nativeMinimal{}, ct.DocstoreEncode, ct.NativeDecode) + check(nm, &nativeMinimal{}, ct.NativeEncode, ct.DocstoreDecode) + + // Test various other types, unless they are unsupported. + unsupported := map[UnsupportedType]bool{} + for _, u := range ct.UnsupportedTypes() { + unsupported[u] = true + } + + // Unsigned integers. + if !unsupported[Uint] { + type Uint struct { + U uint + } + u := &Uint{10} + check(u, &Uint{}, ct.DocstoreEncode, ct.NativeDecode) + check(u, &Uint{}, ct.NativeEncode, ct.DocstoreDecode) + } + + // Arrays. + if !unsupported[Arrays] { + type Arrays struct { + A [2]int + } + a := &Arrays{[2]int{13, 14}} + check(a, &Arrays{}, ct.DocstoreEncode, ct.NativeDecode) + check(a, &Arrays{}, ct.NativeEncode, ct.DocstoreDecode) + } + // Nanosecond-precision time. + type NT struct { + T time.Time + } + + nt := &NT{nanoTime} + if unsupported[NanosecondTimes] { + // Expect rounding to the nearest millisecond. + check := func(encode func(interface{}) (interface{}, error), decode func(interface{}, interface{}) error) { + enc, err := encode(nt) + if err != nil { + t.Fatalf("%+v", err) + } + var got NT + if err := decode(enc, &got); err != nil { + t.Fatalf("%+v", err) + } + want := nt.T.Round(time.Millisecond) + if !got.T.Equal(want) { + t.Errorf("got %v, want %v", got.T, want) + } + } + check(ct.DocstoreEncode, ct.NativeDecode) + check(ct.NativeEncode, ct.DocstoreDecode) + } else { + // Expect perfect round-tripping of nanosecond times. + check(nt, &NT{}, ct.DocstoreEncode, ct.NativeDecode) + check(nt, &NT{}, ct.NativeEncode, ct.DocstoreDecode) + } + + // Binary sets. + if !unsupported[BinarySet] { + type BinarySet struct { + B [][]byte + } + b := &BinarySet{[][]byte{{15}, {16}, {17}}} + check(b, &BinarySet{}, ct.DocstoreEncode, ct.NativeDecode) + check(b, &BinarySet{}, ct.NativeEncode, ct.DocstoreDecode) + } +} + +// Test decoding into an interface{}, where the decoder doesn't know the type of the +// result and must return some Go type that accurately represents the value. +// This is implemented by the AsInterface method of driver.Decoder. +// Since it's fine for different drivers to return different types in this case, +// each test case compares against a list of possible values. +func testBlindDecode(t *testing.T, ct CodecTester) { + t.Helper() + + if ct == nil { + t.Skip("no CodecTester") + } + t.Run("DocstoreEncode", func(t *testing.T) { testBlindDecode1(t, ct.DocstoreEncode, ct.DocstoreDecode) }) + t.Run("NativeEncode", func(t *testing.T) { testBlindDecode1(t, ct.NativeEncode, ct.DocstoreDecode) }) +} + +func testBlindDecode1(t *testing.T, encode func(interface{}) (interface{}, error), decode func(_, _ interface{}) error) { + t.Helper() + + // Encode and decode expect a document, so use this struct to hold the values. + type S struct{ X interface{} } + + for _, test := range []struct { + in interface{} // the value to be encoded + want interface{} // one possibility + want2 interface{} // a second possibility + }{ + {in: nil, want: nil}, + {in: true, want: true}, + {in: "foo", want: "foo"}, + {in: 'c', want: 'c', want2: int64('c')}, + {in: int(3), want: int32(3), want2: int64(3)}, + {in: int8(3), want: int32(3), want2: int64(3)}, + {in: int(-3), want: int32(-3), want2: int64(-3)}, + {in: int64(math.MaxInt32 + 1), want: int64(math.MaxInt32 + 1)}, + {in: float32(1.5), want: float64(1.5)}, + {in: float64(1.5), want: float64(1.5)}, + {in: []byte{1, 2}, want: []byte{1, 2}}, + { + in: []int{1, 2}, + want: []interface{}{int32(1), int32(2)}, + want2: []interface{}{int64(1), int64(2)}, + }, + {in: []float32{1.5, 2.5}, want: []interface{}{float64(1.5), float64(2.5)}}, + {in: []float64{1.5, 2.5}, want: []interface{}{float64(1.5), float64(2.5)}}, + {in: milliTime, want: milliTime, want2: "2019-03-27T00:00:00.005Z"}, + { + in: []time.Time{milliTime}, + want: []interface{}{milliTime}, + want2: []interface{}{"2019-03-27T00:00:00.005Z"}, + }, + { + in: map[string]int{"a": 1}, + want: map[string]interface{}{"a": int64(1)}, + want2: map[string]interface{}{"a": int32(1)}, + }, + {in: map[string][]byte{"a": {1, 2}}, want: map[string]interface{}{"a": []byte{1, 2}}}, + } { + enc, err := encode(&S{test.in}) + if err != nil { + t.Fatalf("encoding %T: %v", test.in, err) + } + var got S + if err := decode(enc, &got); err != nil { + t.Fatalf("decoding %T: %v", test.in, err) + } + matched := false + wants := []interface{}{test.want} + if test.want2 != nil { + wants = append(wants, test.want2) + } + for _, w := range wants { + if cmp.Equal(got.X, w) { + matched = true + break + } + } + if !matched { + t.Errorf("%T: got %#v (%T), not equal to %#v or %#v", test.in, got.X, got.X, test.want, test.want2) + } + } +} + +// A round trip with the docstore codec should work for all docstore-supported types, +// regardless of native driver support. +type docstoreRoundTrip struct { + N *int + I int + U uint + F float64 + St string + B bool + By []byte + L []int + A [2]int + A2 [2]int8 + At ByteArray + Uu uuid.UUID + M map[string]bool + P *string + T time.Time +} + +// TODO(jba): add more fields: structs; embedding. + +// All native codecs should support these types. If one doesn't, remove it from this +// struct and make a new single-field struct for it. +type nativeMinimal struct { + N *int + I int + F float64 + St string + B bool + By []byte + L []int + A [2]int + A2 [2]int8 + At ByteArray + M map[string]bool + P *string + T time.Time + LF []float64 + LS []string +} + +// testProto tests encoding/decoding of a document with protocol buffer +// and pointer-to-protocol-buffer fields. +func testProto(t *testing.T, _ Harness, coll *docstore.Collection) { + t.Helper() + + ctx := context.Background() + type protoStruct struct { + Name string `docstore:"name"` + Proto tspb.Timestamp + PtrToProto *tspb.Timestamp + DocstoreRevision interface{} + } + doc := &protoStruct{ + Name: "testing", + Proto: tspb.Timestamp{Seconds: 42}, + PtrToProto: &tspb.Timestamp{Seconds: 43}, + } + + err := coll.Create(ctx, doc) + if err != nil { + t.Fatal(err) + } + got := &protoStruct{} + err = coll.Query().Get(ctx).Next(ctx, got) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(got, doc, cmpopts.IgnoreUnexported(tspb.Timestamp{})); diff != "" { + t.Error(diff) + } +} + +// The following is the schema for the collection where the ID is composed from +// multiple fields instead of one. It can be used for query testing. +// It is loosely borrowed from the DynamoDB documentation. +// It is rich enough to require indexes for some drivers. + +// A HighScore records one user's high score in a particular game. +// The primary key fields are Game and Player. +type HighScore struct { + Game string + Player string + Score int + Time time.Time + WithGlitch bool + DocstoreRevision interface{} +} + +func newHighScore() interface{} { return &HighScore{} } + +// HighScoreKey constructs a single primary key from a HighScore struct or a map +// with the same fields by concatenating the Game and Player fields. +func HighScoreKey(doc docstore.Document) interface{} { + switch d := doc.(type) { + case *HighScore: + return d.key() + case map[string]interface{}: + return barConcat(d["Game"], d["Player"]) + default: + panic("bad arg") + } +} + +func (h *HighScore) key() string { + if h.Game == "" || h.Player == "" { + return "" + } + return barConcat(h.Game, h.Player) +} + +func barConcat(a, b interface{}) string { return fmt.Sprintf("%v|%v", a, b) } + +func highScoreLess(h1, h2 *HighScore) bool { return h1.key() < h2.key() } + +func (h *HighScore) String() string { + return fmt.Sprintf("%s=%d@%s", h.key(), h.Score, h.Time.Format("01/02")) +} + +func date(month, day int) time.Time { + return time.Date(2019, time.Month(month), day, 0, 0, 0, 0, time.UTC) +} + +const ( + game1 = "Praise All Monsters" + game2 = "Zombie DMV" + game3 = "Days Gone" +) + +var highScores = []*HighScore{ + {game1, "pat", 49, date(3, 13), false, nil}, + {game1, "mel", 60, date(4, 10), false, nil}, + {game1, "andy", 81, date(2, 1), false, nil}, + {game1, "fran", 33, date(3, 19), false, nil}, + {game2, "pat", 120, date(4, 1), true, nil}, + {game2, "billie", 111, date(4, 10), false, nil}, + {game2, "mel", 190, date(4, 18), true, nil}, + {game2, "fran", 33, date(3, 20), false, nil}, +} + +func addHighScores(t *testing.T, coll *docstore.Collection) { + t.Helper() + + alist := coll.Actions() + for _, doc := range highScores { + d := *doc + alist.Put(&d) + } + if err := alist.Do(context.Background()); err != nil { + t.Fatalf("%+v", err) + } +} + +func testGetQueryKeyField(t *testing.T, coll *docstore.Collection, revField string) { + t.Helper() + + // Query the key field of a collection that has one. + // (The collection used for testGetQuery uses a key function rather than a key field.) + ctx := context.Background() + docs := []docmap{ + {KeyField: "qkf1", "a": "one", revField: nil}, + {KeyField: "qkf2", "a": "two", revField: nil}, + {KeyField: "qkf3", "a": "three", revField: nil}, + } + al := coll.Actions() + for _, d := range docs { + al.Put(d) + } + if err := al.Do(ctx); err != nil { + t.Fatal(err) + } + iter := coll.Query().Where(KeyField, "<", "qkf3").Get(ctx) + defer iter.Stop() + got := mustCollect(ctx, t, iter) + want := docs[:2] + diff := cmpDiff(got, want, cmpopts.SortSlices(sortByKeyField)) + if diff != "" { + t.Error(diff) + } + + // Test that queries with selected fields always return the key. + iter = coll.Query().Get(ctx, "a", docstore.FieldPath(revField)) + defer iter.Stop() + got = mustCollect(ctx, t, iter) + for _, d := range docs { + checkHasRevisionField(t, d, revField) + } + diff = cmpDiff(got, docs, cmpopts.SortSlices(sortByKeyField)) + if diff != "" { + t.Error(diff) + } +} + +func sortByKeyField(d1, d2 docmap) bool { return d1[KeyField].(string) < d2[KeyField].(string) } + +// TODO(shantuo): consider add this test to all action tests, like the AltRev +// ones. +func testActionsWithCompositeID(t *testing.T, _ Harness, coll *docstore.Collection) { + t.Helper() + + ctx := context.Background() + // Create cannot generate an ID for the document when using IDFunc. + checkCode(t, coll.Create(ctx, &HighScore{}), gcerrors.InvalidArgument) + checkCode(t, coll.Get(ctx, &HighScore{}), gcerrors.InvalidArgument) + + // Put + addHighScores(t, coll) + // Get + gots := make([]*HighScore, len(highScores)) + actions := coll.Actions() + for i, doc := range highScores { + gots[i] = &HighScore{Game: doc.Game, Player: doc.Player} + actions.Get(gots[i]) + } + if err := actions.Do(ctx); err != nil { + t.Fatal(err) + } + for i, got := range gots { + if got.DocstoreRevision == nil { + t.Errorf("%v missing DocstoreRevision", got) + } else { + got.DocstoreRevision = nil + } + if diff := cmp.Diff(got, highScores[i]); diff != "" { + t.Error(diff) + } + } +} + +func testGetQuery(t *testing.T, _ Harness, coll *docstore.Collection) { + t.Helper() + + ctx := context.Background() + addHighScores(t, coll) + + // Query filters should have the same behavior when doing string and number + // comparison. + tests := []struct { + name string + q *docstore.Query + fields []docstore.FieldPath // fields to get + want func(*HighScore) bool // filters highScores + before func(x, y *HighScore) bool // if present, checks result order + }{ + { + name: "All", + q: coll.Query(), + want: func(*HighScore) bool { return true }, + }, + { + name: "Game", + q: coll.Query().Where("Game", "=", game2), + want: func(h *HighScore) bool { return h.Game == game2 }, + }, + { + name: "Score", + q: coll.Query().Where("Score", ">", 100), + want: func(h *HighScore) bool { return h.Score > 100 }, + }, + { + name: "Player", + q: coll.Query().Where("Player", "=", "billie"), + want: func(h *HighScore) bool { return h.Player == "billie" }, + }, + { + name: "GamePlayer", + q: coll.Query().Where("Player", "=", "andy").Where("Game", "=", game1), + want: func(h *HighScore) bool { return h.Player == "andy" && h.Game == game1 }, + }, + { + name: "PlayerScore", + q: coll.Query().Where("Player", "=", "pat").Where("Score", "<", 100), + want: func(h *HighScore) bool { return h.Player == "pat" && h.Score < 100 }, + }, + { + name: "GameScore", + q: coll.Query().Where("Game", "=", game1).Where("Score", ">=", 50), + want: func(h *HighScore) bool { return h.Game == game1 && h.Score >= 50 }, + }, + { + name: "PlayerTime", + q: coll.Query().Where("Player", "=", "mel").Where("Time", ">", date(4, 1)), + want: func(h *HighScore) bool { return h.Player == "mel" && h.Time.After(date(4, 1)) }, + }, + { + name: "ScoreTime", + q: coll.Query().Where("Score", ">=", 50).Where("Time", ">", date(4, 1)), + want: func(h *HighScore) bool { return h.Score >= 50 && h.Time.After(date(4, 1)) }, + }, + { + name: "PlayerIn", + q: coll.Query().Where("Player", "in", []string{"pat", "billie"}), + want: func(h *HighScore) bool { return h.Player == "pat" || h.Player == "billie" }, + }, + { + name: "PlayerNotIn", + q: coll.Query().Where("Player", "not-in", []string{"pat", "billie"}), + want: func(h *HighScore) bool { return h.Player != "pat" && h.Player != "billie" }, + }, + { + name: "WithGlitch", + q: coll.Query().Where("WithGlitch", "=", true), + want: func(h *HighScore) bool { return h.WithGlitch }, + }, + { + name: "WithGlitchIn", + q: coll.Query().Where("WithGlitch", "in", []bool{true}), + want: func(h *HighScore) bool { return h.WithGlitch }, + }, + { + name: "WithGlitchNotIn", + q: coll.Query().Where("WithGlitch", "not-in", []bool{true}), + want: func(h *HighScore) bool { return !h.WithGlitch }, + }, + { + name: "AllByPlayerAsc", + q: coll.Query().OrderBy("Player", docstore.Ascending), + want: func(h *HighScore) bool { return true }, + before: func(h1, h2 *HighScore) bool { return h1.Player < h2.Player }, + }, + { + name: "AllByPlayerDesc", + q: coll.Query().OrderBy("Player", docstore.Descending), + want: func(h *HighScore) bool { return true }, + before: func(h1, h2 *HighScore) bool { return h1.Player > h2.Player }, + }, + { + name: "GameByPlayerAsc", + // We need a filter on Player, and it can't be the empty string (DynamoDB limitation). + // So pick any string that sorts less than all valid player names. + q: coll.Query().Where("Game", "=", game1).Where("Player", ">", "."). + OrderBy("Player", docstore.Ascending), + want: func(h *HighScore) bool { return h.Game == game1 }, + before: func(h1, h2 *HighScore) bool { return h1.Player < h2.Player }, + }, + { + // Same as above, but descending. + name: "GameByPlayerDesc", + q: coll.Query().Where("Game", "=", game1).Where("Player", ">", "."). + OrderBy("Player", docstore.Descending), + want: func(h *HighScore) bool { return h.Game == game1 }, + before: func(h1, h2 *HighScore) bool { return h1.Player > h2.Player }, + }, + // TODO(jba): add more OrderBy tests. + { + name: "AllWithKeyFields", + q: coll.Query(), + fields: []docstore.FieldPath{"Game", "Player", docstore.FieldPath(docstore.DefaultRevisionField)}, + want: func(h *HighScore) bool { + h.Score = 0 + h.Time = time.Time{} + h.WithGlitch = false + return true + }, + }, + { + name: "AllWithScore", + q: coll.Query(), + fields: []docstore.FieldPath{"Game", "Player", "Score", "WithGlitch", docstore.FieldPath(docstore.DefaultRevisionField)}, + want: func(h *HighScore) bool { + h.Time = time.Time{} + return true + }, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got, err := collectHighScores(ctx, tc.q.Get(ctx, tc.fields...)) + if err != nil { + t.Fatal(err) + } + for _, g := range got { + if g.DocstoreRevision == nil { + t.Errorf("%v missing DocstoreRevision", g) + } else { + g.DocstoreRevision = nil + } + } + want := filterHighScores(highScores, tc.want) + _, err = tc.q.Plan() + if err != nil { + t.Fatal(err) + } + diff := cmp.Diff(got, want, cmpopts.SortSlices(highScoreLess)) + if diff != "" { + t.Fatal(diff) + } + if tc.before != nil { + // Verify that the results are sorted according to tc.less. + for i := 1; i < len(got); i++ { + if tc.before(got[i], got[i-1]) { + t.Errorf("%s at %d sorts before previous %s", got[i], i, got[i-1]) + } + } + } + // We can't assume anything about the query plan. Just verify that Plan returns + // successfully. + if _, err := tc.q.Plan(KeyField); err != nil { + t.Fatal(err) + } + }) + } + t.Run("OffsetAndLimitCounts", func(t *testing.T) { + nDocs := len(highScores) // 8 + tests := []struct { + name string + offset int + limit int + expected int + }{ + { + name: "LimitOnly", + offset: 0, + limit: 2, + expected: 2, + }, + { + name: "OffsetOnly", + offset: 2, + limit: nDocs, + expected: nDocs - 2, + }, + { + name: "OffsetAndLimit", + offset: 2, + limit: 2, + expected: 2, + }, + { + name: "OffsetEqualToFirstPage", + offset: nDocs, + limit: 2, + expected: 0, + }, + { + name: "OffsetLessThanFirstPage", + offset: nDocs - 1, + limit: 2, + expected: 1, + }, + { + name: "OffsetGreaterThanFirstPage", + offset: nDocs + 1, + limit: 2, + expected: 0, + }, + { + name: "OffsetIsZero", + offset: 0, + limit: 2, + expected: 2, + }, + { + name: "OffsetAndLimitGreaterThanPageSize", + offset: nDocs + 1, + limit: nDocs + 1, + expected: 0, + }, + { + name: "OffsetLessThanPageSizeAndLimitGreaterThanPageSize", + offset: nDocs - 1, + limit: nDocs + 1, + expected: 1, + }, + // Scenarios covered elsewhere: + // - /go-cloud/docstore/query_test.go#TestInvalidQuery: + // - NegativeLimit + // - ZeroLimit + // - TwoLimits + // - NegativeOffset + // - TwoOffsets + // - ZeroOffsetAndLimit + // - NegativeOffsetAndLimit + // - ZeroOffsetAndNegativeLimit + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + offsetLimitQ := coll.Query().Offset(tt.offset).Limit(tt.limit) + got := mustCollectHighScores(ctx, t, offsetLimitQ.Get(ctx)) + + if len(got) != tt.expected { + t.Errorf("got %v, wanted %v documents", len(got), tt.expected) + } + }) + } + }) + t.Run("EOF", func(t *testing.T) { + // To address this issue https://github.com/google/go-cloud/issues/3405#issue-2193025645 + q := coll.Query() + it := q.Get(context.Background()) + defer it.Stop() + h := &HighScore{} + for { + err := it.Next(context.Background(), h) + if err == io.EOF { + break + } + if err != nil { + t.Errorf("unexpected error: %v", err) + return + } + } + // Call Next again to trigger io.EOF + err := it.Next(context.Background(), h) + if err != io.EOF { + t.Errorf("expected io.EOF, got %v", err) + } + }) +} + +func filterHighScores(hs []*HighScore, f func(*HighScore) bool) []*HighScore { + var res []*HighScore + for _, h := range hs { + c := *h // Copy in case f modifies its argument. + if f(&c) { + res = append(res, &c) + } + } + return res +} + +// ClearCollection delete all documents from this collection after test. +func ClearCollection(fataler interface { + Helper() + Fatalf(string, ...interface{}) +}, coll *docstore.Collection, +) { + fataler.Helper() + + ctx := context.Background() + iter := coll.Query().Get(ctx) + dels := coll.Actions() + for { + doc := map[string]interface{}{} + err := iter.Next(ctx, doc) + if err == io.EOF { + break + } + if err != nil { + fataler.Fatalf("%+v", err) + } + dels.Delete(doc) + } + if err := dels.Do(ctx); err != nil { + fataler.Fatalf("%+v", err) + } +} + +func forEach(ctx context.Context, iter *docstore.DocumentIterator, create func() interface{}, handle func(interface{}) error) error { + for { + doc := create() + err := iter.Next(ctx, doc) + if err == io.EOF { + break + } + if err != nil { + return err + } + if err := handle(doc); err != nil { + return err + } + } + return nil +} + +func mustCollect(ctx context.Context, t *testing.T, iter *docstore.DocumentIterator) []docmap { + t.Helper() + + var ms []docmap + newDocmap := func() interface{} { return docmap{} } + collect := func(m interface{}) error { ms = append(ms, m.(docmap)); return nil } + if err := forEach(ctx, iter, newDocmap, collect); err != nil { + t.Fatal(err) + } + return ms +} + +func mustCollectHighScores(ctx context.Context, t *testing.T, iter *docstore.DocumentIterator) []*HighScore { + t.Helper() + + hs, err := collectHighScores(ctx, iter) + if err != nil { + t.Fatal(err) + } + return hs +} + +func collectHighScores(ctx context.Context, iter *docstore.DocumentIterator) ([]*HighScore, error) { + var hs []*HighScore + collect := func(h interface{}) error { hs = append(hs, h.(*HighScore)); return nil } + if err := forEach(ctx, iter, newHighScore, collect); err != nil { + return nil, err + } + return hs, nil +} + +func testMultipleActions(t *testing.T, coll *docstore.Collection, revField string) { + t.Helper() + + ctx := context.Background() + + must := func(err error) { + t.Helper() + if err != nil { + t.Fatal(err) + } + } + + var docs []docmap + for i := 0; i < 9; i++ { + docs = append(docs, docmap{ + KeyField: fmt.Sprintf("testUnorderedActions%d", i), + "s": fmt.Sprint(i), + revField: nil, + }) + } + + compare := func(gots, wants []docmap) { + t.Helper() + for i := 0; i < len(gots); i++ { + got := gots[i] + want := clone(wants[i]) + want[revField] = got[revField] + if !cmp.Equal(got, want, cmpopts.IgnoreUnexported(tspb.Timestamp{})) { + t.Errorf("index #%d:\ngot %v\nwant %v", i, got, want) + } + } + } + + // Put the first three docs. + actions := coll.Actions() + for i := 0; i < 6; i++ { + actions.Create(docs[i]) + } + must(actions.Do(ctx)) + + // Replace the first three and put six more. + actions = coll.Actions() + for i := 0; i < 3; i++ { + docs[i]["s"] = fmt.Sprintf("%d'", i) + actions.Replace(docs[i]) + } + for i := 3; i < 9; i++ { + actions.Put(docs[i]) + } + must(actions.Do(ctx)) + + // Delete the first three, get the second three, and put three more. + gdocs := []docmap{ + {KeyField: docs[3][KeyField]}, + {KeyField: docs[4][KeyField]}, + {KeyField: docs[5][KeyField]}, + } + actions = coll.Actions() + actions.Update(docs[6], docstore.Mods{"s": "6'", "n": docstore.Increment(1)}) + actions.Get(gdocs[0]) + actions.Delete(docs[0]) + actions.Delete(docs[1]) + actions.Update(docs[7], docstore.Mods{"s": "7'"}) + actions.Get(gdocs[1]) + actions.Delete(docs[2]) + actions.Get(gdocs[2]) + actions.Update(docs[8], docstore.Mods{"n": docstore.Increment(-1)}) + must(actions.Do(ctx)) + compare(gdocs, docs[3:6]) + + // At this point, the existing documents are 3 - 9. + + // Get the first four, try to create one that already exists, delete a + // nonexistent doc, and put one. Only the Get of #3, the Delete and the Put + // should succeed. + actions = coll.Actions() + for _, doc := range []docmap{ + {KeyField: docs[0][KeyField]}, + {KeyField: docs[1][KeyField]}, + {KeyField: docs[2][KeyField]}, + {KeyField: docs[3][KeyField]}, + } { + actions.Get(doc) + } + docs[4][revField] = nil + actions.Create(docs[4]) // create existing doc + actions.Put(docs[5]) + // TODO(jba): Understand why the following line is necessary for dynamo but not the others. + docs[0][revField] = nil + actions.Delete(docs[0]) // delete nonexistent doc + err := actions.Do(ctx) + if err == nil { + t.Fatal("want error, got nil") + } + alerr, ok := err.(docstore.ActionListError) + if !ok { + t.Fatalf("got %v (%T), want ActionListError", alerr, alerr) + } + for _, e := range alerr { + switch i := e.Index; i { + case 3, 5, 6: + t.Errorf("index %d: got %v, want nil", i, e.Err) + + case 4, -1: // -1 for mongodb issue, see https://jira.mongodb.org/browse/GODRIVER-1028 + if ec := gcerrors.Code(e.Err); ec != gcerrors.AlreadyExists && + ec != gcerrors.FailedPrecondition { // TODO(shantuo): distinguish this case for dyanmo + t.Errorf("index 4: create an existing document: got %v, want error", e.Err) + } + + default: + if gcerrors.Code(e.Err) != gcerrors.NotFound { + t.Errorf("index %d: got %v, want NotFound", i, e.Err) + } + } + } +} + +func testAtomicWrites(t *testing.T, coll *docstore.Collection, revField string) { + t.Helper() + + ctx := context.Background() + + must := func(err error) { + t.Helper() + if err != nil { + t.Fatal(err) + } + } + + var docs []docmap + for i := 0; i < 9; i++ { + docs = append(docs, docmap{ + KeyField: fmt.Sprintf("testAtomicWrites%d", i), + "s": fmt.Sprint(i), + revField: nil, + }) + } + + compare := func(gots, wants []docmap) { + t.Helper() + for i := 0; i < len(gots); i++ { + got := gots[i] + want := clone(wants[i]) + want[revField] = got[revField] + if !cmp.Equal(got, want, cmpopts.IgnoreUnexported(tspb.Timestamp{})) { + t.Errorf("index #%d:\ngot %v\nwant %v", i, got, want) + } + } + } + + // Put the nine docs. + actions := coll.Actions() + for i := 0; i < 9; i++ { + actions.Create(docs[i]) + } + must(actions.Do(ctx)) + + // Delete the first three, get the second three, and update last three in transaction. + gdocs := []docmap{ + {KeyField: docs[3][KeyField]}, + {KeyField: docs[4][KeyField]}, + {KeyField: docs[5][KeyField]}, + } + actions = coll.Actions() + actions.Get(gdocs[0]) + actions.Delete(docs[0]) + actions.Delete(docs[1]) + actions.Get(gdocs[1]) + actions.Delete(docs[2]) + actions.Get(gdocs[2]) + actions.AtomicWrites() + actions.Update(docs[6], docstore.Mods{"s": "66"}) + actions.Update(docs[7], docstore.Mods{"s": "77"}) + actions.Update(docs[8], docstore.Mods{"s": "88"}) + + must(actions.Do(ctx)) + compare(gdocs, docs[3:6]) + + // Get the docs updated as part of atomic writes and verify that the values were updated successfully. + actions = coll.Actions() + + doc := docmap{KeyField: docs[6][KeyField]} + _ = coll.Get(ctx, doc) + if diff := cmpDiff("66", doc["s"]); diff != "" { + t.Fatal(diff) + } + + doc = docmap{KeyField: docs[7][KeyField]} + _ = coll.Get(ctx, doc) + if diff := cmpDiff("77", doc["s"]); diff != "" { + t.Fatal(diff) + } + + doc = docmap{KeyField: docs[8][KeyField]} + _ = coll.Get(ctx, doc) + if diff := cmpDiff("88", doc["s"]); diff != "" { + t.Fatal(diff) + } +} + +func testAtomicWritesFail(t *testing.T, coll *docstore.Collection, revField string) { + t.Helper() + + ctx := context.Background() + + must := func(err error) { + t.Helper() + if err != nil { + t.Fatal(err) + } + } + + var docs []docmap + for i := 0; i < 9; i++ { + docs = append(docs, docmap{ + KeyField: fmt.Sprintf("testAtomicWrites%d", i), + "s": fmt.Sprint(i), + revField: nil, + }) + } + + compare := func(gots, wants []docmap) { + t.Helper() + for i := 0; i < len(gots); i++ { + got := gots[i] + want := clone(wants[i]) + want[revField] = got[revField] + if !cmp.Equal(got, want, cmpopts.IgnoreUnexported(tspb.Timestamp{})) { + t.Errorf("index #%d:\ngot %v\nwant %v", i, got, want) + } + } + } + + // Put the first eight docs. + actions := coll.Actions() + for i := 0; i < 8; i++ { + actions.Create(docs[i]) + } + must(actions.Do(ctx)) + + // Delete the first three, get the second three, and update last three in transaction. + gdocs := []docmap{ + {KeyField: docs[3][KeyField]}, + {KeyField: docs[4][KeyField]}, + {KeyField: docs[5][KeyField]}, + } + actions = coll.Actions() + actions.Get(gdocs[0]) + actions.Delete(docs[0]) + actions.Delete(docs[1]) + actions.Get(gdocs[1]) + actions.Delete(docs[2]) + actions.Get(gdocs[2]) + actions.AtomicWrites() + actions.Update(docs[6], docstore.Mods{"s": "66"}) + actions.Update(docs[7], docstore.Mods{"s": "77"}) + // this document doesn't exist so it will fail the transaction + actions.Update(docs[8], docstore.Mods{"s": "88"}) + + err := actions.Do(ctx) + if err == nil { + t.Fatal("want transaction to fail") + } + compare(gdocs, docs[3:6]) + + // validate that the values still remains the original + doc := docmap{KeyField: docs[6][KeyField]} + _ = coll.Get(ctx, doc) + if diff := cmpDiff("6", doc["s"]); diff != "" { + t.Fatal(diff) + } + + doc = docmap{KeyField: docs[7][KeyField]} + _ = coll.Get(ctx, doc) + if diff := cmpDiff("7", doc["s"]); diff != "" { + t.Fatal(diff) + } +} + +func testActionsOnStructNoRev(t *testing.T, _ Harness, coll *docstore.Collection) { + t.Helper() + + type item struct { + Name string `docstore:"name"` + I int + } + doc1 := item{Name: "createandreplace"} + doc2 := item{Name: "putandupdate"} + ctx := context.Background() + + got1 := item{Name: doc1.Name} + got2 := map[string]interface{}{"name": doc2.Name} + if err := coll.Actions(). + Create(&doc1).Put(&doc2). + Get(&got1).Get(got2). + Do(ctx); err != nil { + t.Fatal(err) + } + checkNoRevisionField(t, got2, docstore.DefaultRevisionField) + + got3 := map[string]interface{}{"name": doc1.Name} + got4 := item{Name: doc2.Name} + if err := coll.Actions(). + Replace(&doc1).Update(&item{Name: doc2.Name}, docstore.Mods{"I": 1}). + Get(got3, "I").Get(&got4, "I"). + Do(ctx); err != nil { + t.Fatal(err) + } + checkNoRevisionField(t, got3, docstore.DefaultRevisionField) +} + +func testExampleInDoc(t *testing.T, _ Harness, coll *docstore.Collection) { + t.Helper() + + type Name struct { + First, Last string + } + type Book struct { + Title string `docstore:"name"` + Author Name `docstore:"author"` + PublicationYears []int `docstore:"pub_years,omitempty"` + NumPublications int `docstore:"-"` + } + + must := func(err error) { + t.Helper() + if err != nil { + t.Fatal(err) + } + } + checkFieldEqual := func(got, want interface{}, field string) { + t.Helper() + fvg, err := MustDocument(got).GetField(field) + must(err) + fvw, err := MustDocument(want).GetField(field) + must(err) + if !cmp.Equal(fvg, fvw) { + t.Errorf("%s: got %v want %v", field, fvg, fvw) + } + } + + doc1 := &Book{ + Title: "The Master and Margarita", + Author: Name{ + First: "Mikhail", + Last: "Bulgakov", + }, + PublicationYears: []int{1967, 1973}, + NumPublications: 2, + } + + doc2 := map[string]interface{}{ + KeyField: "The Heart of a Dog", + "author": map[string]interface{}{ + "First": "Mikhail", + "Last": "Bulgakov", + }, + "pub_years": []int{1968, 1987}, + } + + ctx := context.Background() + must(coll.Actions().Create(doc1).Put(doc2).Do(ctx)) + got1 := &Book{Title: doc1.Title} + got2 := &Book{Title: doc2[KeyField].(string)} + must(coll.Actions().Get(got1).Get(got2).Do(ctx)) + + if got1.NumPublications != 0 { + t.Errorf("docstore:\"-\" tagged field isn't ignored") + } + checkFieldEqual(got1, doc1, "author") + checkFieldEqual(got2, doc2, "pub_years") + + gots := mustCollect(ctx, t, coll.Query().Where("author.Last", "=", "Bulgakov").Get(ctx)) + if len(gots) != 2 { + t.Errorf("got %v want all two results", gots) + } + must(coll.Actions().Delete(doc1).Delete(doc2).Do(ctx)) +} + +// Verify that BeforeDo is invoked, and its as function behaves as expected. +func testBeforeDo(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + ctx := context.Background() + withCollection(t, newHarness, SingleKey, func(t *testing.T, h Harness, coll *docstore.Collection) { + t.Helper() + + var called bool + beforeDo := func(asFunc func(interface{}) bool) error { + called = true + if asFunc(nil) { + return errors.New("asFunc returned true when called with nil, want false") + } + // At least one of the expected types must return true. Special case: if + // there are no types, then the as function never returns true, so skip the + // check. + if len(h.BeforeDoTypes()) > 0 { + found := false + for _, b := range h.BeforeDoTypes() { + v := reflect.New(reflect.TypeOf(b)).Interface() + if asFunc(v) { + found = true + break + } + } + if !found { + return errors.New("none of the BeforeDoTypes works with the as function") + } + } + return nil + } + + check := func(f func(*docstore.ActionList)) { + t.Helper() + // First, verify that if a BeforeDo function returns an error, so does ActionList.Do. + // We depend on that for the rest of the test. + al := coll.Actions().BeforeDo(func(func(interface{}) bool) error { return errors.New("") }) + f(al) + if err := al.Do(ctx); err == nil { + t.Error("beforeDo returning error: got nil from Do, want error") + return + } + called = false + al = coll.Actions().BeforeDo(beforeDo) + f(al) + if err := al.Do(ctx); err != nil { + t.Error(err) + return + } + if !called { + t.Error("BeforeDo function never called") + } + } + + doc := docmap{KeyField: "testBeforeDo"} + check(func(l *docstore.ActionList) { l.Create(doc) }) + check(func(l *docstore.ActionList) { l.Replace(doc) }) + check(func(l *docstore.ActionList) { l.Put(doc) }) + check(func(l *docstore.ActionList) { l.Update(doc, docstore.Mods{"a": 1}) }) + check(func(l *docstore.ActionList) { l.Get(doc) }) + check(func(l *docstore.ActionList) { l.Delete(doc) }) + }) +} + +// Verify that BeforeQuery is invoked, and its as function behaves as expected. +func testBeforeQuery(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + ctx := context.Background() + withCollection(t, newHarness, SingleKey, func(t *testing.T, h Harness, coll *docstore.Collection) { + t.Helper() + + var called bool + beforeQuery := func(asFunc func(interface{}) bool) error { + called = true + if asFunc(nil) { + return errors.New("asFunc returned true when called with nil, want false") + } + // At least one of the expected types must return true. Special case: if + // there are no types, then the as function never returns true, so skip the + // check. + if len(h.BeforeQueryTypes()) > 0 { + found := false + for _, b := range h.BeforeQueryTypes() { + v := reflect.New(reflect.TypeOf(b)).Interface() + if asFunc(v) { + found = true + break + } + } + if !found { + return errors.New("none of the BeforeQueryTypes works with the as function") + } + } + return nil + } + + iter := coll.Query().BeforeQuery(beforeQuery).Get(ctx) + if err := iter.Next(ctx, docmap{}); err != io.EOF { + t.Fatalf("got %v, wanted io.EOF", err) + } + if !called { + t.Error("BeforeQuery function never called for Get") + } + }) +} + +func testAs(t *testing.T, coll *docstore.Collection, st AsTest) { + t.Helper() + + // Verify Collection.As + if err := st.CollectionCheck(coll); err != nil { + t.Error(err) + } + + ctx := context.Background() + + // Query + qs := []*docstore.Query{ + coll.Query().Where("Game", "=", game3), + // Note: don't use filter on Player, the test table has Player as the + // partition key of a Global Secondary Index, which doesn't support + // ConsistentRead mode, which is what the As test does in its BeforeQuery + // function. + coll.Query().Where("Score", ">", 50), + } + for _, q := range qs { + iter := q.Get(ctx) + if err := st.QueryCheck(iter); err != nil { + t.Error(err) + } + } + + // ErrorCheck + doc := &HighScore{game3, "steph", 24, date(4, 25), false, nil} + if err := coll.Create(ctx, doc); err != nil { + t.Fatal(err) + } + doc.DocstoreRevision = nil + if err := coll.Create(ctx, doc); err == nil { + t.Fatal("got nil error from creating an existing item, want an error") + } else { + if alerr, ok := err.(docstore.ActionListError); ok { + for _, aerr := range alerr { + if checkerr := st.ErrorCheck(coll, aerr.Err); checkerr != nil { + t.Error(checkerr) + } + } + } else if checkerr := st.ErrorCheck(coll, err); checkerr != nil { + t.Error(checkerr) + } + } +} + +func clone(m docmap) docmap { + r := docmap{} + for k, v := range m { + r[k] = v + } + return r +} + +func cmpDiff(a, b interface{}, opts ...cmp.Option) string { + // Firestore revisions can be protos. + return cmp.Diff(a, b, append([]cmp.Option{cmp.Comparer(proto.Equal)}, opts...)...) +} + +func checkCode(t *testing.T, err error, code gcerrors.ErrorCode) { + t.Helper() + if gcerrors.Code(err) != code { + t.Errorf("got %v, want %s", err, code) + } +} diff --git a/go-cloud/docstore/drivertest/util.go b/go-cloud/docstore/drivertest/util.go new file mode 100644 index 000000000..af0ff5249 --- /dev/null +++ b/go-cloud/docstore/drivertest/util.go @@ -0,0 +1,52 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 drivertest + +import ( + "math/rand" + "sync" + + "github.com/google/uuid" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" +) + +// MakeUniqueStringDeterministicForTesting uses a specified seed value to +// produce the same sequence of values in driver.UniqueString for testing. +// +// Call when running tests that will be replayed. +func MakeUniqueStringDeterministicForTesting(seed int64) { + r := &randReader{r: rand.New(rand.NewSource(seed))} + uuid.SetRand(r) +} + +type randReader struct { + mu sync.Mutex + r *rand.Rand +} + +func (r *randReader) Read(buf []byte) (int, error) { + r.mu.Lock() + defer r.mu.Unlock() + return r.r.Read(buf) +} + +// MustDocument is like driver.NewDocument, but panics on error. +func MustDocument(doc interface{}) driver.Document { + dd, err := driver.NewDocument(doc) + if err != nil { + panic(err) + } + return dd +} diff --git a/go-cloud/docstore/example_test.go b/go-cloud/docstore/example_test.go new file mode 100644 index 000000000..cfe3d2718 --- /dev/null +++ b/go-cloud/docstore/example_test.go @@ -0,0 +1,286 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 docstore_test + +import ( + "context" + "fmt" + "io" + "log" + "time" + + firestore "cloud.google.com/go/firestore/apiv1" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + _ "github.com/DataDog/iceberg-go/go-cloud/docstore/awsdynamodb" + _ "github.com/DataDog/iceberg-go/go-cloud/docstore/gcpfirestore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/memdocstore" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +type Player struct { + Name string + Score int + DocstoreRevision interface{} +} + +func ExampleCollection_Actions_bulkWrite() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var coll *docstore.Collection + + // Build an ActionList to create several new players, then execute it. + // The actions may happen in any order. + newPlayers := []string{"Pat", "Mel", "Fran"} + actionList := coll.Actions() + for _, p := range newPlayers { + actionList.Create(&Player{Name: p, Score: 0}) + } + if err := actionList.Do(ctx); err != nil { + log.Fatal(err) + } +} + +func ExampleCollection_Actions_getAfterWrite() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var coll *docstore.Collection + + // Add a document to the collection, then retrieve it. + // Because both the Put and the Get refer to the same document, + // they happen in order. + got := Player{Name: "Pat"} + err := coll.Actions().Put(&Player{Name: "Pat", Score: 88}).Get(&got).Do(ctx) + if err != nil { + log.Fatal(err) + } + fmt.Println(got.Name, got.Score) +} + +func ExampleCollection_Update() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var coll *docstore.Collection + + // Create a player. + pat := &Player{Name: "Pat", Score: 0} + if err := coll.Create(ctx, pat); err != nil { + log.Fatal(err) + } + + // Set the score to a new value. + pat2 := &Player{Name: "Pat"} + err := coll.Actions().Update(pat, docstore.Mods{"Score": 15}).Get(pat2).Do(ctx) + if err != nil { + log.Fatal(err) + } + + // Increment the score. + err = coll.Actions().Update(pat, docstore.Mods{"Score": docstore.Increment(5)}).Get(pat2).Do(ctx) + if err != nil { + log.Fatal(err) + } +} + +func ExampleOpenCollection() { + ctx := context.Background() + // Open a collection using the gcpfirestore package. + // You will need to blank-import the package for this to work: + // import _ "gocloud.dev/docstore/gcpfirestore" + coll, err := docstore.OpenCollection(ctx, "firestore://my-collection") + if err != nil { + log.Fatal(err) + } + defer coll.Close() + + _ = coll // Use the collection. +} + +func ExampleCollection_As() { + // This example is specific to the gcpfirestore implementation; it demonstrates + // access to the underlying *cloud.google.com/go/firestore/apiv1.Client. + + // You will need to blank-import the package for this to work: + // import _ "gocloud.dev/docstore/gcpfirestore" + + // The types exposed for As by gcpfirestore are documented in + // https://godoc.org/gocloud.dev/docstore/gcpfirestore#hdr-As + + // This URL will open the collection using default credentials. + ctx := context.Background() + coll, err := docstore.OpenCollection(ctx, + "firestore://projects/myproject/databases/(default)/documents/mycollection?name_field=myID") + if err != nil { + log.Fatal(err) + } + defer coll.Close() + + // Try to access and use the underlying mongo.Collection. + var fsClient *firestore.Client + if coll.As(&fsClient) { + _ = fsClient // TODO: Use the client. + } else { + log.Println("Unable to access firestore.Client through Collection.As") + } +} + +func ExampleCollection_ErrorAs() { + // This example is specific to the awsdynamodb implementation. + // You will need to blank-import the package for this to work: + // import _ "gocloud.dev/docstore/awsdynamodb" + + // The types exposed for As by mongodocstore are documented in + // https://godoc.org/gocloud.dev/docstore/mongodocstore#hdr-As + + // This URL will open the collection using default credentials. + ctx := context.Background() + coll, err := docstore.OpenCollection(ctx, "dynamodb://mytable?partition_key=partkey") + if err != nil { + log.Fatal(err) + } + defer coll.Close() + + doc := map[string]interface{}{"_id": "a"} + if err := coll.Create(ctx, doc); err != nil { + var aerr awserr.Error + if coll.ErrorAs(err, &aerr) { + fmt.Println("got", aerr) + } else { + fmt.Println("could not convert error") + } + } +} + +func ExampleQuery_Get() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var coll *docstore.Collection + + // Ask for all players with scores at least 20. + iter := coll.Query().Where("Score", ">=", 20).OrderBy("Score", docstore.Descending).Get(ctx) + defer iter.Stop() + + // Query.Get returns an iterator. Call Next on it until io.EOF. + for { + var p Player + err := iter.Next(ctx, &p) + if err == io.EOF { + break + } else if err != nil { + log.Fatal(err) + } else { + fmt.Printf("%s: %d\n", p.Name, p.Score) + } + } +} + +func ExampleQuery_Get_full() { + ctx := context.Background() + coll, err := memdocstore.OpenCollection("Name", nil) + if err != nil { + log.Fatal(err) + } + defer coll.Close() + + // Add some documents to the collection. + err = coll.Actions(). + Put(&Player{Name: "Pat", Score: 10}). + Put(&Player{Name: "Mel", Score: 20}). + Put(&Player{Name: "Fran", Score: 30}). + Do(ctx) + if err != nil { + log.Fatal(err) + } + + // Ask for all players with scores at least 20. + iter := coll.Query().Where("Score", ">=", 20).OrderBy("Score", docstore.Descending).Get(ctx) + defer iter.Stop() + + // Query.Get returns an iterator. Call Next on it until io.EOF. + for { + var p Player + err := iter.Next(ctx, &p) + if err == io.EOF { + break + } else if err != nil { + log.Fatal(err) + } else { + fmt.Printf("%s: %d\n", p.Name, p.Score) + } + } + + // Output: + // Fran: 30 + // Mel: 20 +} + +func Example_optimisticLocking() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + coll, err := memdocstore.OpenCollection("Name", nil) + if err != nil { + log.Fatal(err) + } + defer coll.Close() + + // Create a player. + pat := &Player{Name: "Pat", Score: 7} + if err := coll.Create(ctx, pat); err != nil { + log.Fatal(err) + } + fmt.Println(pat) // memdocstore revisions are deterministic, so we can check the output. + + // Double a player's score. We cannot use Update to multiply, so we use optimistic + // locking instead. + + // We may have to retry a few times; put a time limit on that. + ctx, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + for { + // Get the document. + player := &Player{Name: "Pat"} + if err := coll.Get(ctx, player); err != nil { + log.Fatal(err) + } + // player.DocstoreRevision is set to the document's revision. + + // Modify the document locally. + player.Score *= 2 + + // Replace the document. player.DocstoreRevision will be checked against + // the stored document's revision. + err := coll.Replace(ctx, player) + if err != nil { + code := gcerrors.Code(err) + // On FailedPrecondition or NotFound, try again. + if code == gcerrors.FailedPrecondition || code == gcerrors.NotFound { + continue + } + log.Fatal(err) + } + fmt.Println(player) + break + } + + // Output: + // &{Pat 7 1} + // &{Pat 14 2} +} diff --git a/go-cloud/docstore/gcpfirestore/codec.go b/go-cloud/docstore/gcpfirestore/codec.go new file mode 100644 index 000000000..052302c46 --- /dev/null +++ b/go-cloud/docstore/gcpfirestore/codec.go @@ -0,0 +1,322 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcpfirestore + +// Encoding and decoding between supported docstore types and Firestore protos. + +import ( + "errors" + "fmt" + "path" + "reflect" + "time" + + pb "cloud.google.com/go/firestore/apiv1/firestorepb" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "google.golang.org/genproto/googleapis/type/latlng" + tspb "google.golang.org/protobuf/types/known/timestamppb" +) + +// encodeDoc encodes a driver.Document into Firestore's representation. +// A Firestore document (*pb.Document) is just a Go map from strings to *pb.Values. +func encodeDoc(doc driver.Document, nameField string) (*pb.Document, error) { + var e encoder + if err := doc.Encode(&e); err != nil { + return nil, err + } + fields := e.pv.GetMapValue().Fields + // Do not put the name field in the document itself. + if nameField != "" { + delete(fields, nameField) + } + return &pb.Document{Fields: fields}, nil +} + +// encodeValue encodes a Go value as a Firestore Value. +// The Firestore proto definition for Value is a oneof of various types, +// including basic types like string as well as lists and maps. +func encodeValue(x interface{}) (*pb.Value, error) { + var e encoder + if err := driver.Encode(reflect.ValueOf(x), &e); err != nil { + return nil, err + } + return e.pv, nil +} + +// encoder implements driver.Encoder. Its job is to encode a single Firestore value. +type encoder struct { + pv *pb.Value +} + +var nullValue = &pb.Value{ValueType: &pb.Value_NullValue{}} + +func (e *encoder) EncodeNil() { e.pv = nullValue } +func (e *encoder) EncodeBool(x bool) { e.pv = &pb.Value{ValueType: &pb.Value_BooleanValue{x}} } +func (e *encoder) EncodeInt(x int64) { e.pv = &pb.Value{ValueType: &pb.Value_IntegerValue{x}} } +func (e *encoder) EncodeUint(x uint64) { e.pv = &pb.Value{ValueType: &pb.Value_IntegerValue{int64(x)}} } +func (e *encoder) EncodeBytes(x []byte) { e.pv = &pb.Value{ValueType: &pb.Value_BytesValue{x}} } +func (e *encoder) EncodeFloat(x float64) { e.pv = floatval(x) } +func (e *encoder) EncodeString(x string) { e.pv = &pb.Value{ValueType: &pb.Value_StringValue{x}} } + +func (e *encoder) ListIndex(int) { panic("impossible") } +func (e *encoder) MapKey(string) { panic("impossible") } + +func (e *encoder) EncodeList(n int) driver.Encoder { + s := make([]*pb.Value, n) + e.pv = &pb.Value{ValueType: &pb.Value_ArrayValue{&pb.ArrayValue{Values: s}}} + return &listEncoder{s: s} +} + +func (e *encoder) EncodeMap(n int) driver.Encoder { + m := make(map[string]*pb.Value, n) + e.pv = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: m}}} + return &mapEncoder{m: m} +} + +var ( + typeOfGoTime = reflect.TypeOf(time.Time{}) + typeOfProtoTimestamp = reflect.TypeOf((*tspb.Timestamp)(nil)) + typeOfLatLng = reflect.TypeOf((*latlng.LatLng)(nil)) +) + +// Encode time.Time, latlng.LatLng, and ts.Timestamp specially, because the Go Firestore +// client does. +func (e *encoder) EncodeSpecial(v reflect.Value) (bool, error) { + switch v.Type() { + case typeOfGoTime: + ts := tspb.New(v.Interface().(time.Time)) + e.pv = &pb.Value{ValueType: &pb.Value_TimestampValue{ts}} + return true, nil + case typeOfProtoTimestamp: + if v.IsNil() { + e.pv = nullValue + } else { + e.pv = &pb.Value{ValueType: &pb.Value_TimestampValue{v.Interface().(*tspb.Timestamp)}} + } + return true, nil + case typeOfLatLng: + if v.IsNil() { + e.pv = nullValue + } else { + e.pv = &pb.Value{ValueType: &pb.Value_GeoPointValue{v.Interface().(*latlng.LatLng)}} + } + return true, nil + default: + return false, nil + } +} + +type listEncoder struct { + s []*pb.Value + encoder +} + +func (e *listEncoder) ListIndex(i int) { e.s[i] = e.pv } + +type mapEncoder struct { + m map[string]*pb.Value + encoder +} + +func (e *mapEncoder) MapKey(k string) { e.m[k] = e.pv } + +func floatval(x float64) *pb.Value { return &pb.Value{ValueType: &pb.Value_DoubleValue{x}} } + +//////////////////////////////////////////////////////////////// + +// decodeDoc decodes a Firestore document into a driver.Document. +func decodeDoc(pdoc *pb.Document, ddoc driver.Document, nameField, revField string) error { + if pdoc.Fields == nil { + pdoc.Fields = map[string]*pb.Value{} + } + if nameField != "" { + pdoc.Fields[nameField] = &pb.Value{ValueType: &pb.Value_StringValue{StringValue: path.Base(pdoc.Name)}} + } + mv := &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: pdoc.Fields}}} + if err := ddoc.Decode(decoder{mv}); err != nil { + return err + } + // Set the revision field in the document, if it exists, to the update time. + if ddoc.HasField(revField) && pdoc.UpdateTime != nil { + return ddoc.SetField(revField, pdoc.UpdateTime) + } + return nil +} + +type decoder struct { + pv *pb.Value +} + +func (d decoder) String() string { // for debugging + return fmt.Sprint(d.pv) +} + +func (d decoder) AsNull() bool { + _, ok := d.pv.ValueType.(*pb.Value_NullValue) + return ok +} + +func (d decoder) AsBool() (bool, bool) { + if b, ok := d.pv.ValueType.(*pb.Value_BooleanValue); ok { + return b.BooleanValue, true + } + return false, false +} + +func (d decoder) AsString() (string, bool) { + if s, ok := d.pv.ValueType.(*pb.Value_StringValue); ok { + return s.StringValue, true + } + return "", false +} + +func (d decoder) AsInt() (int64, bool) { + if i, ok := d.pv.ValueType.(*pb.Value_IntegerValue); ok { + return i.IntegerValue, true + } + return 0, false +} + +func (d decoder) AsUint() (uint64, bool) { + if i, ok := d.pv.ValueType.(*pb.Value_IntegerValue); ok { + return uint64(i.IntegerValue), true + } + return 0, false +} + +func (d decoder) AsFloat() (float64, bool) { + if f, ok := d.pv.ValueType.(*pb.Value_DoubleValue); ok { + return f.DoubleValue, true + } + return 0, false +} + +func (d decoder) AsBytes() ([]byte, bool) { + if bs, ok := d.pv.ValueType.(*pb.Value_BytesValue); ok { + return bs.BytesValue, true + } + return nil, false +} + +// AsInterface decodes the value in d into the most appropriate Go type. +func (d decoder) AsInterface() (interface{}, error) { + return decodeValue(d.pv) +} + +func decodeValue(v *pb.Value) (interface{}, error) { + switch v := v.ValueType.(type) { + case *pb.Value_NullValue: + return nil, nil + case *pb.Value_BooleanValue: + return v.BooleanValue, nil + case *pb.Value_IntegerValue: + return v.IntegerValue, nil + case *pb.Value_DoubleValue: + return v.DoubleValue, nil + case *pb.Value_StringValue: + return v.StringValue, nil + case *pb.Value_BytesValue: + return v.BytesValue, nil + case *pb.Value_TimestampValue: + // Return TimestampValue as time.Time. + return v.TimestampValue.AsTime(), nil + case *pb.Value_ReferenceValue: + // TODO(jba): support references + return nil, errors.New("references are not currently supported") + case *pb.Value_GeoPointValue: + // Return GeoPointValue as *latlng.LatLng. + return v.GeoPointValue, nil + case *pb.Value_ArrayValue: + s := make([]interface{}, len(v.ArrayValue.Values)) + for i, pv := range v.ArrayValue.Values { + e, err := decodeValue(pv) + if err != nil { + return nil, err + } + s[i] = e + } + return s, nil + case *pb.Value_MapValue: + m := make(map[string]interface{}, len(v.MapValue.Fields)) + for k, pv := range v.MapValue.Fields { + e, err := decodeValue(pv) + if err != nil { + return nil, err + } + m[k] = e + } + return m, nil + } + return nil, fmt.Errorf("unknown firestore value type %T", v) +} + +func (d decoder) ListLen() (int, bool) { + a := d.pv.GetArrayValue() + if a == nil { + return 0, false + } + return len(a.Values), true +} + +func (d decoder) DecodeList(f func(int, driver.Decoder) bool) { + for i, e := range d.pv.GetArrayValue().Values { + if !f(i, decoder{e}) { + return + } + } +} + +func (d decoder) MapLen() (int, bool) { + m := d.pv.GetMapValue() + if m == nil { + return 0, false + } + return len(m.Fields), true +} + +func (d decoder) DecodeMap(f func(string, driver.Decoder, bool) bool) { + for k, v := range d.pv.GetMapValue().Fields { + if !f(k, decoder{v}, true) { + return + } + } +} + +func (d decoder) AsSpecial(v reflect.Value) (bool, interface{}, error) { + switch v.Type() { + case typeOfGoTime: + if ts, ok := d.pv.ValueType.(*pb.Value_TimestampValue); ok { + if ts.TimestampValue == nil { + return true, time.Time{}, nil + } + return true, ts.TimestampValue.AsTime(), nil + } + return true, nil, fmt.Errorf("expected TimestampValue for time.Time, got %+v", d.pv.ValueType) + case typeOfProtoTimestamp: + if ts, ok := d.pv.ValueType.(*pb.Value_TimestampValue); ok { + return true, ts.TimestampValue, nil + } + return true, nil, fmt.Errorf("expected TimestampValue for *ts.Timestamp, got %+v", d.pv.ValueType) + + case typeOfLatLng: + if ll, ok := d.pv.ValueType.(*pb.Value_GeoPointValue); ok { + return true, ll.GeoPointValue, nil + } + return true, nil, fmt.Errorf("expected GeoPointValue for *latlng.LatLng, got %+v", d.pv.ValueType) + + default: + return false, nil, nil + } +} diff --git a/go-cloud/docstore/gcpfirestore/codec_test.go b/go-cloud/docstore/gcpfirestore/codec_test.go new file mode 100644 index 000000000..457197182 --- /dev/null +++ b/go-cloud/docstore/gcpfirestore/codec_test.go @@ -0,0 +1,83 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcpfirestore + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" + "google.golang.org/genproto/googleapis/type/latlng" + tspb "google.golang.org/protobuf/types/known/timestamppb" +) + +// Test that special types round-trip. +// These aren't tested in the docstore-wide conformance tests. +func TestCodecSpecial(t *testing.T) { + const nameField = "Name" + + type S struct { + Name string + T time.Time + TS, TSn *tspb.Timestamp + LL, LLn *latlng.LatLng + } + tm := time.Date(2019, 3, 14, 0, 0, 0, 0, time.UTC) + ts := tspb.New(tm) + in := &S{ + Name: "name", + T: tm, + TS: ts, + TSn: nil, + LL: &latlng.LatLng{Latitude: 3, Longitude: 4}, + LLn: nil, + } + var got S + + enc, err := encodeDoc(drivertest.MustDocument(in), nameField) + if err != nil { + t.Fatal(err) + } + enc.Name = "collPath/" + in.Name + gotdoc := drivertest.MustDocument(&got) + // Test type-driven decoding (where the types of the struct fields are available). + if err := decodeDoc(enc, gotdoc, nameField, docstore.DefaultRevisionField); err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(&got, in, cmpopts.IgnoreUnexported(tspb.Timestamp{}, latlng.LatLng{})); diff != "" { + t.Error(diff) + } + + // Test type-blind decoding. + gotmap := map[string]interface{}{} + gotmapdoc := drivertest.MustDocument(gotmap) + if err := decodeDoc(enc, gotmapdoc, nameField, docstore.DefaultRevisionField); err != nil { + t.Fatal(err) + } + wantmap := map[string]interface{}{ + "Name": "name", + "T": in.T, + "TS": in.T, // timestamps always decode as time.Time + "TSn": nil, + "LL": in.LL, + "LLn": nil, + } + if diff := cmp.Diff(gotmap, wantmap, cmpopts.IgnoreUnexported(latlng.LatLng{})); diff != "" { + t.Error(diff) + } +} diff --git a/go-cloud/docstore/gcpfirestore/create_indexes.sh b/go-cloud/docstore/gcpfirestore/create_indexes.sh new file mode 100755 index 000000000..c542317ea --- /dev/null +++ b/go-cloud/docstore/gcpfirestore/create_indexes.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Creates the Firestore indexes needed for tests. +# Takes one argument: the GCP project ID. +# +# If an index already exists, this script will fail. To re-create the index, delete +# it from the UI at https://firebase.corp.google.com/project/$project_id/database/firestore/indexes. + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +# Except we want to keep going if there is a failure, and x is too verbose. +set -uo pipefail + +project_id="${1:-}" +if [[ -z "$project_id" ]]; then + echo "usage: create_indexes.sh PROJECT" 1>&2 + exit 64 +fi + +echo "Creating indexes for $project_id" +echo "UI at https://firebase.corp.google.com/project/$project_id/database/firestore/indexes" + +collection=docstore-test-2 + +function create_index() { + gcloud --project "$project_id" beta firestore indexes composite create --collection-group "$collection" \ + --field-config field-path=$1,order=$2 --field-config field-path=$3,order=$4 +} + +set -x + +create_index Player ascending Score ascending +create_index Game ascending Score ascending +create_index Player ascending Time ascending +create_index Game ascending Player ascending +create_index Game ascending Player descending diff --git a/go-cloud/docstore/gcpfirestore/example_test.go b/go-cloud/docstore/gcpfirestore/example_test.go new file mode 100644 index 000000000..9d070ee51 --- /dev/null +++ b/go-cloud/docstore/gcpfirestore/example_test.go @@ -0,0 +1,92 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcpfirestore_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/gcpfirestore" + "github.com/DataDog/iceberg-go/go-cloud/gcp" +) + +func ExampleOpenCollection() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + log.Fatal(err) + } + client, _, err := gcpfirestore.Dial(ctx, creds.TokenSource) + if err != nil { + log.Fatal(err) + } + resourceID := gcpfirestore.CollectionResourceID("my-project", "my-collection") + coll, err := gcpfirestore.OpenCollection(client, resourceID, "userID", nil) + if err != nil { + log.Fatal(err) + } + defer coll.Close() +} + +func ExampleOpenCollectionWithNameFunc() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + type HighScore struct { + Game string + Player string + } + + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + log.Fatal(err) + } + client, _, err := gcpfirestore.Dial(ctx, creds.TokenSource) + if err != nil { + log.Fatal(err) + } + + // The name of a document is constructed from the Game and Player fields. + nameFromDocument := func(doc docstore.Document) string { + hs := doc.(*HighScore) + return hs.Game + "|" + hs.Player + } + + resourceID := gcpfirestore.CollectionResourceID("my-project", "my-collection") + coll, err := gcpfirestore.OpenCollectionWithNameFunc(client, resourceID, nameFromDocument, nil) + if err != nil { + log.Fatal(err) + } + defer coll.Close() +} + +func Example_openCollectionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/docstore/gcpfirestore" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // docstore.OpenCollection creates a *docstore.Collection from a URL. + const url = "firestore://projects/my-project/databases/(default)/documents/my-collection?name_field=userID" + coll, err := docstore.OpenCollection(ctx, url) + if err != nil { + log.Fatal(err) + } + defer coll.Close() +} diff --git a/go-cloud/docstore/gcpfirestore/fs.go b/go-cloud/docstore/gcpfirestore/fs.go new file mode 100644 index 000000000..4981dc728 --- /dev/null +++ b/go-cloud/docstore/gcpfirestore/fs.go @@ -0,0 +1,838 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcpfirestore provides a docstore implementation backed by Google Cloud +// Firestore. +// Use OpenCollection to construct a *docstore.Collection. +// +// Docstore types not supported by the Go firestore client, cloud.google.com/go/firestore: +// - unsigned integers: encoded is int64s +// - arrays: encoded as Firestore array values +// +// Firestore types not supported by Docstore: +// - Document reference (a pointer to another Firestore document) +// +// # URLs +// +// For docstore.OpenCollection, gcpfirestore registers for the scheme +// "firestore". +// The default URL opener will create a connection using default credentials +// from the environment, as described in +// https://cloud.google.com/docs/authentication/production. +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// gcpfirestore exposes the following types for as functions. +// The pb package is google.golang.org/genproto/googleapis/firestore/v1. +// The firestore package is cloud.google.com/go/firestore/apiv1. +// - Collection.As: *firestore.Client +// - ActionList.BeforeDo: *pb.BatchGetDocumentsRequest or *pb.CommitRequest. +// - Query.BeforeQuery: *pb.RunQueryRequest +// - DocumentIterator: firestore.Firestore_RunQueryClient +// - Error: *google.golang.org/grpc/status.Status +// +// # Queries +// +// Firestore allows only one field in a query to be compared with an inequality +// operator (one other than "="). This driver selects the first field in a Where +// clause with an inequality to pass to Firestore and handles the rest locally. For +// example, if the query specifies the three clauses A > 1, B > 2 and A < 3, then +// A > 1 and A < 3 will be sent to Firestore, and the results will be filtered by +// B > 2 in this driver. +// +// Firestore requires a composite index if a query contains both an equality and an +// inequality comparison. This driver returns an error if the necessary index does +// not exist. You must create the index manually. See +// https://cloud.google.com/firestore/docs/query-data/indexing for details. +// +// See https://cloud.google.com/firestore/docs/query-data/queries for more information on Firestore queries. +package gcpfirestore // import "gocloud.dev/docstore/gcpfirestore" + +import ( + "bytes" + "context" + "fmt" + "io" + "os" + "reflect" + "regexp" + "strings" + + vkit "cloud.google.com/go/firestore/apiv1" + pb "cloud.google.com/go/firestore/apiv1/firestorepb" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/useragent" + "google.golang.org/api/option" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" + tspb "google.golang.org/protobuf/types/known/timestamppb" +) + +// Dial returns a client to use with Firestore and a clean-up function to close +// the client after used. +// If the 'FIRESTORE_EMULATOR_HOST' environment variable is set the client connects +// to the GCP firestore emulator by overriding the default endpoint. +func Dial(ctx context.Context, ts gcp.TokenSource) (*vkit.Client, func(), error) { + opts := []option.ClientOption{ + useragent.ClientOption("docstore"), + } + if host := os.Getenv("FIRESTORE_EMULATOR_HOST"); host != "" { + conn, err := grpc.DialContext(ctx, host, + grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + return nil, nil, err + } + opts = append(opts, + option.WithEndpoint(host), + option.WithGRPCConn(conn), + ) + } else { + opts = append(opts, option.WithTokenSource(ts)) + } + c, err := vkit.NewClient(ctx, opts...) + return c, func() { c.Close() }, err +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + Dial, + wire.Struct(new(URLOpener), "Client"), +) + +type collection struct { + nameField string + nameFunc func(docstore.Document) string + client *vkit.Client + dbPath string // e.g. "projects/P/databases/(default)" + collPath string // e.g. "projects/P/databases/(default)/documents/States/Wisconsin/cities" + opts *Options +} + +// Options contains optional arguments to the OpenCollection functions. +type Options struct { + // If true, allow queries that require client-side evaluation of filters (Where clauses) + // to run. + AllowLocalFilters bool + // The name of the field holding the document revision. + // Defaults to docstore.DefaultRevisionField. + RevisionField string + + // The maximum number of RPCs that can be in progress for a single call to + // ActionList.Do. + // If less than 1, there is no limit. + MaxOutstandingActionRPCs int +} + +// CollectionResourceID constructs a resource ID for a collection from the project ID and the collection path. +// See the OpenCollection example for use. +func CollectionResourceID(projectID, collPath string) string { + return fmt.Sprintf("projects/%s/databases/(default)/documents/%s", projectID, collPath) +} + +// CollectResoureceIDWithDatabase constructs a resource ID for a collection from the project ID, database ID, and the collection path. +// See the OpenCollection example for use. +func CollectionResourceIDWithDatabase(projectID, databaseID, collPath string) string { + return fmt.Sprintf("projects/%s/databases/%s/documents/%s", projectID, databaseID, collPath) +} + +// OpenCollection creates a *docstore.Collection representing a Firestore collection. +// +// collResourceID must be of the form "project//databases/(default)/documents/". +// may be a top-level collection, like "States", or it may be a path to a nested +// collection, like "States/Wisconsin/Cities". +// See https://cloud.google.com/firestore/docs/reference/rest/ for more detail. +// +// gcpfirestore requires that a single field, nameField, be designated the primary +// key. Its values must be strings, and must be unique over all documents in the +// collection. The primary key must be provided to retrieve a document. +func OpenCollection(client *vkit.Client, collResourceID, nameField string, opts *Options) (*docstore.Collection, error) { + c, err := newCollection(client, collResourceID, nameField, nil, opts) + if err != nil { + return nil, err + } + return docstore.NewCollection(c), nil +} + +// OpenCollectionWithNameFunc creates a *docstore.Collection representing a Firestore collection. +// +// collResourceID must be of the form "project//databases/(default)/documents/". +// may be a top-level collection, like "States", or it may be a path to a nested +// collection, like "States/Wisconsin/Cities". +// +// The nameFunc argument is function that accepts a document and returns the value to +// be used for the document's primary key. It should return the empty string if the +// document is missing the information to construct a name. This will cause all +// actions, even Create, to fail. +// +// Providing a function to construct the primary key is useful in two situations: if +// your desired primary key field is not a string, or if there is more than one field +// you want to use as a primary key. +// +// For the collection to be usable with Query.Delete and Query.Update, nameFunc +// must work with both map and struct types representing the same underlying +// data structure. See gocloud.dev/docstore/drivertest.HighScoreKey for an example. +func OpenCollectionWithNameFunc(client *vkit.Client, collResourceID string, nameFunc func(docstore.Document) string, opts *Options) (*docstore.Collection, error) { + c, err := newCollection(client, collResourceID, "", nameFunc, opts) + if err != nil { + return nil, err + } + return docstore.NewCollection(c), nil +} + +var resourceIDRE = regexp.MustCompile(`^(projects/[^/]+/databases/[^/]+)/documents/.+`) + +func newCollection(client *vkit.Client, collResourceID, nameField string, nameFunc func(docstore.Document) string, opts *Options) (*collection, error) { + if nameField == "" && nameFunc == nil { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "one of nameField or nameFunc must be provided") + } + matches := resourceIDRE.FindStringSubmatch(collResourceID) + if matches == nil { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "bad collection resource ID %q; must match %v", + collResourceID, resourceIDRE) + } + dbPath := matches[1] + if opts == nil { + opts = &Options{} + } + if opts.RevisionField == "" { + opts.RevisionField = docstore.DefaultRevisionField + } + return &collection{ + client: client, + nameField: nameField, + nameFunc: nameFunc, + dbPath: dbPath, + collPath: collResourceID, + opts: opts, + }, nil +} + +// Key returns the document key, if present. This is either the value of the field +// called c.nameField, or the result of calling c.nameFunc. +func (c *collection) Key(doc driver.Document) (interface{}, error) { + if c.nameField != "" { + name, err := doc.GetField(c.nameField) + vn := reflect.ValueOf(name) + if err != nil || name == nil || driver.IsEmptyValue(vn) { + // missing field is not an error + return nil, nil + } + // Check that the reflect kind is String so we can support any type whose underlying type + // is string. E.g. "type DocName string". + if vn.Kind() != reflect.String { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "key field %q with value %v is not a string", + c.nameField, name) + } + sname := vn.String() + if sname == "" { // empty string is the same as missing + return nil, nil + } + return sname, nil + } + sname := c.nameFunc(doc.Origin) + if sname == "" { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "missing document key") + } + return sname, nil +} + +func (c *collection) RevisionField() string { + return c.opts.RevisionField +} + +// RunActions implements driver.RunActions. +func (c *collection) RunActions(ctx context.Context, actions []*driver.Action, opts *driver.RunActionsOptions) driver.ActionListError { + errs := make([]error, len(actions)) + beforeGets, gets, writes, writesTx, afterGets := driver.GroupActions(actions) + calls := c.buildCommitCalls(writes, errs) + atomicWritesCall := c.buildAtomicWritesCommitCall(writesTx, errs) + // runGets does not issue concurrent RPCs, so it doesn't need a throttle. + c.runGets(ctx, beforeGets, errs, opts) + t := driver.NewThrottle(c.opts.MaxOutstandingActionRPCs) + for _, call := range calls { + call := call + t.Acquire() + go func() { + defer t.Release() + c.doCommitCall(ctx, call, errs, opts) + }() + } + // commit the atomic writes + if atomicWritesCall != nil && len(atomicWritesCall.actions) > 0 { + t.Acquire() + go func() { + defer t.Release() + c.doCommitCall(ctx, atomicWritesCall, errs, opts) + }() + } + + t.Acquire() + c.runGets(ctx, gets, errs, opts) + t.Release() + t.Wait() + c.runGets(ctx, afterGets, errs, opts) + return driver.NewActionListError(errs) +} + +// runGets executes a group of Get actions by calling the BatchGetDocuments RPC. +// It may make several calls, because all gets in a single RPC must have the same set of field paths. +func (c *collection) runGets(ctx context.Context, actions []*driver.Action, errs []error, opts *driver.RunActionsOptions) { + for _, group := range driver.GroupByFieldPath(actions) { + c.batchGet(ctx, group, errs, opts) + } +} + +// Run a single BatchGet RPC with the given Get actions, all of which have the same set of field paths. +// Populate errs, a slice of per-action errors indexed by the original action list position. +func (c *collection) batchGet(ctx context.Context, gets []*driver.Action, errs []error, opts *driver.RunActionsOptions) { + setErr := func(err error) { + for _, g := range gets { + errs[g.Index] = err + } + } + + req, err := c.newGetRequest(gets) + if err != nil { + setErr(err) + return + } + indexByPath := map[string]int{} // from document path to index in gets + for i, path := range req.Documents { + indexByPath[path] = i + } + if opts.BeforeDo != nil { + if err := opts.BeforeDo(driver.AsFunc(req)); err != nil { + setErr(err) + return + } + } + streamClient, err := c.client.BatchGetDocuments(withResourceHeader(ctx, req.Database), req) + if err != nil { + setErr(err) + return + } + for { + resp, err := streamClient.Recv() + if err == io.EOF { + break + } + if err != nil { + setErr(err) + return + } + switch r := resp.Result.(type) { + case *pb.BatchGetDocumentsResponse_Found: + pdoc := r.Found + i, ok := indexByPath[pdoc.Name] + if !ok { + setErr(gcerr.Newf(gcerr.Internal, nil, "no index for path %s", pdoc.Name)) + } else { + errs[gets[i].Index] = decodeDoc(pdoc, gets[i].Doc, c.nameField, c.opts.RevisionField) + } + case *pb.BatchGetDocumentsResponse_Missing: + i := indexByPath[r.Missing] + errs[gets[i].Index] = gcerr.Newf(gcerr.NotFound, nil, "document at path %q is missing", r.Missing) + default: + setErr(gcerr.Newf(gcerr.Internal, nil, "unknown BatchGetDocumentsResponse result type")) + return + } + } +} + +func (c *collection) newGetRequest(gets []*driver.Action) (*pb.BatchGetDocumentsRequest, error) { + req := &pb.BatchGetDocumentsRequest{Database: c.dbPath} + for _, a := range gets { + req.Documents = append(req.Documents, c.collPath+"/"+a.Key.(string)) + } + // groupActions has already made sure that all the actions have the same field paths, + // so just use the first one. + var fps []string // field paths that will go in the mask + for _, fp := range gets[0].FieldPaths { + fps = append(fps, toServiceFieldPath(fp)) + } + if fps != nil { + req.Mask = &pb.DocumentMask{FieldPaths: fps} + } + return req, nil +} + +// commitCall holds information needed to make a Commit RPC and to follow up after it is done. +type commitCall struct { + writes []*pb.Write // writes to commit + actions []*driver.Action // actions corresponding to those writes + newNames []string // new names for Create; parallel to actions +} + +// Construct a set of concurrently runnable calls to Commit. +func (c *collection) buildCommitCalls(actions []*driver.Action, errs []error) []*commitCall { + // Convert each action to one or more writes, collecting names for newly created + // documents along the way. Divide writes into those with preconditions and those without. + // Writes without preconditions can't fail, so we can execute them all in one Commit RPC. + // All other writes must be run as separate Commits. + var ( + nCall = &commitCall{} // for writes without preconditions + pCalls []*commitCall // for writes with preconditions + ) + for _, a := range actions { + ws, nn, err := c.actionToWrites(a) + if err != nil { + errs[a.Index] = err + } else if ws[0].CurrentDocument == nil { // no precondition + nCall.writes = append(nCall.writes, ws...) + nCall.actions = append(nCall.actions, a) + nCall.newNames = append(nCall.newNames, nn) + } else { // writes have a precondition + pCalls = append(pCalls, &commitCall{ + writes: ws, + actions: []*driver.Action{a}, + newNames: []string{nn}, + }) + } + } + if len(nCall.writes) == 0 { + return pCalls + } + return append(pCalls, nCall) +} + +// Construct a commit call with all the atomic writes +func (c *collection) buildAtomicWritesCommitCall(actions []*driver.Action, errs []error) *commitCall { + atomicWritesCommitCall := &commitCall{} + for _, a := range actions { + ws, nn, err := c.actionToWrites(a) + if err != nil { + errs[a.Index] = err + return nil + } else { + atomicWritesCommitCall.writes = append(atomicWritesCommitCall.writes, ws...) + atomicWritesCommitCall.actions = append(atomicWritesCommitCall.actions, a) + atomicWritesCommitCall.newNames = append(atomicWritesCommitCall.newNames, nn) + } + } + return atomicWritesCommitCall +} + +// Convert an action to one or more Firestore Write protos. +func (c *collection) actionToWrites(a *driver.Action) ([]*pb.Write, string, error) { + var ( + w *pb.Write + ws []*pb.Write + err error + docName string + newName string // for Create with no name + ) + if a.Key != nil { + docName = a.Key.(string) + } + switch a.Kind { + case driver.Create: + // Make a name for this document if it doesn't have one. + if a.Key == nil { + docName = driver.UniqueString() + newName = docName + } + w, err = c.putWrite(a.Doc, docName, &pb.Precondition{ConditionType: &pb.Precondition_Exists{Exists: false}}) + + case driver.Replace: + // If the given document has a revision, use it as the precondition (it implies existence). + pc, perr := c.revisionPrecondition(a.Doc) + if perr != nil { + return nil, "", perr + } + // Otherwise, just require that the document exists. + if pc == nil { + pc = &pb.Precondition{ConditionType: &pb.Precondition_Exists{Exists: true}} + } + w, err = c.putWrite(a.Doc, docName, pc) + + case driver.Put: + pc, perr := c.revisionPrecondition(a.Doc) + if perr != nil { + return nil, "", perr + } + w, err = c.putWrite(a.Doc, docName, pc) + + case driver.Update: + ws, err = c.updateWrites(a.Doc, docName, a.Mods) + + case driver.Delete: + w, err = c.deleteWrite(a.Doc, docName) + + default: + err = gcerr.Newf(gcerr.Internal, nil, "bad action %+v", a) + } + if err != nil { + return nil, "", err + } + if ws == nil { + ws = []*pb.Write{w} + } + return ws, newName, nil +} + +func (c *collection) putWrite(doc driver.Document, docName string, pc *pb.Precondition) (*pb.Write, error) { + pdoc, err := encodeDoc(doc, c.nameField) + if err != nil { + return nil, err + } + pdoc.Name = c.collPath + "/" + docName + return &pb.Write{ + Operation: &pb.Write_Update{Update: pdoc}, + CurrentDocument: pc, + }, nil +} + +func (c *collection) deleteWrite(doc driver.Document, docName string) (*pb.Write, error) { + pc, err := c.revisionPrecondition(doc) + if err != nil { + return nil, err + } + return &pb.Write{ + Operation: &pb.Write_Delete{Delete: c.collPath + "/" + docName}, + CurrentDocument: pc, + }, nil +} + +// updateWrites returns a slice of writes because we may need two: one for setting +// and deleting values, the other for transforms. +func (c *collection) updateWrites(doc driver.Document, docName string, mods []driver.Mod) ([]*pb.Write, error) { + ts, err := c.revisionTimestamp(doc) + if err != nil { + return nil, err + } + fields, paths, transforms, err := processMods(mods) + if err != nil { + return nil, err + } + return newUpdateWrites(c.collPath+"/"+docName, ts, fields, paths, transforms) +} + +func newUpdateWrites(docPath string, ts *tspb.Timestamp, fields map[string]*pb.Value, paths []string, transforms []*pb.DocumentTransform_FieldTransform) ([]*pb.Write, error) { + pc := preconditionFromTimestamp(ts) + // If there is no revision in the document, add a precondition that the document exists. + if pc == nil { + pc = &pb.Precondition{ConditionType: &pb.Precondition_Exists{Exists: true}} + } + var ws []*pb.Write + if len(fields) > 0 || len(paths) > 0 { + ws = []*pb.Write{{ + Operation: &pb.Write_Update{Update: &pb.Document{ + Name: docPath, + Fields: fields, + }}, + UpdateMask: &pb.DocumentMask{FieldPaths: paths}, + CurrentDocument: pc, + }} + pc = nil // If the precondition is in the write, we don't need it in the transform. + } + if len(transforms) > 0 { + ws = append(ws, &pb.Write{ + Operation: &pb.Write_Transform{ + Transform: &pb.DocumentTransform{ + Document: docPath, + FieldTransforms: transforms, + }, + }, + CurrentDocument: pc, + }) + } + return ws, nil +} + +// To update a document, we need to send: +// - A document with all the fields we want to add or change. +// - A mask with the field paths of all the fields we want to add, change or delete. +// processMods converts the mods into the fields for the document, and a list of +// valid Firestore field paths for the mask. +func processMods(mods []driver.Mod) (fields map[string]*pb.Value, maskPaths []string, transforms []*pb.DocumentTransform_FieldTransform, err error) { + fields = map[string]*pb.Value{} + for _, m := range mods { + sfp := toServiceFieldPath(m.FieldPath) + // If m.Value is nil, we want to delete it. In that case, we put the field in + // the mask but not in the doc. + if inc, ok := m.Value.(driver.IncOp); ok { + pv, err := encodeValue(inc.Amount) + if err != nil { + return nil, nil, nil, err + } + transforms = append(transforms, &pb.DocumentTransform_FieldTransform{ + FieldPath: sfp, + TransformType: &pb.DocumentTransform_FieldTransform_Increment{ + Increment: pv, + }, + }) + } else { + // The field path of every other mod belongs in the mask. + maskPaths = append(maskPaths, sfp) + if m.Value != nil { + pv, err := encodeValue(m.Value) + if err != nil { + return nil, nil, nil, err + } + if err := setAtFieldPath(fields, m.FieldPath, pv); err != nil { + return nil, nil, nil, err + } + } + } + } + return fields, maskPaths, transforms, nil +} + +// doCommitCall Calls the Commit RPC with a list of writes, and handles the results. +func (c *collection) doCommitCall(ctx context.Context, call *commitCall, errs []error, opts *driver.RunActionsOptions) { + wrs, err := c.commit(ctx, call.writes, opts) + if err != nil { + for _, a := range call.actions { + errs[a.Index] = err + } + return + } + // Set the revision fields of the documents. + // The actions and writes may not correspond, because Update actions may require + // two writes. We can tell which writes correspond to actions by the type of write. + j := 0 + for i, a := range call.actions { + wr := wrs[j] + if a.Doc.HasField(c.opts.RevisionField) { + if err := a.Doc.SetField(c.opts.RevisionField, wr.UpdateTime); err != nil { + errs[a.Index] = err + } + } + if call.newNames[i] != "" { + // c.nameField should not be empty since we only create new names when there + // is a nameField. + _ = a.Doc.SetField(c.nameField, call.newNames[i]) + } + if hasFollowingTransform(call.writes, j) { + j = j + 2 + } else { + j++ + } + } +} + +func hasFollowingTransform(writes []*pb.Write, i int) bool { + if i >= len(writes)-1 { + return false + } + curr, ok := writes[i].Operation.(*pb.Write_Update) + if !ok { + return false + } + next, ok := writes[i+1].Operation.(*pb.Write_Transform) + if !ok { + return false + } + return curr.Update.Name == next.Transform.Document +} + +func (c *collection) commit(ctx context.Context, ws []*pb.Write, opts *driver.RunActionsOptions) ([]*pb.WriteResult, error) { + req := &pb.CommitRequest{ + Database: c.dbPath, + Writes: ws, + } + if opts.BeforeDo != nil { + if err := opts.BeforeDo(driver.AsFunc(req)); err != nil { + return nil, err + } + } + res, err := c.client.Commit(withResourceHeader(ctx, req.Database), req) + if err != nil { + return nil, err + } + if len(res.WriteResults) != len(ws) { + return nil, gcerr.Newf(gcerr.Internal, nil, "wrong number of WriteResults from firestore commit") + } + return res.WriteResults, nil +} + +/////////////// +// From memdocstore/mem.go. + +// setAtFieldPath sets m's value at fp to val. It creates intermediate maps as +// needed. It returns an error if a non-final component of fp does not denote a map. +func setAtFieldPath(m map[string]*pb.Value, fp []string, val *pb.Value) error { + m2, err := getParentMap(m, fp, true) + if err != nil { + return err + } + m2[fp[len(fp)-1]] = val + return nil +} + +// getParentMap returns the map that directly contains the given field path; +// that is, the value of m at the field path that excludes the last component +// of fp. If a non-map is encountered along the way, an InvalidArgument error is +// returned. If nil is encountered, nil is returned unless create is true, in +// which case a map is added at that point. +func getParentMap(m map[string]*pb.Value, fp []string, create bool) (map[string]*pb.Value, error) { + for _, k := range fp[:len(fp)-1] { + if m[k] == nil { + if !create { + return nil, nil + } + m[k] = &pb.Value{ValueType: &pb.Value_MapValue{&pb.MapValue{Fields: map[string]*pb.Value{}}}} + } + mv := m[k].GetMapValue() + if mv == nil { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "invalid field path %q at %q", strings.Join(fp, "."), k) + } + m = mv.Fields + } + return m, nil +} + +//////////////// +// From fieldpath.go in cloud.google.com/go/firestore. + +// Convert a docstore field path, which is a []string, into the kind of field path +// that the Firestore service expects: a string of dot-separated components, some of +// which may be quoted. +func toServiceFieldPath(fp []string) string { + cs := make([]string, len(fp)) + for i, c := range fp { + cs[i] = toServiceFieldPathComponent(c) + } + return strings.Join(cs, ".") +} + +// Google SQL syntax for an unquoted field. +var unquotedFieldRE = regexp.MustCompile("^[A-Za-z_][A-Za-z_0-9]*$") + +// toServiceFieldPathComponent returns a string that represents key and is a valid +// Firestore field path component. Components must be quoted with backticks if +// they don't match the above regexp. +func toServiceFieldPathComponent(key string) string { + if unquotedFieldRE.MatchString(key) { + return key + } + var buf bytes.Buffer + buf.WriteRune('`') + for _, r := range key { + if r == '`' || r == '\\' { + buf.WriteRune('\\') + } + buf.WriteRune(r) + } + buf.WriteRune('`') + return buf.String() +} + +// revisionPrecondition returns a Firestore precondition that asserts that the stored document's +// revision matches the revision of doc. +func (c *collection) revisionPrecondition(doc driver.Document) (*pb.Precondition, error) { + rev, err := c.revisionTimestamp(doc) + if err != nil { + return nil, err + } + return preconditionFromTimestamp(rev), nil +} + +// revisionTimestamp extracts the timestamp from the revision field of doc, if there is one. +// It only returns an error if the revision field is present and does not contain the right type. +func (c *collection) revisionTimestamp(doc driver.Document) (*tspb.Timestamp, error) { + v, err := doc.GetField(c.opts.RevisionField) + if err != nil { // revision field not present + return nil, nil + } + if v == nil { // revision field is present, but nil + return nil, nil + } + rev, ok := v.(*tspb.Timestamp) + if !ok { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, + "%s field contains wrong type: got %T, want proto Timestamp", + c.opts.RevisionField, v) + } + return rev, nil +} + +func preconditionFromTimestamp(ts *tspb.Timestamp) *pb.Precondition { + if ts == nil || (ts.Seconds == 0 && ts.Nanos == 0) { // ignore a missing or zero revision + return nil + } + return &pb.Precondition{ConditionType: &pb.Precondition_UpdateTime{ts}} +} + +func (c *collection) ErrorCode(err error) gcerrors.ErrorCode { + return gcerr.GRPCCode(err) +} + +// resourcePrefixHeader is the name of the metadata header used to indicate +// the resource being operated on. +const resourcePrefixHeader = "google-cloud-resource-prefix" + +// withResourceHeader returns a new context that includes resource in a special header. +// Firestore uses the resource header for routing. +func withResourceHeader(ctx context.Context, resource string) context.Context { + md, _ := metadata.FromOutgoingContext(ctx) + md = md.Copy() + md[resourcePrefixHeader] = []string{resource} + return metadata.NewOutgoingContext(ctx, md) +} + +// RevisionToBytes implements driver.RevisionToBytes. +func (c *collection) RevisionToBytes(rev interface{}) ([]byte, error) { + r, ok := rev.(*tspb.Timestamp) + if !ok { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "revision %v of type %[1]T is not a proto Timestamp", rev) + } + return proto.Marshal(r) +} + +// BytesToRevision implements driver.BytesToRevision. +func (c *collection) BytesToRevision(b []byte) (interface{}, error) { + var ts tspb.Timestamp + if err := proto.Unmarshal(b, &ts); err != nil { + return nil, err + } + return &ts, nil +} + +func (c *collection) As(i interface{}) bool { + p, ok := i.(**vkit.Client) + if !ok { + return false + } + *p = c.client + return true +} + +// ErrorAs implements driver.Collection.ErrorAs. +func (c *collection) ErrorAs(err error, i interface{}) bool { + s, ok := status.FromError(err) + if !ok { + return false + } + p, ok := i.(**status.Status) + if !ok { + return false + } + *p = s + return true +} + +// Close implements driver.Collection.Close. +func (c *collection) Close() error { return nil } diff --git a/go-cloud/docstore/gcpfirestore/fs_test.go b/go-cloud/docstore/gcpfirestore/fs_test.go new file mode 100644 index 000000000..c48c5055c --- /dev/null +++ b/go-cloud/docstore/gcpfirestore/fs_test.go @@ -0,0 +1,212 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcpfirestore + +import ( + "context" + "errors" + "testing" + + vkit "cloud.google.com/go/firestore/apiv1" + pb "cloud.google.com/go/firestore/apiv1/firestorepb" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "google.golang.org/api/option" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" + tspb "google.golang.org/protobuf/types/known/timestamppb" +) + +const ( + // projectID is the project ID that was used during the last test run using --record. + projectID = "go-cloud-test-216917" + collectionName1 = "docstore-test-1" + collectionName2 = "docstore-test-2" + collectionName3 = "docstore-test-3" + endPoint = "firestore.googleapis.com:443" +) + +type harness struct { + client *vkit.Client + done func() +} + +func (h *harness) SupportsAtomicWrites() bool { + return true +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + conn, done := setup.NewGCPgRPCConn(ctx, t, endPoint, "docstore") + client, err := vkit.NewClient(ctx, option.WithGRPCConn(conn)) + if err != nil { + done() + return nil, err + } + return &harness{client, done}, nil +} + +func (h *harness) MakeCollection(_ context.Context, kind drivertest.CollectionKind) (driver.Collection, error) { + switch kind { + case drivertest.SingleKey, drivertest.NoRev: + return newCollection(h.client, CollectionResourceID(projectID, collectionName1), drivertest.KeyField, nil, nil) + case drivertest.TwoKey: + return newCollection(h.client, CollectionResourceID(projectID, collectionName2), "", + func(doc docstore.Document) string { + return drivertest.HighScoreKey(doc).(string) + }, &Options{AllowLocalFilters: true}) + case drivertest.AltRev: + return newCollection(h.client, CollectionResourceID(projectID, collectionName1), drivertest.KeyField, nil, + &Options{RevisionField: drivertest.AlternateRevisionField}) + default: + panic("bad kind") + } +} + +func (*harness) BeforeDoTypes() []interface{} { + return []interface{}{&pb.BatchGetDocumentsRequest{}, &pb.CommitRequest{}} +} + +func (*harness) BeforeQueryTypes() []interface{} { + return []interface{}{&pb.RunQueryRequest{}} +} + +func (*harness) RevisionsEqual(rev1, rev2 interface{}) bool { + return proto.Equal(rev1.(*tspb.Timestamp), rev2.(*tspb.Timestamp)) +} + +func (h *harness) Close() { + _ = h.client.Close() + h.done() +} + +// codecTester implements drivertest.CodecTester. +type codecTester struct { + nc *nativeCodec +} + +func (*codecTester) UnsupportedTypes() []drivertest.UnsupportedType { + return []drivertest.UnsupportedType{drivertest.Uint, drivertest.Arrays} +} + +func (c *codecTester) NativeEncode(x interface{}) (interface{}, error) { + return c.nc.Encode(x) +} + +func (c *codecTester) NativeDecode(value, dest interface{}) error { + return c.nc.Decode(value.(*pb.Document), dest) +} + +func (c *codecTester) DocstoreEncode(x interface{}) (interface{}, error) { + var e encoder + if err := drivertest.MustDocument(x).Encode(&e); err != nil { + return nil, err + } + return &pb.Document{ + Name: "projects/P/databases/(default)/documents/C/D", + Fields: e.pv.GetMapValue().Fields, + }, nil +} + +func (c *codecTester) DocstoreDecode(value, dest interface{}) error { + mv := &pb.Value{ValueType: &pb.Value_MapValue{MapValue: &pb.MapValue{ + Fields: value.(*pb.Document).Fields, + }}} + return drivertest.MustDocument(dest).Decode(decoder{mv}) +} + +type verifyAs struct{} + +func (verifyAs) Name() string { + return "verify As" +} + +func (verifyAs) CollectionCheck(coll *docstore.Collection) error { + var fc *vkit.Client + if !coll.As(&fc) { + return errors.New("Collection.As failed") + } + return nil +} + +func (verifyAs) QueryCheck(it *docstore.DocumentIterator) error { + var c pb.Firestore_RunQueryClient + if !it.As(&c) { + return errors.New("DocumentIterator.As failed") + } + _, err := c.Header() + return err +} + +func (v verifyAs) ErrorCheck(c *docstore.Collection, err error) error { + var s *status.Status + if !c.ErrorAs(err, &s) { + return errors.New("Collection.ErrorAs failed") + } + return nil +} + +func TestConformance(t *testing.T) { + drivertest.MakeUniqueStringDeterministicForTesting(1) + nc, err := newNativeCodec() + if err != nil { + t.Fatal(err) + } + drivertest.RunConformanceTests(t, newHarness, &codecTester{nc}, []drivertest.AsTest{verifyAs{}}) +} + +func BenchmarkConformance(b *testing.B) { + ctx := context.Background() + client, err := vkit.NewClient(ctx) + if err != nil { + b.Fatal(err) + } + coll, err := newCollection(client, CollectionResourceID(projectID, collectionName3), drivertest.KeyField, nil, nil) + if err != nil { + b.Fatal(err) + } + drivertest.RunBenchmarks(b, docstore.NewCollection(coll)) +} + +// gcpfirestore-specific tests. + +func TestResourceIDRegexp(t *testing.T) { + for _, good := range []string{ + "projects/abc-_.309/databases/(default)/documents/C", + "projects/P/databases/(default)/documents/C/D/E", + "projects/P/databases/mydb/documents/E/F/G", + } { + if !resourceIDRE.MatchString(good) { + t.Errorf("%q did not match but should have", good) + } + } + + for _, bad := range []string{ + "", + "Projects/P/databases/(default)/documents/C", + "P/databases/(default)/documents/C", + "projects/P/Q/databases/(default)/documents/C", + "projects/P/databases/(default)/C", + "projects/P/databases/(default)/documents/", + "projects/P/databases/(default)", + } { + if resourceIDRE.MatchString(bad) { + t.Errorf("%q matched but should not have", bad) + } + } +} diff --git a/go-cloud/docstore/gcpfirestore/native_codec_test.go b/go-cloud/docstore/gcpfirestore/native_codec_test.go new file mode 100644 index 000000000..daa9f8651 --- /dev/null +++ b/go-cloud/docstore/gcpfirestore/native_codec_test.go @@ -0,0 +1,151 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcpfirestore + +import ( + "context" + "io" + "net" + "testing" + + "cloud.google.com/go/firestore" + pb "cloud.google.com/go/firestore/apiv1/firestorepb" + "github.com/google/go-cmp/cmp" + "google.golang.org/api/option" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/metadata" + tspb "google.golang.org/protobuf/types/known/timestamppb" +) + +// A nativeCodec encodes and decodes structs using the cloud.google.com/go/firestore +// client. Since that package doesn't export its codec, we have to go behind the +// scenes and intercept traffic at the gRPC level. We use interceptors to do that. (A +// mock server would have worked too.) +type nativeCodec struct { + client *firestore.Client + doc *pb.Document +} + +func newNativeCodec() (*nativeCodec, error) { + // Establish a gRPC server, just so we have a connection to hang the interceptors on. + srv := grpc.NewServer() + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + return nil, err + } + go func() { + if err := srv.Serve(l); err != nil { + panic(err) // we should never get an error because we just connect and stop + } + }() + nc := &nativeCodec{} + + conn, err := grpc.Dial(l.Addr().String(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithBlock(), + grpc.WithUnaryInterceptor(nc.interceptUnary), + grpc.WithStreamInterceptor(nc.interceptStream)) + if err != nil { + return nil, err + } + conn.Close() + srv.Stop() + nc.client, err = firestore.NewClient(context.Background(), "P", option.WithGRPCConn(conn)) + if err != nil { + return nil, err + } + return nc, nil +} + +// Intercept all unary (non-streaming) RPCs. The only one we should ever get is a Commit, for +// the Create call in Encode. +// If this completes successfully, the encoded *pb.Document will be in c.doc. +func (c *nativeCodec) interceptUnary(_ context.Context, method string, req, res interface{}, _ *grpc.ClientConn, _ grpc.UnaryInvoker, _ ...grpc.CallOption) error { + c.doc = req.(*pb.CommitRequest).Writes[0].GetUpdate() + res.(*pb.CommitResponse).WriteResults = []*pb.WriteResult{{}} + return nil +} + +// Intercept all streaming RPCs. The only one we should ever get is a BatchGet, for the Get +// call in Decode. +// Before this is called, c.doc must be set to the *pb.Document to be returned from the call. +func (c *nativeCodec) interceptStream(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) { + return &clientStream{ctx: ctx, doc: c.doc}, nil +} + +// clientStream is a fake client stream. It returns a single document, then terminates. +type clientStream struct { + ctx context.Context + doc *pb.Document +} + +func (cs *clientStream) RecvMsg(m interface{}) error { + if cs.doc != nil { + cs.doc.CreateTime = &tspb.Timestamp{} + cs.doc.UpdateTime = &tspb.Timestamp{} + m.(*pb.BatchGetDocumentsResponse).Result = &pb.BatchGetDocumentsResponse_Found{Found: cs.doc} + cs.doc = nil + return nil + } + return io.EOF +} + +func (cs *clientStream) Context() context.Context { return cs.ctx } +func (cs *clientStream) SendMsg(m interface{}) error { return nil } +func (cs *clientStream) Header() (metadata.MD, error) { return nil, nil } +func (cs *clientStream) Trailer() metadata.MD { return nil } +func (cs *clientStream) CloseSend() error { return nil } + +// Encode a Go value into a Firestore proto document. +func (c *nativeCodec) Encode(x interface{}) (*pb.Document, error) { + _, err := c.client.Collection("C").Doc("D").Create(context.Background(), x) + if err != nil { + return nil, err + } + return c.doc, nil +} + +// Decode value, which must be a *pb.Document, into dest. +func (c *nativeCodec) Decode(value *pb.Document, dest interface{}) error { + c.doc = value + docsnap, err := c.client.Collection("C").Doc("D").Get(context.Background()) + if err != nil { + return err + } + return docsnap.DataTo(dest) +} + +func TestNativeCodec(t *testing.T) { + nc, err := newNativeCodec() + if err != nil { + t.Fatal(err) + } + type S struct { + A int + } + want := S{3} + fields, err := nc.Encode(&want) + if err != nil { + t.Fatal(err) + } + var got S + if err := nc.Decode(fields, &got); err != nil { + t.Fatal(err) + } + if !cmp.Equal(got, want) { + t.Errorf("got %+v, want %+v", got, want) + } +} diff --git a/go-cloud/docstore/gcpfirestore/query.go b/go-cloud/docstore/gcpfirestore/query.go new file mode 100644 index 000000000..09d7481d8 --- /dev/null +++ b/go-cloud/docstore/gcpfirestore/query.go @@ -0,0 +1,388 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// TODO(jba): figure out how to get filters with uints to work: since they are represented as +// int64s, the sign is wrong. + +package gcpfirestore + +import ( + "context" + "fmt" + "math" + "path" + "reflect" + "strings" + "time" + + pb "cloud.google.com/go/firestore/apiv1/firestorepb" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "google.golang.org/protobuf/types/known/wrapperspb" +) + +func (c *collection) RunGetQuery(ctx context.Context, q *driver.Query) (driver.DocumentIterator, error) { + return c.newDocIterator(ctx, q) +} + +func (c *collection) newDocIterator(ctx context.Context, q *driver.Query) (*docIterator, error) { + sq, localFilters, err := c.queryToProto(q) + if err != nil { + return nil, err + } + req := &pb.RunQueryRequest{ + Parent: path.Dir(c.collPath), + QueryType: &pb.RunQueryRequest_StructuredQuery{sq}, + } + if q.BeforeQuery != nil { + if err := q.BeforeQuery(driver.AsFunc(req)); err != nil { + return nil, err + } + } + ctx, cancel := context.WithCancel(ctx) + sc, err := c.client.RunQuery(withResourceHeader(ctx, c.dbPath), req) + if err != nil { + cancel() + return nil, err + } + return &docIterator{ + streamClient: sc, + nameField: c.nameField, + revField: c.opts.RevisionField, + localFilters: localFilters, + cancel: cancel, + }, nil +} + +// ////////////////////////////////////////////////////////////// +// The code below is adapted from cloud.google.com/go/firestore. + +type docIterator struct { + streamClient pb.Firestore_RunQueryClient + nameField, revField string + localFilters []driver.Filter + // We call cancel to make sure the stream client doesn't leak resources. + // We don't need to call it if Recv() returns a non-nil error. + // See https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. + cancel func() +} + +func (it *docIterator) Next(ctx context.Context, doc driver.Document) error { + res, err := it.nextResponse(ctx) + if err != nil { + return err + } + return decodeDoc(res.Document, doc, it.nameField, it.revField) +} + +func (it *docIterator) nextResponse(ctx context.Context) (*pb.RunQueryResponse, error) { + for { + res, err := it.streamClient.Recv() + if err != nil { + return nil, err + } + // No document => partial progress; keep receiving. + if res.Document == nil { + continue + } + match, err := it.evaluateLocalFilters(res.Document) + if err != nil { + return nil, err + } + if match { + return res, nil + } + } +} + +// Report whether the filters are true of the document. +func (it *docIterator) evaluateLocalFilters(pdoc *pb.Document) (bool, error) { + if len(it.localFilters) == 0 { + return true, nil + } + // TODO(jba): optimization: evaluate the filter directly on the proto document, without decoding. + m := map[string]interface{}{} + doc, err := driver.NewDocument(m) + if err != nil { + return false, err + } + if err := decodeDoc(pdoc, doc, it.nameField, it.revField); err != nil { + return false, err + } + for _, f := range it.localFilters { + if !evaluateFilter(f, doc) { + return false, nil + } + } + return true, nil +} + +func evaluateFilter(f driver.Filter, doc driver.Document) bool { + val, err := doc.Get(f.FieldPath) + if err != nil { + // Treat a missing field as false. + return false + } + // Compare times. + if t1, ok := val.(time.Time); ok { + if t2, ok := f.Value.(time.Time); ok { + return applyComparison(f.Op, driver.CompareTimes(t1, t2)) + } + return false + } + lhs := reflect.ValueOf(val) + rhs := reflect.ValueOf(f.Value) + if lhs.Kind() == reflect.String { + if rhs.Kind() != reflect.String { + return false + } + return applyComparison(f.Op, strings.Compare(lhs.String(), rhs.String())) + } + + if lhs.Kind() == reflect.Bool { + if rhs.Kind() != reflect.Bool { + return false + } + cmp := 0 + if lhs.Bool() != rhs.Bool() { + cmp = -1 + } + return applyComparison(f.Op, cmp) + } + + cmp, err := driver.CompareNumbers(lhs, rhs) + if err != nil { + return false + } + return applyComparison(f.Op, cmp) +} + +// op is one of the five permitted docstore operators ("=", "<", etc.) +// c is the result of strings.Compare or the like. +func applyComparison(op string, c int) bool { + switch op { + case driver.EqualOp: + return c == 0 + case ">": + return c > 0 + case "<": + return c < 0 + case ">=": + return c >= 0 + case "<=": + return c <= 0 + default: + panic("bad op") + } +} + +func (it *docIterator) Stop() { it.cancel() } + +func (it *docIterator) As(i interface{}) bool { + p, ok := i.(*pb.Firestore_RunQueryClient) + if !ok { + return false + } + *p = it.streamClient + return true +} + +// Converts the query to a Firestore proto. Also returns filters that need to be +// evaluated on the client. +func (c *collection) queryToProto(q *driver.Query) (*pb.StructuredQuery, []driver.Filter, error) { + // The collection ID is the last component of the collection path. + collID := path.Base(c.collPath) + p := &pb.StructuredQuery{ + From: []*pb.StructuredQuery_CollectionSelector{{CollectionId: collID}}, + } + if len(q.FieldPaths) > 0 { + p.Select = &pb.StructuredQuery_Projection{} + for _, fp := range q.FieldPaths { + p.Select.Fields = append(p.Select.Fields, fieldRef(fp)) + } + } + // Apply offset. + if q.Offset > 0 { + p.Offset = int32(q.Offset) + } + // Apply limit. + if q.Limit > 0 { + p.Limit = &wrapperspb.Int32Value{Value: int32(q.Limit)} + } + + // TODO(jba): make sure we retrieve the fields needed for local filters. + sendFilters, localFilters := splitFilters(q.Filters) + if len(localFilters) > 0 && !c.opts.AllowLocalFilters { + return nil, nil, gcerr.Newf(gcerr.InvalidArgument, nil, "query requires local filters; set Options.AllowLocalFilters to true to enable") + } + + // If there is only one filter, use it directly. Otherwise, construct + // a CompositeFilter. + var pfs []*pb.StructuredQuery_Filter + for _, f := range sendFilters { + pf, err := c.filterToProto(f) + if err != nil { + return nil, nil, err + } + pfs = append(pfs, pf) + } + if len(pfs) == 1 { + p.Where = pfs[0] + } else if len(pfs) > 1 { + p.Where = &pb.StructuredQuery_Filter{ + FilterType: &pb.StructuredQuery_Filter_CompositeFilter{&pb.StructuredQuery_CompositeFilter{ + Op: pb.StructuredQuery_CompositeFilter_AND, + Filters: pfs, + }}, + } + } + + if q.OrderByField != "" { + // TODO(jba): reorder filters so order-by one is first of inequalities? + // TODO(jba): see if it's OK if filter inequality direction differs from sort direction. + fref := []string{q.OrderByField} + if q.OrderByField == c.nameField { + fref[0] = "__name__" + } + var dir pb.StructuredQuery_Direction + if q.OrderAscending { + dir = pb.StructuredQuery_ASCENDING + } else { + dir = pb.StructuredQuery_DESCENDING + } + p.OrderBy = []*pb.StructuredQuery_Order{{Field: fieldRef(fref), Direction: dir}} + } + + // TODO(jba): cursors (start/end) + return p, localFilters, nil +} + +// splitFilters separates the list of query filters into those we can send to the Firestore service, +// and those we must evaluate here on the client. +func splitFilters(fs []driver.Filter) (sendToFirestore, evaluateLocally []driver.Filter) { + // Enforce that only one field can have an inequality. + var rangeFP []string + for _, f := range fs { + if f.Op == driver.EqualOp { + sendToFirestore = append(sendToFirestore, f) + } else { + if rangeFP == nil || driver.FieldPathsEqual(rangeFP, f.FieldPath) { + // Multiple inequality filters on the same field are OK. + rangeFP = f.FieldPath + sendToFirestore = append(sendToFirestore, f) + } else { + evaluateLocally = append(evaluateLocally, f) + } + } + } + return sendToFirestore, evaluateLocally +} + +func (c *collection) filterToProto(f driver.Filter) (*pb.StructuredQuery_Filter, error) { + // Treat filters on the name field specially. + if c.nameField != "" && driver.FieldPathEqualsField(f.FieldPath, c.nameField) { + v := reflect.ValueOf(f.Value) + if v.Kind() != reflect.String { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, + "name field filter value %v of type %[1]T is not a string", f.Value) + } + return newFieldFilter([]string{"__name__"}, f.Op, + &pb.Value{ValueType: &pb.Value_ReferenceValue{c.collPath + "/" + v.String()}}) + } + // "= nil" and "= NaN" are handled specially. + if uop, ok := unaryOpFor(f.Value); ok { + if f.Op != driver.EqualOp { + return nil, fmt.Errorf("firestore: must use '=' when comparing %v", f.Value) + } + return &pb.StructuredQuery_Filter{ + FilterType: &pb.StructuredQuery_Filter_UnaryFilter{ + UnaryFilter: &pb.StructuredQuery_UnaryFilter{ + OperandType: &pb.StructuredQuery_UnaryFilter_Field{ + Field: fieldRef(f.FieldPath), + }, + Op: uop, + }, + }, + }, nil + } + pv, err := encodeValue(f.Value) + if err != nil { + return nil, err + } + return newFieldFilter(f.FieldPath, f.Op, pv) +} + +func unaryOpFor(value interface{}) (pb.StructuredQuery_UnaryFilter_Operator, bool) { + switch { + case value == nil: + return pb.StructuredQuery_UnaryFilter_IS_NULL, true + case isNaN(value): + return pb.StructuredQuery_UnaryFilter_IS_NAN, true + default: + return pb.StructuredQuery_UnaryFilter_OPERATOR_UNSPECIFIED, false + } +} + +func isNaN(x interface{}) bool { + switch x := x.(type) { + case float32: + return math.IsNaN(float64(x)) + case float64: + return math.IsNaN(x) + default: + return false + } +} + +func fieldRef(fp []string) *pb.StructuredQuery_FieldReference { + return &pb.StructuredQuery_FieldReference{FieldPath: toServiceFieldPath(fp)} +} + +func newFieldFilter(fp []string, op string, val *pb.Value) (*pb.StructuredQuery_Filter, error) { + var fop pb.StructuredQuery_FieldFilter_Operator + switch op { + case "<": + fop = pb.StructuredQuery_FieldFilter_LESS_THAN + case "<=": + fop = pb.StructuredQuery_FieldFilter_LESS_THAN_OR_EQUAL + case ">": + fop = pb.StructuredQuery_FieldFilter_GREATER_THAN + case ">=": + fop = pb.StructuredQuery_FieldFilter_GREATER_THAN_OR_EQUAL + case driver.EqualOp: + fop = pb.StructuredQuery_FieldFilter_EQUAL + case "in": + fop = pb.StructuredQuery_FieldFilter_IN + case "not-in": + fop = pb.StructuredQuery_FieldFilter_NOT_IN + // TODO(jba): can we support array-contains portably? + // case "array-contains": + // fop = pb.StructuredQuery_FieldFilter_ARRAY_CONTAINS + default: + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "invalid operator: %q", op) + } + return &pb.StructuredQuery_Filter{ + FilterType: &pb.StructuredQuery_Filter_FieldFilter{ + FieldFilter: &pb.StructuredQuery_FieldFilter{ + Field: fieldRef(fp), + Op: fop, + Value: val, + }, + }, + }, nil +} + +func (c *collection) QueryPlan(q *driver.Query) (string, error) { + return "unknown", nil +} diff --git a/go-cloud/docstore/gcpfirestore/query_test.go b/go-cloud/docstore/gcpfirestore/query_test.go new file mode 100644 index 000000000..5325c409d --- /dev/null +++ b/go-cloud/docstore/gcpfirestore/query_test.go @@ -0,0 +1,200 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcpfirestore + +import ( + "math" + "testing" + "time" + + pb "cloud.google.com/go/firestore/apiv1/firestorepb" + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" + "google.golang.org/protobuf/proto" +) + +func TestFilterToProto(t *testing.T) { + c := &collection{nameField: "name", collPath: "collPath"} + for _, test := range []struct { + in driver.Filter + want *pb.StructuredQuery_Filter + }{ + { + driver.Filter{[]string{"a"}, ">", 1}, + &pb.StructuredQuery_Filter{FilterType: &pb.StructuredQuery_Filter_FieldFilter{ + FieldFilter: &pb.StructuredQuery_FieldFilter{ + Field: &pb.StructuredQuery_FieldReference{FieldPath: "a"}, + Op: pb.StructuredQuery_FieldFilter_GREATER_THAN, + Value: &pb.Value{ValueType: &pb.Value_IntegerValue{1}}, + }, + }}, + }, + { + driver.Filter{[]string{"a"}, driver.EqualOp, nil}, + &pb.StructuredQuery_Filter{FilterType: &pb.StructuredQuery_Filter_UnaryFilter{ + UnaryFilter: &pb.StructuredQuery_UnaryFilter{ + OperandType: &pb.StructuredQuery_UnaryFilter_Field{ + Field: &pb.StructuredQuery_FieldReference{FieldPath: "a"}, + }, + Op: pb.StructuredQuery_UnaryFilter_IS_NULL, + }, + }}, + }, + { + driver.Filter{[]string{"a"}, driver.EqualOp, math.NaN()}, + &pb.StructuredQuery_Filter{FilterType: &pb.StructuredQuery_Filter_UnaryFilter{ + UnaryFilter: &pb.StructuredQuery_UnaryFilter{ + OperandType: &pb.StructuredQuery_UnaryFilter_Field{ + Field: &pb.StructuredQuery_FieldReference{FieldPath: "a"}, + }, + Op: pb.StructuredQuery_UnaryFilter_IS_NAN, + }, + }}, + }, + { + driver.Filter{[]string{"name"}, "<", "foo"}, + &pb.StructuredQuery_Filter{FilterType: &pb.StructuredQuery_Filter_FieldFilter{ + FieldFilter: &pb.StructuredQuery_FieldFilter{ + Field: &pb.StructuredQuery_FieldReference{FieldPath: "__name__"}, + Op: pb.StructuredQuery_FieldFilter_LESS_THAN, + Value: &pb.Value{ValueType: &pb.Value_ReferenceValue{"collPath/foo"}}, + }, + }}, + }, + } { + got, err := c.filterToProto(test.in) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(got, test.want, cmp.Comparer(proto.Equal)); diff != "" { + t.Errorf("%+v: %s", test.in, diff) + } + } +} + +func TestSplitFilters(t *testing.T) { + aEqual := driver.Filter{[]string{"a"}, "=", 1} + aLess := driver.Filter{[]string{"a"}, "<", 1} + aGreater := driver.Filter{[]string{"a"}, ">", 1} + bEqual := driver.Filter{[]string{"b"}, "=", 1} + bLess := driver.Filter{[]string{"b"}, "<", 1} + + for _, test := range []struct { + in []driver.Filter + wantSend, wantLocal []driver.Filter + }{ + { + in: nil, + wantSend: nil, + wantLocal: nil, + }, + { + in: []driver.Filter{aEqual}, + wantSend: []driver.Filter{aEqual}, + wantLocal: nil, + }, + { + in: []driver.Filter{aLess}, + wantSend: []driver.Filter{aLess}, + wantLocal: nil, + }, + { + in: []driver.Filter{aLess, aGreater}, + wantSend: []driver.Filter{aLess, aGreater}, + wantLocal: nil, + }, + { + in: []driver.Filter{aLess, bEqual, aGreater}, + wantSend: []driver.Filter{aLess, bEqual, aGreater}, + wantLocal: nil, + }, + { + in: []driver.Filter{aLess, bLess, aGreater}, + wantSend: []driver.Filter{aLess, aGreater}, + wantLocal: []driver.Filter{bLess}, + }, + { + in: []driver.Filter{aEqual, aLess, bLess, aGreater, bEqual}, + wantSend: []driver.Filter{aEqual, aLess, aGreater, bEqual}, + wantLocal: []driver.Filter{bLess}, + }, + } { + gotSend, gotLocal := splitFilters(test.in) + if diff := cmp.Diff(gotSend, test.wantSend); diff != "" { + t.Errorf("%v, send:\n%s", test.in, diff) + } + if diff := cmp.Diff(gotLocal, test.wantLocal); diff != "" { + t.Errorf("%v, local:\n%s", test.in, diff) + } + } +} + +func TestEvaluateFilter(t *testing.T) { + m := map[string]interface{}{ + "i": 32, + "f": 5.5, + "f2": 5.0, + "s": "32", + "t": time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC), + "b": true, + "mi": int64(math.MaxInt64), + } + doc := drivertest.MustDocument(m) + for _, test := range []struct { + field, op string + value interface{} + want bool + }{ + // Firestore compares numbers to each other ignoring type (int vs. float). + // Just a few simple tests here; see driver.TestCompareNumbers for more. + {"i", "=", 32, true}, + {"i", ">", 32, false}, + {"i", "<", 32, false}, + {"i", "=", 32.0, true}, + {"i", ">", 32.0, false}, + {"i", "<", 32.0, false}, + {"f", "=", 5.5, true}, + {"f", "<", 5.5, false}, + {"f2", "=", 5, true}, + {"f2", ">", 5, false}, + // Firestore compares strings to each other, but not to numbers. + {"s", "=", "32", true}, + {"s", ">", "32", false}, + {"s", "<", "32", false}, + {"s", ">", "3", true}, + {"i", "=", "32", false}, + {"i", ">", "32", false}, + {"i", "<", "32", false}, + {"f", "=", "5.5", false}, + {"f", ">", "5.5", false}, + {"f", "<", "5.5", false}, + // Firestore compares times to each other. + {"t", "<", time.Date(2014, 1, 1, 0, 0, 0, 0, time.UTC), true}, + // Comparisons with other types fail. + {"b", "=", "true", false}, + {"b", ">", "true", false}, + {"b", "<", "true", false}, + {"t", "=", 0, false}, + {"t", ">", 0, false}, + {"t", "<", 0, false}, + } { + f := driver.Filter{FieldPath: []string{test.field}, Op: test.op, Value: test.value} + got := evaluateFilter(f, doc) + if got != test.want { + t.Errorf("%s %s %v: got %t, want %t", test.field, test.op, test.value, got, test.want) + } + } +} diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/ActionsOnStructNoRev.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/ActionsOnStructNoRev.replay new file mode 100644 index 000000000..422647220 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/ActionsOnStructNoRev.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/ActionsWithCompositeID.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/ActionsWithCompositeID.replay new file mode 100644 index 000000000..f25993394 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/ActionsWithCompositeID.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/As/verify_As.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/As/verify_As.replay new file mode 100644 index 000000000..9e2c5788b Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/As/verify_As.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..03f8f2a76 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/As/verify_As_returns_false_when_passed_nil.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/AtomicWrites.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/AtomicWrites.replay new file mode 100644 index 000000000..70e8df764 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/AtomicWrites.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/AtomicWritesFail.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/AtomicWritesFail.replay new file mode 100644 index 000000000..bf62f3e65 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/AtomicWritesFail.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/BeforeDo.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/BeforeDo.replay new file mode 100644 index 000000000..d2e9061b5 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/BeforeDo.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/BeforeQuery.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/BeforeQuery.replay new file mode 100644 index 000000000..ab5822f0c Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/BeforeQuery.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Create.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Create.replay new file mode 100644 index 000000000..78c10e3cd Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Create.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Data.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Data.replay new file mode 100644 index 000000000..39fba5227 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Data.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Delete.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Delete.replay new file mode 100644 index 000000000..f7c8f99f2 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Delete.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/ExampleInDoc.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/ExampleInDoc.replay new file mode 100644 index 000000000..02f1c9789 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/ExampleInDoc.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Get.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Get.replay new file mode 100644 index 000000000..931663497 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Get.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/GetQuery.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/GetQuery.replay new file mode 100644 index 000000000..e2317c86c Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/GetQuery.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/GetQueryKeyField.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/GetQueryKeyField.replay new file mode 100644 index 000000000..c4bfb7dda Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/GetQueryKeyField.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/MultipleActions.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/MultipleActions.replay new file mode 100644 index 000000000..834af39b4 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/MultipleActions.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Proto.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Proto.replay new file mode 100644 index 000000000..2e378cf19 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Proto.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Put.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Put.replay new file mode 100644 index 000000000..6eb59038b Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Put.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Query.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Query.replay new file mode 100644 index 000000000..0b949f956 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Query.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Replace.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Replace.replay new file mode 100644 index 000000000..990927e99 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Replace.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/SerializeRevision.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/SerializeRevision.replay new file mode 100644 index 000000000..622984dfe Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/SerializeRevision.replay differ diff --git a/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Update.replay b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Update.replay new file mode 100644 index 000000000..5222f0f99 Binary files /dev/null and b/go-cloud/docstore/gcpfirestore/testdata/TestConformance/Update.replay differ diff --git a/go-cloud/docstore/gcpfirestore/urls.go b/go-cloud/docstore/gcpfirestore/urls.go new file mode 100644 index 000000000..9812464d0 --- /dev/null +++ b/go-cloud/docstore/gcpfirestore/urls.go @@ -0,0 +1,106 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcpfirestore + +import ( + "context" + "errors" + "fmt" + "net/url" + "os" + "path" + "sync" + + vkit "cloud.google.com/go/firestore/apiv1" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/gcp" +) + +func init() { + docstore.DefaultURLMux().RegisterCollection(Scheme, &lazyCredsOpener{}) +} + +type lazyCredsOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazyCredsOpener) OpenCollectionURL(ctx context.Context, u *url.URL) (*docstore.Collection, error) { + o.init.Do(func() { + var tokenSource gcp.TokenSource + if e := os.Getenv("FIRESTORE_EMULATOR_HOST"); e == "" { + // Connect to the GCP default endpoint if the 'FIRESTORE_EMULATOR_HOST' environment variable is not set. + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + o.err = err + return + } + tokenSource = creds.TokenSource + } + client, _, err := Dial(ctx, tokenSource) + if err != nil { + o.err = err + return + } + o.opener = &URLOpener{Client: client} + }) + if o.err != nil { + return nil, fmt.Errorf("open collection %s: %v", u, o.err) + } + return o.opener.OpenCollectionURL(ctx, u) +} + +// Scheme is the URL scheme firestore registers its URLOpener under on +// docstore.DefaultMux. +const Scheme = "firestore" + +// URLOpener opens firestore URLs like +// "firestore://projects/myproject/databases/(default)/documents/mycollection?name_field=myID". +// +// See https://firebase.google.com/docs/firestore/data-model for more details. +// +// The following query parameters are supported: +// +// - name_field (required): gcpfirestore requires that a single string field, +// +// name_field, be designated the primary key. Its values must be unique over all +// documents in the collection, and the primary key must be provided to retrieve +// a document. +type URLOpener struct { + // Client must be set to a non-nil client authenticated with Cloud Firestore + // scope or equivalent. + Client *vkit.Client +} + +// OpenCollectionURL opens a docstore.Collection based on u. +func (o *URLOpener) OpenCollectionURL(ctx context.Context, u *url.URL) (*docstore.Collection, error) { + q := u.Query() + options := &Options{ + RevisionField: q.Get("revision_field"), + } + + nameField := q.Get("name_field") + if nameField == "" { + return nil, errors.New("open collection %s: name_field is required to open a collection") + } + q.Del("name_field") + q.Del("revision_field") + for param := range q { + return nil, fmt.Errorf("open collection %s: invalid query parameter %q", u, param) + } + collResourceID := path.Join(u.Host, u.Path) + return OpenCollection(o.Client, collResourceID, nameField, options) +} diff --git a/go-cloud/docstore/gcpfirestore/urls_test.go b/go-cloud/docstore/gcpfirestore/urls_test.go new file mode 100644 index 000000000..ae1d42386 --- /dev/null +++ b/go-cloud/docstore/gcpfirestore/urls_test.go @@ -0,0 +1,59 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcpfirestore + +import ( + "context" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" +) + +func TestOpenCollectionFromURL(t *testing.T) { + cleanup := setup.FakeGCPDefaultCredentials(t) + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"firestore://projects/myproject/databases/(default)/documents/mycoll?name_field=_id", false}, + // OK, hierarchical collection. + {"firestore://projects/myproject/databases/(default)/documents/mycoll/mydoc/subcoll?name_field=_id", false}, + // Missing project ID. + {"firestore:///mycoll?name_field=_id", true}, + // Empty collection. + {"firestore://projects/myproject/", true}, + // Missing name field. + {"firestore://projects/myproject/databases/(default)/documents/mycoll", true}, + // Passing revision field. + {"firestore://projects/myproject/databases/(default)/documents/mycoll?name_field=_id&revision_field=123", false}, + // Invalid param. + {"firestore://projects/myproject/databases/(default)/documents/mycoll?name_field=_id¶m=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + d, err := docstore.OpenCollection(ctx, test.URL) + if d != nil { + defer d.Close() + } + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + } +} diff --git a/go-cloud/docstore/internal/fields/README.md b/go-cloud/docstore/internal/fields/README.md new file mode 100644 index 000000000..bb1a31be4 --- /dev/null +++ b/go-cloud/docstore/internal/fields/README.md @@ -0,0 +1 @@ +This package is copied from cloud.google.com/go/internal/fields. diff --git a/go-cloud/docstore/internal/fields/fields.go b/go-cloud/docstore/internal/fields/fields.go new file mode 100644 index 000000000..7e6c196f9 --- /dev/null +++ b/go-cloud/docstore/internal/fields/fields.go @@ -0,0 +1,494 @@ +// Copyright 2019 The Go Cloud Development Kit 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 fields provides a view of the fields of a struct that follows the Go +// rules, amended to consider tags and case insensitivity. +// +// # Usage +// +// First define a function that interprets tags: +// +// func parseTag(st reflect.StructTag) (name string, keep bool, other interface{}, err error) { ... } +// +// The function's return values describe whether to ignore the field +// completely or provide an alternate name, as well as other data from the +// parse that is stored to avoid re-parsing. +// +// Then define a function to validate the type: +// +// func validate(t reflect.Type) error { ... } +// +// Then, if necessary, define a function to specify leaf types - types +// which should be considered one field and not be recursed into: +// +// func isLeafType(t reflect.Type) bool { ... } +// +// eg: +// +// func isLeafType(t reflect.Type) bool { +// return t == reflect.TypeOf(time.Time{}) +// } +// +// Next, construct a Cache, passing your functions. As its name suggests, a +// Cache remembers validation and field information for a type, so subsequent +// calls with the same type are very fast. +// +// cache := fields.NewCache(parseTag, validate, isLeafType) +// +// To get the fields of a struct type as determined by the above rules, call +// the Fields method: +// +// fields, err := cache.Fields(reflect.TypeOf(MyStruct{})) +// +// The return value can be treated as a slice of Fields. +// +// Given a string, such as a key or column name obtained during unmarshalling, +// call Match on the list of fields to find a field whose name is the best +// match: +// +// field := fields.Match(name) +// +// Match looks for an exact match first, then falls back to a case-insensitive +// comparison. +package fields + +import ( + "bytes" + "reflect" + "sort" + "strings" + "sync" +) + +// A Field records information about a struct field. +type Field struct { + Name string // effective field name + NameFromTag bool // did Name come from a tag? + Type reflect.Type // field type + Index []int // index sequence, for reflect.Value.FieldByIndex + ParsedTag interface{} // third return value of the parseTag function + + nameBytes []byte + equalFold func(s, t []byte) bool +} + +// ParseTagFunc is a function that accepts a struct tag and returns four values: an alternative name for the field +// extracted from the tag, a boolean saying whether to keep the field or ignore it, additional data that is stored +// with the field information to avoid having to parse the tag again, and an error. +type ParseTagFunc func(reflect.StructTag) (name string, keep bool, other interface{}, err error) + +// ValidateFunc is a function that accepts a reflect.Type and returns an error if the struct type is invalid in any +// way. +type ValidateFunc func(reflect.Type) error + +// LeafTypesFunc is a function that accepts a reflect.Type and returns true if the struct type a leaf, or false if not. +// TODO(deklerk) is this description accurate? +type LeafTypesFunc func(reflect.Type) bool + +// A Cache records information about the fields of struct types. +// +// A Cache is safe for use by multiple goroutines. +type Cache struct { + parseTag ParseTagFunc + validate ValidateFunc + leafTypes LeafTypesFunc + cache sync.Map // from reflect.Type to cacheValue +} + +// NewCache constructs a Cache. +// +// Its first argument should be a function that accepts +// a struct tag and returns four values: an alternative name for the field +// extracted from the tag, a boolean saying whether to keep the field or ignore +// it, additional data that is stored with the field information to avoid +// having to parse the tag again, and an error. +// +// Its second argument should be a function that accepts a reflect.Type and +// returns an error if the struct type is invalid in any way. For example, it +// may check that all of the struct field tags are valid, or that all fields +// are of an appropriate type. +func NewCache(parseTag ParseTagFunc, validate ValidateFunc, leafTypes LeafTypesFunc) *Cache { + if parseTag == nil { + parseTag = func(reflect.StructTag) (string, bool, interface{}, error) { + return "", true, nil, nil + } + } + if validate == nil { + validate = func(reflect.Type) error { + return nil + } + } + if leafTypes == nil { + leafTypes = func(reflect.Type) bool { + return false + } + } + + return &Cache{ + parseTag: parseTag, + validate: validate, + leafTypes: leafTypes, + } +} + +// A fieldScan represents an item on the fieldByNameFunc scan work list. +type fieldScan struct { + typ reflect.Type + index []int +} + +// Fields returns all the exported fields of t, which must be a struct type. It +// follows the standard Go rules for embedded fields, modified by the presence +// of tags. The result is sorted lexicographically by index. +// +// These rules apply in the absence of tags: +// Anonymous struct fields are treated as if their inner exported fields were +// fields in the outer struct (embedding). The result includes all fields that +// aren't shadowed by fields at higher level of embedding. If more than one +// field with the same name exists at the same level of embedding, it is +// excluded. An anonymous field that is not of struct type is treated as having +// its type as its name. +// +// Tags modify these rules as follows: +// A field's tag is used as its name. +// An anonymous struct field with a name given in its tag is treated as +// a field having that name, rather than an embedded struct (the struct's +// fields will not be returned). +// If more than one field with the same name exists at the same level of embedding, +// but exactly one of them is tagged, then the tagged field is reported and the others +// are ignored. +func (c *Cache) Fields(t reflect.Type) (List, error) { + if t.Kind() != reflect.Struct { + panic("fields: Fields of non-struct type") + } + return c.cachedTypeFields(t) +} + +// A List is a list of Fields. +type List []Field + +// MatchExact returns the field in the list with the given name, or nil if there is +// none. +func (l List) MatchExact(name string) *Field { + return l.MatchExactBytes([]byte(name)) +} + +// MatchExactBytes is identical to MatchExact, except that the argument is a byte slice. +func (l List) MatchExactBytes(name []byte) *Field { + for _, f := range l { + if bytes.Equal(f.nameBytes, name) { + return &f + } + } + return nil +} + +// MatchFold returns the field in the list whose name best matches the supplied +// name, nor nil if no field does. If there is a field with the exact name, it +// is returned. Otherwise the first field (sorted by index) whose name matches +// case-insensitively is returned. +func (l List) MatchFold(name string) *Field { + return l.MatchFoldBytes([]byte(name)) +} + +// MatchFoldBytes is identical to MatchFold, except that the argument is a byte slice. +func (l List) MatchFoldBytes(name []byte) *Field { + var f *Field + for i := range l { + ff := &l[i] + if bytes.Equal(ff.nameBytes, name) { + return ff + } + if f == nil && ff.equalFold(ff.nameBytes, name) { + f = ff + } + } + return f +} + +type cacheValue struct { + fields List + err error +} + +// cachedTypeFields is like typeFields but uses a cache to avoid repeated work. +// This code has been copied and modified from +// https://go.googlesource.com/go/+/go1.7.3/src/encoding/json/encode.go. +func (c *Cache) cachedTypeFields(t reflect.Type) (List, error) { + var cv cacheValue + x, ok := c.cache.Load(t) + if ok { + cv = x.(cacheValue) + } else { + if err := c.validate(t); err != nil { + cv = cacheValue{nil, err} + } else { + f, err := c.typeFields(t) + cv = cacheValue{List(f), err} + } + c.cache.Store(t, cv) + } + return cv.fields, cv.err +} + +func (c *Cache) typeFields(t reflect.Type) ([]Field, error) { + fields, err := c.listFields(t) + if err != nil { + return nil, err + } + sort.Sort(byName(fields)) + // Delete all fields that are hidden by the Go rules for embedded fields. + + // The fields are sorted in primary order of name, secondary order of field + // index length. So the first field with a given name is the dominant one. + var out []Field + for advance, i := 0, 0; i < len(fields); i += advance { + // One iteration per name. + // Find the sequence of fields with the name of this first field. + fi := fields[i] + name := fi.Name + for advance = 1; i+advance < len(fields); advance++ { + fj := fields[i+advance] + if fj.Name != name { + break + } + } + // Find the dominant field, if any, out of all fields that have the same name. + dominant, ok := dominantField(fields[i : i+advance]) + if ok { + out = append(out, dominant) + } + } + sort.Sort(byIndex(out)) + return out, nil +} + +func (c *Cache) listFields(t reflect.Type) ([]Field, error) { + // This uses the same condition that the Go language does: there must be a unique instance + // of the match at a given depth level. If there are multiple instances of a match at the + // same depth, they annihilate each other and inhibit any possible match at a lower level. + // The algorithm is breadth first search, one depth level at a time. + + // The current and next slices are work queues: + // current lists the fields to visit on this depth level, + // and next lists the fields on the next lower level. + current := []fieldScan{} + next := []fieldScan{{typ: t}} + + // nextCount records the number of times an embedded type has been + // encountered and considered for queueing in the 'next' slice. + // We only queue the first one, but we increment the count on each. + // If a struct type T can be reached more than once at a given depth level, + // then it annihilates itself and need not be considered at all when we + // process that next depth level. + var nextCount map[reflect.Type]int + + // visited records the structs that have been considered already. + // Embedded pointer fields can create cycles in the graph of + // reachable embedded types; visited avoids following those cycles. + // It also avoids duplicated effort: if we didn't find the field in an + // embedded type T at level 2, we won't find it in one at level 4 either. + visited := map[reflect.Type]bool{} + + var fields []Field // Fields found. + + for len(next) > 0 { + current, next = next, current[:0] + count := nextCount + nextCount = nil + + // Process all the fields at this depth, now listed in 'current'. + // The loop queues embedded fields found in 'next', for processing during the next + // iteration. The multiplicity of the 'current' field counts is recorded + // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'. + for _, scan := range current { + t := scan.typ + if visited[t] { + // We've looked through this type before, at a higher level. + // That higher level would shadow the lower level we're now at, + // so this one can't be useful to us. Ignore it. + continue + } + visited[t] = true + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + + exported := (f.PkgPath == "") + + // If a named field is unexported, ignore it. An anonymous + // unexported field is processed, because it may contain + // exported fields, which are visible. + if !exported && !f.Anonymous { + continue + } + + // Examine the tag. + tagName, keep, other, err := c.parseTag(f.Tag) + if err != nil { + return nil, err + } + if !keep { + continue + } + if c.leafTypes(f.Type) { + fields = append(fields, newField(f, tagName, other, scan.index, i)) + continue + } + + var ntyp reflect.Type + if f.Anonymous { + // Anonymous field of type T or *T. + ntyp = f.Type + if ntyp.Kind() == reflect.Ptr { + ntyp = ntyp.Elem() + } + } + + // Record fields with a tag name, non-anonymous fields, or + // anonymous non-struct fields. + if tagName != "" || ntyp == nil || ntyp.Kind() != reflect.Struct { + if !exported { + continue + } + fields = append(fields, newField(f, tagName, other, scan.index, i)) + if count[t] > 1 { + // If there were multiple instances, add a second, + // so that the annihilation code will see a duplicate. + fields = append(fields, fields[len(fields)-1]) + } + continue + } + + // Queue embedded struct fields for processing with next level, + // but only if the embedded types haven't already been queued. + if nextCount[ntyp] > 0 { + nextCount[ntyp] = 2 // exact multiple doesn't matter + continue + } + if nextCount == nil { + nextCount = map[reflect.Type]int{} + } + nextCount[ntyp] = 1 + if count[t] > 1 { + nextCount[ntyp] = 2 // exact multiple doesn't matter + } + var index []int + index = append(index, scan.index...) + index = append(index, i) + next = append(next, fieldScan{ntyp, index}) + } + } + } + return fields, nil +} + +func newField(f reflect.StructField, tagName string, other interface{}, index []int, i int) Field { + name := tagName + if name == "" { + name = f.Name + } + sf := Field{ + Name: name, + NameFromTag: tagName != "", + Type: f.Type, + ParsedTag: other, + nameBytes: []byte(name), + } + sf.equalFold = foldFunc(sf.nameBytes) + sf.Index = append(sf.Index, index...) + sf.Index = append(sf.Index, i) + return sf +} + +// byName sorts fields using the following criteria, in order: +// 1. name +// 2. embedding depth +// 3. tag presence (preferring a tagged field) +// 4. index sequence. +type byName []Field + +func (x byName) Len() int { return len(x) } + +func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } + +func (x byName) Less(i, j int) bool { + if x[i].Name != x[j].Name { + return x[i].Name < x[j].Name + } + if len(x[i].Index) != len(x[j].Index) { + return len(x[i].Index) < len(x[j].Index) + } + if x[i].NameFromTag != x[j].NameFromTag { + return x[i].NameFromTag + } + return byIndex(x).Less(i, j) +} + +// byIndex sorts field by index sequence. +type byIndex []Field + +func (x byIndex) Len() int { return len(x) } + +func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } + +func (x byIndex) Less(i, j int) bool { + xi := x[i].Index + xj := x[j].Index + ln := len(xi) + if l := len(xj); l < ln { + ln = l + } + for k := 0; k < ln; k++ { + if xi[k] != xj[k] { + return xi[k] < xj[k] + } + } + return len(xi) < len(xj) +} + +// dominantField looks through the fields, all of which are known to have the +// same name, to find the single field that dominates the others using Go's +// embedding rules, modified by the presence of tags. If there are multiple +// top-level fields, the boolean will be false: This condition is an error in +// Go and we skip all the fields. +func dominantField(fs []Field) (Field, bool) { + // The fields are sorted in increasing index-length order, then by presence of tag. + // That means that the first field is the dominant one. We need only check + // for error cases: two fields at top level, either both tagged or neither tagged. + if len(fs) > 1 && len(fs[0].Index) == len(fs[1].Index) && fs[0].NameFromTag == fs[1].NameFromTag { + return Field{}, false + } + return fs[0], true +} + +// ParseStandardTag extracts the sub-tag named by key, then parses it using the +// de facto standard format introduced in encoding/json: +// +// "-" means "ignore this tag", unless it has options (that is, is followed by a comma), +// in which case it is treated a name. +// "" provides an alternative name for the field +// ",opt1,opt2,..." specifies options after the name. +// +// The options are returned as a []string. +func ParseStandardTag(key string, t reflect.StructTag) (name string, keep bool, options []string) { + s := t.Get(key) + parts := strings.Split(s, ",") + if parts[0] == "-" && len(parts) == 1 { + return "", false, nil + } + if len(parts) > 1 { + options = parts[1:] + } + return parts[0], true, options +} diff --git a/go-cloud/docstore/internal/fields/fields_test.go b/go-cloud/docstore/internal/fields/fields_test.go new file mode 100644 index 000000000..488573123 --- /dev/null +++ b/go-cloud/docstore/internal/fields/fields_test.go @@ -0,0 +1,594 @@ +// Copyright 2019 The Go Cloud Development Kit 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 fields + +import ( + "encoding/json" + "errors" + "fmt" + "reflect" + "testing" + "time" + + "github.com/google/go-cmp/cmp" +) + +type embed1 struct { + Em1 int + Dup int // annihilates with embed2.Dup + Shadow int + embed3 +} + +type embed2 struct { + Dup int + embed3 + embed4 +} + +type embed3 struct { + Em3 int // annihilated because embed3 is in both embed1 and embed2 + embed5 +} + +type embed4 struct { + Em4 int + Dup int // annihilation of Dup in embed1, embed2 hides this Dup + *embed1 // ignored because it occurs at a higher level +} + +type embed5 struct { + x int +} + +type Anonymous int + +type S1 struct { + Exported int + unexported int + Shadow int // shadows S1.Shadow + embed1 + *embed2 + Anonymous +} + +type Time struct { + time.Time +} + +var intType = reflect.TypeOf(int(0)) + +func field(name string, tval interface{}, index ...int) *Field { + return &Field{ + Name: name, + Type: reflect.TypeOf(tval), + Index: index, + ParsedTag: []string(nil), + } +} + +func tfield(name string, tval interface{}, index ...int) *Field { + return &Field{ + Name: name, + Type: reflect.TypeOf(tval), + Index: index, + NameFromTag: true, + ParsedTag: []string(nil), + } +} + +func TestFieldsNoTags(t *testing.T) { + c := NewCache(nil, nil, nil) + got, err := c.Fields(reflect.TypeOf(S1{})) + if err != nil { + t.Fatal(err) + } + want := []*Field{ + field("Exported", int(0), 0), + field("Shadow", int(0), 2), + field("Em1", int(0), 3, 0), + field("Em4", int(0), 4, 2, 0), + field("Anonymous", Anonymous(0), 5), + } + for _, f := range want { + f.ParsedTag = nil + } + if msg, ok := compareFields(got, want); !ok { + t.Error(msg) + } +} + +func TestAgainstJSONEncodingNoTags(t *testing.T) { + // Demonstrates that this package produces the same set of fields as encoding/json. + s1 := S1{ + Exported: 1, + unexported: 2, + Shadow: 3, + embed1: embed1{ + Em1: 4, + Dup: 5, + Shadow: 6, + embed3: embed3{ + Em3: 7, + embed5: embed5{x: 8}, + }, + }, + embed2: &embed2{ + Dup: 9, + embed3: embed3{ + Em3: 10, + embed5: embed5{x: 11}, + }, + embed4: embed4{ + Em4: 12, + Dup: 13, + embed1: &embed1{Em1: 14}, + }, + }, + Anonymous: Anonymous(15), + } + var want S1 + want.embed2 = &embed2{} // need this because reflection won't create it + jsonRoundTrip(t, s1, &want) + var got S1 + got.embed2 = &embed2{} + fields, err := NewCache(nil, nil, nil).Fields(reflect.TypeOf(got)) + if err != nil { + t.Fatal(err) + } + setFields(fields, &got, s1) + if !cmp.Equal(got, want, + cmp.AllowUnexported(S1{}, embed1{}, embed2{}, embed3{}, embed4{}, embed5{})) { + t.Errorf("got\n%+v\nwant\n%+v", got, want) + } +} + +// Tests use of LeafTypes parameter to NewCache +func TestAgainstJSONEncodingEmbeddedTime(t *testing.T) { + timeLeafFn := func(t reflect.Type) bool { + return t == reflect.TypeOf(time.Time{}) + } + // Demonstrates that this package can produce the same set of + // fields as encoding/json for a struct with an embedded time.Time. + now := time.Now().UTC() + myt := Time{ + now, + } + var want Time + jsonRoundTrip(t, myt, &want) + var got Time + fields, err := NewCache(nil, nil, timeLeafFn).Fields(reflect.TypeOf(got)) + if err != nil { + t.Fatal(err) + } + setFields(fields, &got, myt) + if !cmp.Equal(got, want) { + t.Errorf("got\n%+v\nwant\n%+v", got, want) + } +} + +type S2 struct { + NoTag int + XXX int `json:"tag"` // tag name takes precedence + Anonymous `json:"anon"` // anonymous non-structs also get their name from the tag + unexported int `json:"tag"` + Embed `json:"em"` // embedded structs with tags become fields + Tag int + YYY int `json:"Tag"` // tag takes precedence over untagged field of the same name + Empty int `json:""` // empty tag is noop + tEmbed1 + tEmbed2 +} + +type Embed struct { + Em int +} + +type tEmbed1 struct { + Dup int + X int `json:"Dup2"` +} + +type tEmbed2 struct { + Y int `json:"Dup"` // takes precedence over tEmbed1.Dup because it is tagged + Z int `json:"Dup2"` // same name as tEmbed1.X and both tagged, so ignored +} + +func jsonTagParser(t reflect.StructTag) (name string, keep bool, other interface{}, err error) { + n, k, o := ParseStandardTag("json", t) + return n, k, o, nil +} + +func validateFunc(t reflect.Type) (err error) { + if t.Kind() != reflect.Struct { + return errors.New("non-struct type used") + } + + for i := 0; i < t.NumField(); i++ { + if t.Field(i).Type.Kind() == reflect.Slice { + return fmt.Errorf("slice field found at field %s on struct %s", t.Field(i).Name, t.Name()) + } + } + + return nil +} + +func TestFieldsWithTags(t *testing.T) { + got, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S2{})) + if err != nil { + t.Fatal(err) + } + want := []*Field{ + field("NoTag", int(0), 0), + tfield("tag", int(0), 1), + tfield("anon", Anonymous(0), 2), + tfield("em", Embed{}, 4), + tfield("Tag", int(0), 6), + field("Empty", int(0), 7), + tfield("Dup", int(0), 8, 0), + } + if msg, ok := compareFields(got, want); !ok { + t.Error(msg) + } +} + +func TestAgainstJSONEncodingWithTags(t *testing.T) { + // Demonstrates that this package produces the same set of fields as encoding/json. + s2 := S2{ + NoTag: 1, + XXX: 2, + Anonymous: 3, + Embed: Embed{ + Em: 4, + }, + tEmbed1: tEmbed1{ + Dup: 5, + X: 6, + }, + tEmbed2: tEmbed2{ + Y: 7, + Z: 8, + }, + } + var want S2 + jsonRoundTrip(t, s2, &want) + var got S2 + fields, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(got)) + if err != nil { + t.Fatal(err) + } + setFields(fields, &got, s2) + if !cmp.Equal(got, want, cmp.AllowUnexported(S2{})) { + t.Errorf("got\n%+v\nwant\n%+v", got, want) + } +} + +func TestUnexportedAnonymousNonStruct(t *testing.T) { + // An unexported anonymous non-struct field should not be recorded. + // This is currently a bug in encoding/json. + // https://github.com/golang/go/issues/18009 + type ( + u int + v int + S struct { + u + v `json:"x"` + int + } + ) + + got, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S{})) + if err != nil { + t.Fatal(err) + } + if len(got) != 0 { + t.Errorf("got %d fields, want 0", len(got)) + } +} + +func TestUnexportedAnonymousStruct(t *testing.T) { + // An unexported anonymous struct with a tag is ignored. + // This is currently a bug in encoding/json. + // https://github.com/golang/go/issues/18009 + type ( + s1 struct{ X int } + S2 struct { + s1 `json:"Y"` + } + ) + got, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S2{})) + if err != nil { + t.Fatal(err) + } + if len(got) != 0 { + t.Errorf("got %d fields, want 0", len(got)) + } +} + +func TestDominantField(t *testing.T) { + // With fields sorted by index length and then by tag presence, + // the dominant field is always the first. Make sure all error + // cases are caught. + for _, test := range []struct { + fields []Field + wantOK bool + }{ + // A single field is OK. + {[]Field{{Index: []int{0}}}, true}, + {[]Field{{Index: []int{0}, NameFromTag: true}}, true}, + // A single field at top level is OK. + {[]Field{{Index: []int{0}}, {Index: []int{1, 0}}}, true}, + {[]Field{{Index: []int{0}}, {Index: []int{1, 0}, NameFromTag: true}}, true}, + {[]Field{{Index: []int{0}, NameFromTag: true}, {Index: []int{1, 0}, NameFromTag: true}}, true}, + // A single tagged field is OK. + {[]Field{{Index: []int{0}, NameFromTag: true}, {Index: []int{1}}}, true}, + // Two untagged fields at the same level is an error. + {[]Field{{Index: []int{0}}, {Index: []int{1}}}, false}, + // Two tagged fields at the same level is an error. + {[]Field{{Index: []int{0}, NameFromTag: true}, {Index: []int{1}, NameFromTag: true}}, false}, + } { + _, gotOK := dominantField(test.fields) + if gotOK != test.wantOK { + t.Errorf("%v: got %t, want %t", test.fields, gotOK, test.wantOK) + } + } +} + +func TestIgnore(t *testing.T) { + type S struct { + X int `json:"-"` + Y int `json:"-,"` // field with name "-" + } + got, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S{})) + if err != nil { + t.Fatal(err) + } + if len(got) != 1 { + t.Errorf("got %d fields, want 1", len(got)) + } +} + +func TestParsedTag(t *testing.T) { + type S struct { + X int `json:"name,omitempty"` + } + got, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S{})) + if err != nil { + t.Fatal(err) + } + want := []*Field{ + { + Name: "name", NameFromTag: true, Type: intType, + Index: []int{0}, ParsedTag: []string{"omitempty"}, + }, + } + if msg, ok := compareFields(got, want); !ok { + t.Error(msg) + } +} + +func TestValidateFunc(t *testing.T) { + type MyInvalidStruct struct { + A string + B []int + } + + _, err := NewCache(nil, validateFunc, nil).Fields(reflect.TypeOf(MyInvalidStruct{})) + if err == nil { + t.Fatal("expected error, got nil") + } + + type MyValidStruct struct { + A string + B int + } + _, err = NewCache(nil, validateFunc, nil).Fields(reflect.TypeOf(MyValidStruct{})) + if err != nil { + t.Fatalf("expected nil, got error: %s\n", err) + } +} + +func compareFields(got []Field, want []*Field) (msg string, ok bool) { + if len(got) != len(want) { + return fmt.Sprintf("got %d fields, want %d", len(got), len(want)), false + } + for i, g := range got { + w := *want[i] + if !fieldsEqual(&g, &w) { + return fmt.Sprintf("got\n%+v\nwant\n%+v", g, w), false + } + } + return "", true +} + +// Need this because Field contains a function, which cannot be compared. +func fieldsEqual(f1, f2 *Field) bool { + if f1 == nil || f2 == nil { + return f1 == f2 + } + return f1.Name == f2.Name && + f1.NameFromTag == f2.NameFromTag && + f1.Type == f2.Type && + cmp.Equal(f1.ParsedTag, f2.ParsedTag) +} + +// Set the fields of dst from those of src. +// dst must be a pointer to a struct value. +// src must be a struct value. +func setFields(fields []Field, dst, src interface{}) { + vsrc := reflect.ValueOf(src) + vdst := reflect.ValueOf(dst).Elem() + for _, f := range fields { + fdst := vdst.FieldByIndex(f.Index) + fsrc := vsrc.FieldByIndex(f.Index) + fdst.Set(fsrc) + } +} + +func jsonRoundTrip(t *testing.T, in, out interface{}) { + t.Helper() + + bytes, err := json.Marshal(in) + if err != nil { + t.Fatal(err) + } + if err := json.Unmarshal(bytes, out); err != nil { + t.Fatal(err) + } +} + +type S3 struct { + S4 + Abc int + AbC int + Tag int + X int `json:"Tag"` + unexported int +} + +type S4 struct { + ABc int + Y int `json:"Abc"` // ignored because of top-level Abc +} + +func TestMatchExact(t *testing.T) { + fields, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S3{})) + if err != nil { + t.Fatal(err) + } + for _, test := range []struct { + name string + want *Field + }{ + // Exact match wins. + {"Abc", field("Abc", int(0), 1)}, + {"AbC", field("AbC", int(0), 2)}, + {"ABc", field("ABc", int(0), 0, 0)}, + // Matches must be exact. + {"abc", nil}, + // Tag name takes precedence over untagged field of the same name. + {"Tag", tfield("Tag", int(0), 4)}, + // Unexported fields disappear. + {"unexported", nil}, + // Untagged embedded structs disappear. + {"S4", nil}, + } { + if got := fields.MatchExact(test.name); !fieldsEqual(got, test.want) { + t.Errorf("match %q:\ngot %+v\nwant %+v", test.name, got, test.want) + } + } +} + +func TestMatchFold(t *testing.T) { + fields, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S3{})) + if err != nil { + t.Fatal(err) + } + for _, test := range []struct { + name string + want *Field + }{ + // Exact match wins. + {"Abc", field("Abc", int(0), 1)}, + {"AbC", field("AbC", int(0), 2)}, + {"ABc", field("ABc", int(0), 0, 0)}, + // If there are multiple matches but no exact match or tag, + // the first field wins, lexicographically by index. + // Here, "ABc" is at a deeper embedding level, but since S4 appears + // first in S3, its index precedes the other fields of S3. + {"abc", field("ABc", int(0), 0, 0)}, + // Tag name takes precedence over untagged field of the same name. + {"Tag", tfield("Tag", int(0), 4)}, + // Unexported fields disappear. + {"unexported", nil}, + // Untagged embedded structs disappear. + {"S4", nil}, + } { + if got := fields.MatchFold(test.name); !fieldsEqual(got, test.want) { + t.Errorf("match %q:\ngot %+v\nwant %+v", test.name, got, test.want) + } + } +} + +func TestAgainstJSONMatchingField(t *testing.T) { + s3 := S3{ + S4: S4{ABc: 1, Y: 2}, + Abc: 3, + AbC: 4, + Tag: 5, + X: 6, + unexported: 7, + } + var want S3 + jsonRoundTrip(t, s3, &want) + v := reflect.ValueOf(want) + fields, err := NewCache(jsonTagParser, nil, nil).Fields(reflect.TypeOf(S3{})) + if err != nil { + t.Fatal(err) + } + for _, test := range []struct { + name string + got int + }{ + {"Abc", 3}, + {"AbC", 4}, + {"ABc", 1}, + {"abc", 1}, + {"Tag", 6}, + } { + f := fields.MatchFold(test.name) + if f == nil { + t.Fatalf("%s: no match", test.name) + } + w := v.FieldByIndex(f.Index).Interface() + if test.got != w { + t.Errorf("%s: got %d, want %d", test.name, test.got, w) + } + } +} + +func TestTagErrors(t *testing.T) { + called := false + c := NewCache(func(t reflect.StructTag) (string, bool, interface{}, error) { + called = true + s := t.Get("f") + if s == "bad" { + return "", false, nil, errors.New("error") + } + return s, true, nil, nil + }, nil, nil) + + type T struct { + X int `f:"ok"` + Y int `f:"bad"` + } + + _, err := c.Fields(reflect.TypeOf(T{})) + if !called { + t.Fatal("tag parser not called") + } + if err == nil { + t.Error("want error, got nil") + } + // Second time, we should cache the error. + called = false + _, err = c.Fields(reflect.TypeOf(T{})) + if called { + t.Fatal("tag parser called on second time") + } + if err == nil { + t.Error("want error, got nil") + } +} diff --git a/go-cloud/docstore/internal/fields/fold.go b/go-cloud/docstore/internal/fields/fold.go new file mode 100644 index 000000000..600974634 --- /dev/null +++ b/go-cloud/docstore/internal/fields/fold.go @@ -0,0 +1,154 @@ +// Copyright 2019 The Go Cloud Development Kit 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 fields + +// This file was copied from https://go.googlesource.com/go/+/go1.7.3/src/encoding/json/fold.go. +// Only the license and package were changed. + +import ( + "bytes" + "unicode/utf8" +) + +const ( + caseMask = ^byte(0x20) // Mask to ignore case in ASCII. + kelvin = '\u212a' + smallLongEss = '\u017f' +) + +// foldFunc returns one of four different case folding equivalence +// functions, from most general (and slow) to fastest: +// +// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8 +// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S') +// 3) asciiEqualFold, no special, but includes non-letters (including _) +// 4) simpleLetterEqualFold, no specials, no non-letters. +// +// The letters S and K are special because they map to 3 runes, not just 2: +// - S maps to s and to U+017F 'ſ' Latin small letter long s +// - k maps to K and to U+212A 'K' Kelvin sign +// +// See https://play.golang.org/p/tTxjOc0OGo +// +// The returned function is specialized for matching against s and +// should only be given s. It's not curried for performance reasons. +func foldFunc(s []byte) func(s, t []byte) bool { + nonLetter := false + special := false // special letter + for _, b := range s { + if b >= utf8.RuneSelf { + return bytes.EqualFold + } + upper := b & caseMask + if upper < 'A' || upper > 'Z' { + nonLetter = true + } else if upper == 'K' || upper == 'S' { + // See above for why these letters are special. + special = true + } + } + if special { + return equalFoldRight + } + if nonLetter { + return asciiEqualFold + } + return simpleLetterEqualFold +} + +// equalFoldRight is a specialization of bytes.EqualFold when s is +// known to be all ASCII (including punctuation), but contains an 's', +// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. +// See comments on foldFunc. +func equalFoldRight(s, t []byte) bool { + for _, sb := range s { + if len(t) == 0 { + return false + } + tb := t[0] + if tb < utf8.RuneSelf { + if sb != tb { + sbUpper := sb & caseMask + if 'A' <= sbUpper && sbUpper <= 'Z' { + if sbUpper != tb&caseMask { + return false + } + } else { + return false + } + } + t = t[1:] + continue + } + // sb is ASCII and t is not. t must be either kelvin + // sign or long s; sb must be s, S, k, or K. + tr, size := utf8.DecodeRune(t) + switch sb { + case 's', 'S': + if tr != smallLongEss { + return false + } + case 'k', 'K': + if tr != kelvin { + return false + } + default: + return false + } + t = t[size:] + + } + return len(t) <= 0 +} + +// asciiEqualFold is a specialization of bytes.EqualFold for use when +// s is all ASCII (but may contain non-letters) and contains no +// special-folding letters. +// See comments on foldFunc. +func asciiEqualFold(s, t []byte) bool { + if len(s) != len(t) { + return false + } + for i, sb := range s { + tb := t[i] + if sb == tb { + continue + } + if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { + if sb&caseMask != tb&caseMask { + return false + } + } else { + return false + } + } + return true +} + +// simpleLetterEqualFold is a specialization of bytes.EqualFold for +// use when s is all ASCII letters (no underscores, etc) and also +// doesn't contain 'k', 'K', 's', or 'S'. +// See comments on foldFunc. +func simpleLetterEqualFold(s, t []byte) bool { + if len(s) != len(t) { + return false + } + for i, b := range s { + if b&caseMask != t[i]&caseMask { + return false + } + } + return true +} diff --git a/go-cloud/docstore/internal/fields/fold_test.go b/go-cloud/docstore/internal/fields/fold_test.go new file mode 100644 index 000000000..b404de0b2 --- /dev/null +++ b/go-cloud/docstore/internal/fields/fold_test.go @@ -0,0 +1,129 @@ +// Copyright 2019 The Go Cloud Development Kit 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 fields + +// This file was copied from https://go.googlesource.com/go/+/go1.7.3/src/encoding/json/fold_test.go. +// Only the license and package were changed. + +import ( + "bytes" + "strings" + "testing" + "unicode/utf8" +) + +var foldTests = []struct { + fn func(s, t []byte) bool + s, t string + want bool +}{ + {equalFoldRight, "", "", true}, + {equalFoldRight, "a", "a", true}, + {equalFoldRight, "", "a", false}, + {equalFoldRight, "a", "", false}, + {equalFoldRight, "a", "A", true}, + {equalFoldRight, "AB", "ab", true}, + {equalFoldRight, "AB", "ac", false}, + {equalFoldRight, "sbkKc", "ſbKKc", true}, + {equalFoldRight, "SbKkc", "ſbKKc", true}, + {equalFoldRight, "SbKkc", "ſbKK", false}, + {equalFoldRight, "e", "é", false}, + {equalFoldRight, "s", "S", true}, + + {simpleLetterEqualFold, "", "", true}, + {simpleLetterEqualFold, "abc", "abc", true}, + {simpleLetterEqualFold, "abc", "ABC", true}, + {simpleLetterEqualFold, "abc", "ABCD", false}, + {simpleLetterEqualFold, "abc", "xxx", false}, + + {asciiEqualFold, "a_B", "A_b", true}, + {asciiEqualFold, "aa@", "aa`", false}, // verify 0x40 and 0x60 aren't case-equivalent +} + +func TestFold(t *testing.T) { + for i, tt := range foldTests { + if got := tt.fn([]byte(tt.s), []byte(tt.t)); got != tt.want { + t.Errorf("%d. %q, %q = %v; want %v", i, tt.s, tt.t, got, tt.want) + } + truth := strings.EqualFold(tt.s, tt.t) + if truth != tt.want { + t.Errorf("strings.EqualFold doesn't agree with case %d", i) + } + } +} + +func TestFoldAgainstUnicode(t *testing.T) { + const bufSize = 5 + buf1 := make([]byte, 0, bufSize) + buf2 := make([]byte, 0, bufSize) + var runes []rune + for i := 0x20; i <= 0x7f; i++ { + runes = append(runes, rune(i)) + } + runes = append(runes, kelvin, smallLongEss) + + funcs := []struct { + name string + fold func(s, t []byte) bool + letter bool // must be ASCII letter + simple bool // must be simple ASCII letter (not 'S' or 'K') + }{ + { + name: "equalFoldRight", + fold: equalFoldRight, + }, + { + name: "asciiEqualFold", + fold: asciiEqualFold, + simple: true, + }, + { + name: "simpleLetterEqualFold", + fold: simpleLetterEqualFold, + simple: true, + letter: true, + }, + } + + for _, ff := range funcs { + for _, r := range runes { + if r >= utf8.RuneSelf { + continue + } + if ff.letter && !isASCIILetter(byte(r)) { + continue + } + if ff.simple && (r == 's' || r == 'S' || r == 'k' || r == 'K') { + continue + } + for _, r2 := range runes { + buf1 := append(buf1[:0], 'x') + buf2 := append(buf2[:0], 'x') + buf1 = buf1[:1+utf8.EncodeRune(buf1[1:bufSize], r)] + buf2 = buf2[:1+utf8.EncodeRune(buf2[1:bufSize], r2)] + buf1 = append(buf1, 'x') + buf2 = append(buf2, 'x') + want := bytes.EqualFold(buf1, buf2) + if got := ff.fold(buf1, buf2); got != want { + t.Errorf("%s(%q, %q) = %v; want %v", ff.name, buf1, buf2, got, want) + } + } + } + } +} + +func isASCIILetter(b byte) bool { + return ('A' <= b && b <= 'Z') || ('a' <= b && b <= 'z') +} diff --git a/go-cloud/docstore/memdocstore/codec.go b/go-cloud/docstore/memdocstore/codec.go new file mode 100644 index 000000000..19bb65af7 --- /dev/null +++ b/go-cloud/docstore/memdocstore/codec.go @@ -0,0 +1,203 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 memdocstore + +import ( + "fmt" + "reflect" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" +) + +// encodeDoc encodes a driver.Document as a storedDoc. +func encodeDoc(doc driver.Document) (storedDoc, error) { + var e encoder + if err := doc.Encode(&e); err != nil { + return nil, err + } + return storedDoc(e.val.(map[string]interface{})), nil +} + +func encodeValue(v interface{}) (interface{}, error) { + var e encoder + if err := driver.Encode(reflect.ValueOf(v), &e); err != nil { + return nil, err + } + return e.val, nil +} + +type encoder struct { + val interface{} +} + +func (e *encoder) EncodeNil() { e.val = nil } +func (e *encoder) EncodeBool(x bool) { e.val = x } +func (e *encoder) EncodeInt(x int64) { e.val = x } +func (e *encoder) EncodeUint(x uint64) { e.val = int64(x) } +func (e *encoder) EncodeBytes(x []byte) { e.val = x } +func (e *encoder) EncodeFloat(x float64) { e.val = x } +func (e *encoder) EncodeString(x string) { e.val = x } +func (e *encoder) ListIndex(int) { panic("impossible") } +func (e *encoder) MapKey(string) { panic("impossible") } + +var typeOfGoTime = reflect.TypeOf(time.Time{}) + +func (e *encoder) EncodeSpecial(v reflect.Value) (bool, error) { + if v.Type() == typeOfGoTime { + e.val = v.Interface() + return true, nil + } + return false, nil +} + +func (e *encoder) EncodeList(n int) driver.Encoder { + // All slices and arrays are encoded as []interface{} + s := make([]interface{}, n) + e.val = s + return &listEncoder{s: s} +} + +type listEncoder struct { + s []interface{} + encoder +} + +func (e *listEncoder) ListIndex(i int) { e.s[i] = e.val } + +type mapEncoder struct { + m map[string]interface{} + encoder +} + +func (e *encoder) EncodeMap(n int) driver.Encoder { + m := make(map[string]interface{}, n) + e.val = m + return &mapEncoder{m: m} +} + +func (e *mapEncoder) MapKey(k string) { e.m[k] = e.val } + +//////////////////////////////////////////////////////////////// + +// decodeDoc decodes m into ddoc. +func decodeDoc(m storedDoc, ddoc driver.Document, fps [][]string) error { + var m2 map[string]interface{} + if len(fps) == 0 { + m2 = m + } else { + // Make a document to decode from that has only the field paths. + // (We don't need the key field because ddoc must already have it.) + m2 = map[string]interface{}{} + for _, fp := range fps { + val, err := getAtFieldPath(m, fp, false) + if err != nil { + if gcerrors.Code(err) == gcerrors.NotFound { + continue + } + return err + } + if err := setAtFieldPath(m2, fp, val); err != nil { + return err + } + } + } + return ddoc.Decode(decoder{m2}) +} + +type decoder struct { + val interface{} +} + +func (d decoder) String() string { + return fmt.Sprint(d.val) +} + +func (d decoder) AsNull() bool { + return d.val == nil +} + +func (d decoder) AsBool() (bool, bool) { + b, ok := d.val.(bool) + return b, ok +} + +func (d decoder) AsString() (string, bool) { + s, ok := d.val.(string) + return s, ok +} + +func (d decoder) AsInt() (int64, bool) { + i, ok := d.val.(int64) + return i, ok +} + +func (d decoder) AsUint() (uint64, bool) { + i, ok := d.val.(int64) + return uint64(i), ok +} + +func (d decoder) AsFloat() (float64, bool) { + f, ok := d.val.(float64) + return f, ok +} + +func (d decoder) AsBytes() ([]byte, bool) { + bs, ok := d.val.([]byte) + return bs, ok +} + +func (d decoder) AsInterface() (interface{}, error) { + return d.val, nil +} + +func (d decoder) ListLen() (int, bool) { + if s, ok := d.val.([]interface{}); ok { + return len(s), true + } + return 0, false +} + +func (d decoder) DecodeList(f func(i int, d2 driver.Decoder) bool) { + for i, e := range d.val.([]interface{}) { + if !f(i, decoder{e}) { + return + } + } +} + +func (d decoder) MapLen() (int, bool) { + if m, ok := d.val.(map[string]interface{}); ok { + return len(m), true + } + return 0, false +} + +func (d decoder) DecodeMap(f func(key string, d2 driver.Decoder, _ bool) bool) { + for k, v := range d.val.(map[string]interface{}) { + if !f(k, decoder{v}, true) { + return + } + } +} + +func (d decoder) AsSpecial(v reflect.Value) (bool, interface{}, error) { + if v.Type() == typeOfGoTime { + return true, d.val, nil + } + return false, nil, nil +} diff --git a/go-cloud/docstore/memdocstore/codec_test.go b/go-cloud/docstore/memdocstore/codec_test.go new file mode 100644 index 000000000..1ae4fb36e --- /dev/null +++ b/go-cloud/docstore/memdocstore/codec_test.go @@ -0,0 +1,159 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 memdocstore + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" +) + +type aStruct struct { + X int + embed + Z *bool + W uint + T time.Time + L []int + F float32 + B []byte +} + +type embed struct { + Y string +} + +func TestEncodeDoc(t *testing.T) { + var b bool = true + tm := time.Now() + for _, test := range []struct { + in interface{} + want storedDoc + }{ + { + in: map[string]interface{}{ + "x": map[int]interface{}{ + 1: "a", + 2: 17, + 3: []float32{1.0, 2.5}, + 4: map[string]bool{"false": false, "true": true}, + }, + }, + want: storedDoc{ + "x": map[string]interface{}{ + "1": "a", + "2": int64(17), + "3": []interface{}{float64(1.0), float64(2.5)}, + "4": map[string]interface{}{"false": false, "true": true}, + }, + }, + }, + { + in: &aStruct{ + X: 3, + embed: embed{Y: "y"}, + Z: &b, + W: 33, + T: tm, + L: []int{4, 5}, + F: 2.5, + B: []byte("abc"), + }, + want: storedDoc{ + "X": int64(3), + "Y": "y", + "Z": true, + "W": int64(33), + "T": tm, + "L": []interface{}{int64(4), int64(5)}, + "F": 2.5, + "B": []byte("abc"), + }, + }, + } { + doc := drivertest.MustDocument(test.in) + got, err := encodeDoc(doc) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(got, test.want); diff != "" { + t.Errorf("%+v: %s", test.in, diff) + } + } +} + +func TestDecodeDoc(t *testing.T) { + var b bool = true + tm := time.Now() + for _, test := range []struct { + in storedDoc + val interface{} + want interface{} + }{ + { + storedDoc{ + "x": map[string]interface{}{ + "1": "a", + "2": int64(17), + "3": []interface{}{float64(1.0), float64(2.5)}, + "4": map[string]interface{}{"false": false, "true": true}, + }, + }, + map[string]interface{}{}, + map[string]interface{}{ + "x": map[string]interface{}{ + "1": "a", + "2": int64(17), + "3": []interface{}{1.0, 2.5}, + "4": map[string]interface{}{"false": false, "true": true}, + }, + }, + }, + { + storedDoc{ + "X": int64(3), + "Y": "y", + "Z": true, + "W": int64(33), + "T": tm, + "L": []interface{}{int64(4), int64(5)}, + "F": 2.5, + "B": []byte("abc"), + }, + &aStruct{}, + &aStruct{ + X: 3, + embed: embed{Y: "y"}, + Z: &b, + W: 33, + T: tm, + L: []int{4, 5}, + F: 2.5, + B: []byte("abc"), + }, + }, + } { + got := test.val + doc := drivertest.MustDocument(test.val) + if err := decodeDoc(test.in, doc, nil); err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(got, test.want, cmp.AllowUnexported(aStruct{})); diff != "" { + t.Errorf("%+v: %s", test.in, diff) + } + } +} diff --git a/go-cloud/docstore/memdocstore/example_test.go b/go-cloud/docstore/memdocstore/example_test.go new file mode 100644 index 000000000..782d5c3b4 --- /dev/null +++ b/go-cloud/docstore/memdocstore/example_test.go @@ -0,0 +1,74 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 memdocstore_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/memdocstore" +) + +func ExampleOpenCollection() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + coll, err := memdocstore.OpenCollection("keyField", nil) + if err != nil { + log.Fatal(err) + } + defer coll.Close() + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + // Output: +} + +func ExampleOpenCollectionWithKeyFunc() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + type HighScore struct { + Game string + Player string + } + + // The name of a document is constructed from the Game and Player fields. + nameFromDocument := func(doc docstore.Document) interface{} { + hs := doc.(*HighScore) + return hs.Game + "|" + hs.Player + } + + coll, err := memdocstore.OpenCollectionWithKeyFunc(nameFromDocument, nil) + if err != nil { + log.Fatal(err) + } + defer coll.Close() + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + // Output: +} + +func Example_openCollectionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/docstore/memdocstore" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // docstore.OpenCollection creates a *docstore.Collection from a URL. + coll, err := docstore.OpenCollection(ctx, "mem://collection/keyField") + if err != nil { + log.Fatal(err) + } + defer coll.Close() + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + // Output: +} diff --git a/go-cloud/docstore/memdocstore/mem.go b/go-cloud/docstore/memdocstore/mem.go new file mode 100644 index 000000000..783235765 --- /dev/null +++ b/go-cloud/docstore/memdocstore/mem.go @@ -0,0 +1,548 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 memdocstore provides an in-process in-memory implementation of the docstore +// API. It is suitable for local development and testing. +// +// Every document in a memdocstore collection has a unique primary key. The primary +// key values need not be strings; they may be any comparable Go value. +// +// # Action Lists +// +// Action lists are executed concurrently. Each action in an action list is executed +// in a separate goroutine. +// +// memdocstore calls the BeforeDo function of an ActionList once before executing the +// actions. Its As function never returns true. +// +// # URLs +// +// For docstore.OpenCollection, memdocstore registers for the scheme +// "mem". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +package memdocstore // import "gocloud.dev/docstore/memdocstore" + +import ( + "context" + "encoding/gob" + "fmt" + "os" + "reflect" + "sort" + "strconv" + "strings" + "sync" + + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +// Options are optional arguments to the OpenCollection functions. +type Options struct { + // The name of the field holding the document revision. + // Defaults to docstore.DefaultRevisionField. + RevisionField string + + // The maximum number of concurrent goroutines started for a single call to + // ActionList.Do. If less than 1, there is no limit. + MaxOutstandingActions int + + // The filename associated with this collection. + // When a collection is opened with a non-nil filename, the collection + // is loaded from the file if it exists. Otherwise, an empty collection is created. + // When the collection is closed, its contents are saved to the file. + Filename string + + // AllowNestedSliceQueries allows querying into nested slices. + // If true queries for a field path which points to a slice will return + // true if any element of the slice has a value that validates with the operator. + // This makes the memdocstore more compatible with MongoDB, + // but other providers may not support this feature. + AllowNestedSliceQueries bool + + // Call this function when the collection is closed. + // For internal use only. + onClose func() +} + +// TODO(jba): make this package thread-safe. + +// OpenCollection creates a *docstore.Collection backed by memory. keyField is the +// document field holding the primary key of the collection. +func OpenCollection(keyField string, opts *Options) (*docstore.Collection, error) { + c, err := newCollection(keyField, nil, opts) + if err != nil { + return nil, err + } + return docstore.NewCollection(c), nil +} + +// OpenCollectionWithKeyFunc creates a *docstore.Collection backed by memory. keyFunc takes +// a document and returns the document's primary key. It should return nil if the +// document is missing the information to construct a key. This will cause all +// actions, even Create, to fail. +// +// For the collection to be usable with Query.Delete and Query.Update, +// keyFunc must work with map[string]interface{} as well as whatever +// struct type the collection normally uses (if any). +func OpenCollectionWithKeyFunc(keyFunc func(docstore.Document) interface{}, opts *Options) (*docstore.Collection, error) { + c, err := newCollection("", keyFunc, opts) + if err != nil { + return nil, err + } + return docstore.NewCollection(c), nil +} + +func newCollection(keyField string, keyFunc func(docstore.Document) interface{}, opts *Options) (driver.Collection, error) { + if keyField == "" && keyFunc == nil { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "must provide either keyField or keyFunc") + } + if opts == nil { + opts = &Options{} + } + if opts.RevisionField == "" { + opts.RevisionField = docstore.DefaultRevisionField + } + docs, err := loadDocs(opts.Filename) + if err != nil { + return nil, err + } + return &collection{ + keyField: keyField, + keyFunc: keyFunc, + docs: docs, + opts: opts, + curRevision: 0, + }, nil +} + +// A storedDoc is a document that is stored in a collection. +// +// We store documents as maps from keys to values. Even if the user is using +// map[string]interface{}, we make our own copy. +// +// Using a separate helps distinguish documents coming from a user (those "on +// the client," in a more typical driver that acts as a network client) from +// those stored in a collection (those "on the server"). +type storedDoc map[string]interface{} + +type collection struct { + keyField string + keyFunc func(docstore.Document) interface{} + opts *Options + mu sync.Mutex + docs map[interface{}]storedDoc + curRevision int64 // incremented on each write +} + +func (c *collection) Key(doc driver.Document) (interface{}, error) { + if c.keyField != "" { + key, _ := doc.GetField(c.keyField) // no error on missing key, and it will be nil + return key, nil + } + key := c.keyFunc(doc.Origin) + if key == nil || driver.IsEmptyValue(reflect.ValueOf(key)) { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "missing document key") + } + return key, nil +} + +func (c *collection) RevisionField() string { + return c.opts.RevisionField +} + +// ErrorCode implements driver.ErrorCode. +func (c *collection) ErrorCode(err error) gcerrors.ErrorCode { + return gcerrors.Code(err) +} + +// RunActions implements driver.RunActions. +func (c *collection) RunActions(ctx context.Context, actions []*driver.Action, opts *driver.RunActionsOptions) driver.ActionListError { + errs := make([]error, len(actions)) + + // Run the actions concurrently with each other. + run := func(as []*driver.Action) { + t := driver.NewThrottle(c.opts.MaxOutstandingActions) + for _, a := range as { + a := a + t.Acquire() + go func() { + defer t.Release() + errs[a.Index] = c.runAction(ctx, a) + }() + } + t.Wait() + } + + if opts.BeforeDo != nil { + if err := opts.BeforeDo(func(interface{}) bool { return false }); err != nil { + for i := range errs { + errs[i] = err + } + return driver.NewActionListError(errs) + } + } + + beforeGets, gets, writes, _, afterGets := driver.GroupActions(actions) + run(beforeGets) + run(gets) + run(writes) + run(afterGets) + return driver.NewActionListError(errs) +} + +// runAction executes a single action. +func (c *collection) runAction(ctx context.Context, a *driver.Action) error { + // Stop if the context is done. + if ctx.Err() != nil { + return ctx.Err() + } + // Get the key from the doc so we can look it up in the map. + c.mu.Lock() + defer c.mu.Unlock() + // If there is a key, get the current document with that key. + var ( + current storedDoc + exists bool + ) + if a.Key != nil { + current, exists = c.docs[a.Key] + } + // Check for a NotFound error. + if !exists && (a.Kind == driver.Replace || a.Kind == driver.Update || a.Kind == driver.Get) { + return gcerr.Newf(gcerr.NotFound, nil, "document with key %v does not exist", a.Key) + } + switch a.Kind { + case driver.Create: + // It is an error to attempt to create an existing document. + if exists { + return gcerr.Newf(gcerr.AlreadyExists, nil, "Create: document with key %v exists", a.Key) + } + // If the user didn't supply a value for the key field, create a new one. + if a.Key == nil { + a.Key = driver.UniqueString() + // Set the new key in the document. + if err := a.Doc.SetField(c.keyField, a.Key); err != nil { + return gcerr.Newf(gcerr.InvalidArgument, nil, "cannot set key field %q", c.keyField) + } + } + fallthrough + + case driver.Replace, driver.Put: + if err := c.checkRevision(a.Doc, current); err != nil { + return err + } + doc, err := encodeDoc(a.Doc) + if err != nil { + return err + } + if a.Doc.HasField(c.opts.RevisionField) { + c.changeRevision(doc) + if err := a.Doc.SetField(c.opts.RevisionField, doc[c.opts.RevisionField]); err != nil { + return err + } + } + c.docs[a.Key] = doc + + case driver.Delete: + if err := c.checkRevision(a.Doc, current); err != nil { + return err + } + delete(c.docs, a.Key) + + case driver.Update: + if err := c.checkRevision(a.Doc, current); err != nil { + return err + } + if err := c.update(current, a.Mods); err != nil { + return err + } + if a.Doc.HasField(c.opts.RevisionField) { + c.changeRevision(current) + if err := a.Doc.SetField(c.opts.RevisionField, current[c.opts.RevisionField]); err != nil { + return err + } + } + + case driver.Get: + // We've already retrieved the document into current, above. + // Now we copy its fields into the user-provided document. + if err := decodeDoc(current, a.Doc, a.FieldPaths); err != nil { + return err + } + default: + return gcerr.Newf(gcerr.Internal, nil, "unknown kind %v", a.Kind) + } + return nil +} + +// Must be called with the lock held. +// Does not change the stored doc's revision field; that is up to the caller. +func (c *collection) update(doc storedDoc, mods []driver.Mod) error { + // Sort mods by first field path element so tests are deterministic. + sort.Slice(mods, func(i, j int) bool { return mods[i].FieldPath[0] < mods[j].FieldPath[0] }) + + // To make update atomic, we first convert the actions into a form that can't + // fail. + type guaranteedMod struct { + parentMap map[string]interface{} // the map holding the key to be modified + key string + encodedValue interface{} // the value after encoding + } + + gmods := make([]guaranteedMod, len(mods)) + var err error + for i, mod := range mods { + gmod := &gmods[i] + // Check that the field path is valid. That is, every component of the path + // but the last refers to a map, and no component along the way is nil. + if gmod.parentMap, err = getParentMap(doc, mod.FieldPath, false); err != nil { + return err + } + gmod.key = mod.FieldPath[len(mod.FieldPath)-1] + if inc, ok := mod.Value.(driver.IncOp); ok { + amt, err := encodeValue(inc.Amount) + if err != nil { + return err + } + if gmod.encodedValue, err = add(gmod.parentMap[gmod.key], amt); err != nil { + return err + } + } else if mod.Value != nil { + // Make sure the value encodes successfully. + if gmod.encodedValue, err = encodeValue(mod.Value); err != nil { + return err + } + } + } + // Now execute the guaranteed mods. + for _, m := range gmods { + if m.encodedValue == nil { + delete(m.parentMap, m.key) + } else { + m.parentMap[m.key] = m.encodedValue + } + } + return nil +} + +// Add two encoded numbers. +// Since they're encoded, they are either int64 or float64. +// Allow adding a float to an int, producing a float. +// TODO(jba): see how other drivers handle that. +func add(x, y interface{}) (interface{}, error) { + if x == nil { + return y, nil + } + switch x := x.(type) { + case int64: + switch y := y.(type) { + case int64: + return x + y, nil + case float64: + return float64(x) + y, nil + default: + // This shouldn't happen because it should be checked by docstore. + return nil, gcerr.Newf(gcerr.Internal, nil, "bad increment aount type %T", y) + } + case float64: + switch y := y.(type) { + case int64: + return x + float64(y), nil + case float64: + return x + y, nil + default: + // This shouldn't happen because it should be checked by docstore. + return nil, gcerr.Newf(gcerr.Internal, nil, "bad increment aount type %T", y) + } + default: + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "value %v being incremented not int64 or float64", x) + } +} + +// Must be called with the lock held. +func (c *collection) changeRevision(doc storedDoc) { + c.curRevision++ + doc[c.opts.RevisionField] = c.curRevision +} + +func (c *collection) checkRevision(arg driver.Document, current storedDoc) error { + if current == nil { + return nil // no existing document or the incoming doc has no revision + } + curRev, ok := current[c.opts.RevisionField] + if !ok { + return nil // there is no revision to check + } + curRev = curRev.(int64) + r, err := arg.GetField(c.opts.RevisionField) + if err != nil || r == nil { + return nil // no incoming revision information: nothing to check + } + wantRev, ok := r.(int64) + if !ok { + return gcerr.Newf(gcerr.InvalidArgument, nil, "revision field %s is not an int64", c.opts.RevisionField) + } + if wantRev != curRev { + return gcerr.Newf(gcerr.FailedPrecondition, nil, "mismatched revisions: want %d, current %d", wantRev, curRev) + } + return nil +} + +// getAtFieldPath gets the value of m at fp. It returns an error if fp is invalid. +// If nested is true compare against all elements of a slice, see AllowNestedSliceQueries +// (see getParentMap). +func getAtFieldPath(m map[string]any, fp []string, nested bool) (result any, err error) { + var get func(m any, name string) any + get = func(m any, name string) any { + switch m := m.(type) { + case map[string]any: + return m[name] + case []any: + if !nested { + return nil + } + var result []any + for _, e := range m { + next := get(e, name) + // If we have slices within slices the compare function does not see the nested slices. + // Changing the compare function to be recursive would be more effort than flattening the slices here. + sliced, ok := next.([]any) + if ok { + result = append(result, sliced...) + } else { + result = append(result, next) + } + } + return result + } + return nil + } + result = m + for _, k := range fp { + next := get(result, k) + if next == nil { + return nil, gcerr.Newf(gcerr.NotFound, nil, "field %s not found", strings.Join(fp, ".")) + } + result = next + } + return result, nil +} + +// setAtFieldPath sets m's value at fp to val. It creates intermediate maps as +// needed. It returns an error if a non-final component of fp does not denote a map. +func setAtFieldPath(m map[string]interface{}, fp []string, val interface{}) error { + m2, err := getParentMap(m, fp, true) + if err != nil { + return err + } + m2[fp[len(fp)-1]] = val + return nil +} + +// getParentMap returns the map that directly contains the given field path; +// that is, the value of m at the field path that excludes the last component +// of fp. If a non-map is encountered along the way, an InvalidArgument error is +// returned. If nil is encountered, nil is returned unless create is true, in +// which case a map is added at that point. +func getParentMap(m map[string]interface{}, fp []string, create bool) (map[string]interface{}, error) { + var ok bool + for _, k := range fp[:len(fp)-1] { + if m[k] == nil { + if !create { + return nil, nil + } + m[k] = map[string]interface{}{} + } + m, ok = m[k].(map[string]interface{}) + if !ok { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "invalid field path %q at %q", strings.Join(fp, "."), k) + } + } + return m, nil +} + +// RevisionToBytes implements driver.RevisionToBytes. +func (c *collection) RevisionToBytes(rev interface{}) ([]byte, error) { + r, ok := rev.(int64) + if !ok { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "revision %v of type %[1]T is not an int64", rev) + } + return strconv.AppendInt(nil, r, 10), nil +} + +// BytesToRevision implements driver.BytesToRevision. +func (c *collection) BytesToRevision(b []byte) (interface{}, error) { + return strconv.ParseInt(string(b), 10, 64) +} + +// As implements driver.As. +func (c *collection) As(i interface{}) bool { return false } + +// As implements driver.Collection.ErrorAs. +func (c *collection) ErrorAs(err error, i interface{}) bool { return false } + +// Close implements driver.Collection.Close. +// If the collection was created with a Filename option, Close writes the +// collection's documents to the file. +func (c *collection) Close() error { + if c.opts.onClose != nil { + c.opts.onClose() + } + return saveDocs(c.opts.Filename, c.docs) +} + +type mapOfDocs = map[interface{}]storedDoc + +// Read a map from the filename if is is not empty and the file exists. +// Otherwise return an empty (not nil) map. +func loadDocs(filename string) (mapOfDocs, error) { + if filename == "" { + return mapOfDocs{}, nil + } + f, err := os.Open(filename) + if err != nil { + if !os.IsNotExist(err) { + return nil, err + } + // If the file doesn't exist, return an empty map without error. + return mapOfDocs{}, nil + } + defer f.Close() + var m mapOfDocs + if err := gob.NewDecoder(f).Decode(&m); err != nil { + return nil, fmt.Errorf("failed to decode from %q: %v", filename, err) + } + return m, nil +} + +// saveDocs saves m to filename if filename is not empty. +func saveDocs(filename string, m mapOfDocs) error { + if filename == "" { + return nil + } + f, err := os.Create(filename) + if err != nil { + return err + } + if err := gob.NewEncoder(f).Encode(m); err != nil { + _ = f.Close() + return fmt.Errorf("failed to encode to %q: %v", filename, err) + } + return f.Close() +} diff --git a/go-cloud/docstore/memdocstore/mem_test.go b/go-cloud/docstore/memdocstore/mem_test.go new file mode 100644 index 000000000..17a22f43b --- /dev/null +++ b/go-cloud/docstore/memdocstore/mem_test.go @@ -0,0 +1,341 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 memdocstore + +import ( + "context" + "io" + "os" + "path/filepath" + "slices" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" +) + +type harness struct{} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return &harness{}, nil +} + +func (h *harness) MakeCollection(_ context.Context, kind drivertest.CollectionKind) (driver.Collection, error) { + switch kind { + case drivertest.SingleKey, drivertest.NoRev: + return newCollection(drivertest.KeyField, nil, nil) + case drivertest.TwoKey: + return newCollection("", drivertest.HighScoreKey, nil) + case drivertest.AltRev: + return newCollection(drivertest.KeyField, nil, &Options{RevisionField: drivertest.AlternateRevisionField}) + default: + panic("bad kind") + } +} + +func (*harness) BeforeDoTypes() []interface{} { return nil } +func (*harness) BeforeQueryTypes() []interface{} { return nil } + +func (*harness) RevisionsEqual(rev1, rev2 interface{}) bool { return rev1 == rev2 } + +func (*harness) SupportsAtomicWrites() bool { return false } + +func (*harness) Close() {} + +func TestConformance(t *testing.T) { + // CodecTester is nil because memdocstore has no native representation. + drivertest.RunConformanceTests(t, newHarness, nil, nil) +} + +type docmap = map[string]interface{} + +// memdocstore-specific tests. + +// The following tests test memdocstore's backend implementation. + +func TestUpdateEncodesValues(t *testing.T) { + // Check that update encodes the values in mods. + ctx := context.Background() + dc, err := newCollection(drivertest.KeyField, nil, nil) + if err != nil { + t.Fatal(err) + } + coll := docstore.NewCollection(dc) + defer coll.Close() + doc := docmap{drivertest.KeyField: "testUpdateEncodes", "a": 1, dc.RevisionField(): nil} + if err := coll.Put(ctx, doc); err != nil { + t.Fatal(err) + } + if err := coll.Update(ctx, doc, docstore.Mods{"a": 2}); err != nil { + t.Fatal(err) + } + got := docmap{drivertest.KeyField: doc[drivertest.KeyField]} + // This Get will fail if the int value 2 in the above mod was not encoded to an int64. + if err := coll.Get(ctx, got); err != nil { + t.Fatal(err) + } + want := docmap{ + drivertest.KeyField: doc[drivertest.KeyField], + "a": int64(2), + dc.RevisionField(): got[dc.RevisionField()], + } + if !cmp.Equal(got, want) { + t.Errorf("got %v, want %v", got, want) + } +} + +func TestUpdateAtomic(t *testing.T) { + // Check that update is atomic. + ctx := context.Background() + dc, err := newCollection(drivertest.KeyField, nil, nil) + if err != nil { + t.Fatal(err) + } + coll := docstore.NewCollection(dc) + defer coll.Close() + doc := docmap{drivertest.KeyField: "testUpdateAtomic", "a": "A", "b": "B", dc.RevisionField(): nil} + + mods := docstore.Mods{"a": "Y", "b.c": "Z"} // "b" is not a map, so "b.c" is an error + if err := coll.Put(ctx, doc); err != nil { + t.Fatal(err) + } + if errs := coll.Actions().Update(doc, mods).Do(ctx); errs == nil { + t.Fatal("got nil, want errors") + } + got := docmap{drivertest.KeyField: doc[drivertest.KeyField]} + if err := coll.Get(ctx, got); err != nil { + t.Fatal(err) + } + want := docmap{ + drivertest.KeyField: doc[drivertest.KeyField], + dc.RevisionField(): got[dc.RevisionField()], + "a": "A", + "b": "B", + } + if !cmp.Equal(got, want) { + t.Errorf("got %v, want %v", got, want) + } +} + +func TestQueryNested(t *testing.T) { + ctx := context.Background() + + dc, err := newCollection(drivertest.KeyField, nil, &Options{AllowNestedSliceQueries: true}) + if err != nil { + t.Fatal(err) + } + coll := docstore.NewCollection(dc) + defer coll.Close() + + // Set up test documents + testDocs := []docmap{{ + drivertest.KeyField: "TestQueryNested", + "list": []any{docmap{"a": "A"}}, + "map": docmap{"b": "B"}, + "listOfMaps": []any{docmap{"id": "1"}, docmap{"id": "2"}, docmap{"id": "3"}}, + "mapOfLists": docmap{"ids": []any{"1", "2", "3"}}, + "deep": []any{docmap{"nesting": []any{docmap{"of": docmap{"elements": "yes"}}}}}, + "listOfLists": []any{docmap{"items": []any{docmap{"price": 10}, docmap{"price": 20}}}}, + dc.RevisionField(): nil, + }, { + drivertest.KeyField: "CheapItems", + "items": []any{docmap{"price": 10}, docmap{"price": 1}}, + dc.RevisionField(): nil, + }, { + drivertest.KeyField: "ExpensiveItems", + "items": []any{docmap{"price": 50}, docmap{"price": 100}}, + dc.RevisionField(): nil, + }} + + for _, testDoc := range testDocs { + err = coll.Put(ctx, testDoc) + if err != nil { + t.Fatal(err) + } + } + + tests := []struct { + name string + where []any + wantKeys []string + }{ + { + name: "list field match", + where: []any{"list.a", "=", "A"}, + wantKeys: []string{"TestQueryNested"}, + }, { + name: "list field no match", + where: []any{"list.a", "=", "missing"}, + }, { + name: "map field match", + where: []any{"map.b", "=", "B"}, + wantKeys: []string{"TestQueryNested"}, + }, { + name: "list of maps field match", + where: []any{"listOfMaps.id", "=", "2"}, + wantKeys: []string{"TestQueryNested"}, + }, { + name: "map of lists field match", + where: []any{"mapOfLists.ids", "=", "1"}, + wantKeys: []string{"TestQueryNested"}, + }, { + name: "deep nested field match", + where: []any{"deep.nesting.of.elements", "=", "yes"}, + wantKeys: []string{"TestQueryNested"}, + }, { + name: "list of lists exact price 10", + where: []any{"listOfLists.items.price", "=", 10}, + wantKeys: []string{"TestQueryNested"}, + }, { + name: "list of lists exact price 20", + where: []any{"listOfLists.items.price", "=", 20}, + wantKeys: []string{"TestQueryNested"}, + }, { + name: "list of lists price less than or equal to 20", + where: []any{"listOfLists.items.price", "<=", 20}, + wantKeys: []string{"TestQueryNested"}, + }, { + name: "items price equals 1", + where: []any{"items.price", "=", 1}, + wantKeys: []string{"CheapItems"}, + }, { + name: "items price equals 5 (no match)", + where: []any{"items.price", "=", 5}, + }, { + name: "items price greater than or equal to 1", + where: []any{"items.price", ">=", 1}, + wantKeys: []string{"CheapItems", "ExpensiveItems"}, + }, { + name: "items price greater than or equal to 5", + where: []any{"items.price", ">=", 5}, + wantKeys: []string{"CheapItems", "ExpensiveItems"}, + }, { + name: "items price greater than or equal to 10", + where: []any{"items.price", ">=", 10}, + wantKeys: []string{"CheapItems", "ExpensiveItems"}, + }, { + name: "items price less than or equal to 50", + where: []any{"items.price", "<=", 50}, + wantKeys: []string{"CheapItems", "ExpensiveItems"}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + iter := coll.Query().Where(docstore.FieldPath(tc.where[0].(string)), tc.where[1].(string), tc.where[2]).Get(ctx) + var got []docmap + for { + doc := docmap{} + err := iter.Next(ctx, doc) + if err != nil { + if err == io.EOF { + break + } + t.Fatal(err) + } + got = append(got, doc) + } + + // Extract keys from results + var gotKeys []string + for _, d := range got { + if key, ok := d[drivertest.KeyField].(string); ok { + gotKeys = append(gotKeys, key) + } + } + slices.Sort(gotKeys) + + diff := cmp.Diff(gotKeys, tc.wantKeys) + if diff != "" { + t.Errorf("query results mismatch (-got +want):\n%s", diff) + } + }) + } +} + +func TestSortDocs(t *testing.T) { + newDocs := func() []storedDoc { + return []storedDoc{ + {"a": int64(1), "b": "1", "c": 3.0}, + {"a": int64(2), "b": "2", "c": 4.0}, + {"a": int64(3), "b": "3"}, // missing "c" + } + } + inorder := newDocs() + reversed := newDocs() + for i := 0; i < len(reversed)/2; i++ { + j := len(reversed) - i - 1 + reversed[i], reversed[j] = reversed[j], reversed[i] + } + + for _, test := range []struct { + field string + ascending bool + want []storedDoc + }{ + {"a", true, inorder}, + {"a", false, reversed}, + {"b", true, inorder}, + {"b", false, reversed}, + {"c", true, inorder}, + {"c", false, []storedDoc{inorder[1], inorder[0], inorder[2]}}, + } { + got := newDocs() + sortDocs(got, test.field, test.ascending) + if diff := cmp.Diff(got, test.want); diff != "" { + t.Errorf("%q, asc=%t:\n%s", test.field, test.ascending, diff) + } + } +} + +func TestSaveAndLoad(t *testing.T) { + dir := t.TempDir() + + // Load from nonexistent file should return empty data. + f := filepath.Join(dir, "saveAndLoad") + got, err := loadDocs(f) + if err != nil { + t.Fatalf("loading from nonexistent file, got %v, want nil", err) + } + if len(got) != 0 { + t.Fatalf("loading from nonexistent file, got %v, want empty map", got) + } + + // Save some data into the file. + docs := map[interface{}]storedDoc{ + "k1": {"key": "k1", "a": 1}, + "k2": {"key": "k2", "b": 2}, + } + if err := saveDocs(f, docs); err != nil { + t.Fatal(err) + } + // File should exist now. + if _, err := os.Lstat(f); err != nil { + t.Fatal(err) + } + + // Reload the data. + got, err = loadDocs(f) + if err != nil { + t.Fatal(err) + } + if !cmp.Equal(got, docs) { + t.Errorf("\ngot %v\nwant %v", got, docs) + } +} diff --git a/go-cloud/docstore/memdocstore/query.go b/go-cloud/docstore/memdocstore/query.go new file mode 100644 index 000000000..564730062 --- /dev/null +++ b/go-cloud/docstore/memdocstore/query.go @@ -0,0 +1,225 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 memdocstore + +import ( + "context" + "io" + "reflect" + "sort" + "strings" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" +) + +func (c *collection) RunGetQuery(_ context.Context, q *driver.Query) (driver.DocumentIterator, error) { + if q.BeforeQuery != nil { + if err := q.BeforeQuery(func(interface{}) bool { return false }); err != nil { + return nil, err + } + } + + c.mu.Lock() + defer c.mu.Unlock() + + var resultDocs []storedDoc + for _, doc := range c.docs { + if filtersMatch(q.Filters, doc, c.opts.AllowNestedSliceQueries) { + resultDocs = append(resultDocs, doc) + } + } + if q.OrderByField != "" { + sortDocs(resultDocs, q.OrderByField, q.OrderAscending) + } + + // Apply offset + if q.Offset > 0 { + if q.Offset >= len(resultDocs) { + resultDocs = []storedDoc{} // If offset is larger than or equal to the length, result should be an empty slice + } else { + resultDocs = resultDocs[q.Offset:] + } + } + + // Apply limit + if q.Limit > 0 && len(resultDocs) > q.Limit { + resultDocs = resultDocs[:q.Limit] + } + + // Include the key field in the field paths if there is one. + var fps [][]string + if len(q.FieldPaths) > 0 && c.keyField != "" { + fps = append([][]string{{c.keyField}}, q.FieldPaths...) + } else { + fps = q.FieldPaths + } + + return &docIterator{ + docs: resultDocs, + fieldPaths: fps, + revField: c.opts.RevisionField, + }, nil +} + +func filtersMatch(fs []driver.Filter, doc storedDoc, nested bool) bool { + for _, f := range fs { + if !filterMatches(f, doc, nested) { + return false + } + } + return true +} + +func filterMatches(f driver.Filter, doc storedDoc, nested bool) bool { + docval, err := getAtFieldPath(doc, f.FieldPath, nested) + // missing or bad field path => no match + if err != nil { + return false + } + c, ok := compare(docval, f.Value, f.Op) + if !ok { + return false + } + return applyComparison(f.Op, c) +} + +// op is one of the permitted docstore operators ("=", "<", etc.) +// c is the result of strings.Compare or the like. +// TODO(jba): dedup from gcpfirestore/query? +func applyComparison(op string, c int) bool { + switch op { + case driver.EqualOp: + return c == 0 + case ">": + return c > 0 + case "<": + return c < 0 + case ">=": + return c >= 0 + case "<=": + return c <= 0 + case "in": + return c == 0 + case "not-in": + return c != 0 + default: + panic("bad op") + } +} + +func compare(x1, x2 any, op string) (int, bool) { + v1 := reflect.ValueOf(x1) + v2 := reflect.ValueOf(x2) + // For in/not-in queries. Otherwise this should only be reached with AllowNestedSliceQueries set. + // Return 0 if x1 is in slice x2, -1 if not. + if v2.Kind() == reflect.Slice { + for i := range v2.Len() { + if c, ok := compare(x1, v2.Index(i).Interface(), op); ok { + if c == 0 { + return 0, true + } + if op != "in" && op != "not-in" { + return c, true + } + } + } + return -1, true + } + // See Options.AllowNestedSliceQueries + // When querying for x2 in the document and x1 is a list of values we only need one value to match + // the comparison value depends on the operator. + if v1.Kind() == reflect.Slice { + v2Greater := false + v2Less := false + for i := range v1.Len() { + if c, ok := compare(x2, v1.Index(i).Interface(), op); ok { + if c == 0 { + return 0, true + } + v2Greater = v2Greater || c > 0 + v2Less = v2Less || c < 0 + } + } + if op[0] == '>' && v2Less { + return 1, true + } else if op[0] == '<' && v2Greater { + return -1, true + } + return 0, false + } + if v1.Kind() == reflect.String && v2.Kind() == reflect.String { + return strings.Compare(v1.String(), v2.String()), true + } + if cmp, err := driver.CompareNumbers(v1, v2); err == nil { + return cmp, true + } + if t1, ok := x1.(time.Time); ok { + if t2, ok := x2.(time.Time); ok { + return driver.CompareTimes(t1, t2), true + } + } + if v1.Kind() == reflect.Bool && v2.Kind() == reflect.Bool { + if v1.Bool() == v2.Bool() { + return 0, true + } + return -1, true + } + return 0, false +} + +func sortDocs(docs []storedDoc, field string, asc bool) { + sort.Slice(docs, func(i, j int) bool { + c, ok := compare(docs[i][field], docs[j][field], ">") + if !ok { + return false + } + if asc { + return c < 0 + } + return c > 0 + }) +} + +type docIterator struct { + docs []storedDoc + fieldPaths [][]string + revField string + err error +} + +func (it *docIterator) Next(ctx context.Context, doc driver.Document) error { + if it.err != nil { + return it.err + } + if len(it.docs) == 0 { + it.err = io.EOF + return it.err + } + if err := decodeDoc(it.docs[0], doc, it.fieldPaths); err != nil { + it.err = err + return it.err + } + it.docs = it.docs[1:] + return nil +} + +func (it *docIterator) Stop() { it.err = io.EOF } + +func (it *docIterator) As(i interface{}) bool { return false } + +func (c *collection) QueryPlan(q *driver.Query) (string, error) { + return "", nil +} diff --git a/go-cloud/docstore/memdocstore/urls.go b/go-cloud/docstore/memdocstore/urls.go new file mode 100644 index 000000000..e1f2952ec --- /dev/null +++ b/go-cloud/docstore/memdocstore/urls.go @@ -0,0 +1,103 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 memdocstore + +import ( + "context" + "fmt" + "net/url" + "strings" + "sync" + + "github.com/DataDog/iceberg-go/go-cloud/docstore" +) + +func init() { + docstore.DefaultURLMux().RegisterCollection(Scheme, &URLOpener{}) +} + +// Scheme is the URL scheme memdocstore registers its URLOpener under on +// docstore.DefaultMux. +const Scheme = "mem" + +// URLOpener opens URLs like "mem://collection/_id". +// +// The URL's host is the name of the collection. +// The URL's path is used as the keyField. +// +// The following query parameters are supported: +// +// - revision_field (optional): the name of the revision field. +// - filename (optional): the filename to store the collection in. +type URLOpener struct { + mu sync.Mutex + collections map[string]urlColl +} + +type urlColl struct { + keyName string + coll *docstore.Collection +} + +// OpenCollectionURL opens a docstore.Collection based on u. +func (o *URLOpener) OpenCollectionURL(ctx context.Context, u *url.URL) (*docstore.Collection, error) { + q := u.Query() + collName := u.Host + if collName == "" { + return nil, fmt.Errorf("open collection %v: empty collection name", u) + } + keyName := u.Path + keyName = strings.TrimPrefix(keyName, "/") + if keyName == "" || strings.ContainsRune(keyName, '/') { + return nil, fmt.Errorf("open collection %v: invalid key name %q (must be non-empty and have no slashes)", u, keyName) + } + + options := &Options{ + RevisionField: q.Get("revision_field"), + Filename: q.Get("filename"), + AllowNestedSliceQueries: q.Get("allow_nested_slice_queries") == "true", + onClose: func() { + o.mu.Lock() + delete(o.collections, collName) + o.mu.Unlock() + }, + } + q.Del("revision_field") + q.Del("filename") + q.Del("allow_nested_slice_queries") + for param := range q { + return nil, fmt.Errorf("open collection %v: invalid query parameter %q", u, param) + } + + o.mu.Lock() + defer o.mu.Unlock() + if o.collections == nil { + o.collections = map[string]urlColl{} + } + ucoll, ok := o.collections[collName] + if !ok { + coll, err := OpenCollection(keyName, options) + if err != nil { + return nil, err + } + o.collections[collName] = urlColl{keyName, coll} + return coll, nil + } + if ucoll.keyName != keyName { + return nil, fmt.Errorf("open collection %v: key name %q does not equal existing key name %q", + u, keyName, ucoll.keyName) + } + return ucoll.coll, nil +} diff --git a/go-cloud/docstore/memdocstore/urls_test.go b/go-cloud/docstore/memdocstore/urls_test.go new file mode 100644 index 000000000..d4a666c0a --- /dev/null +++ b/go-cloud/docstore/memdocstore/urls_test.go @@ -0,0 +1,57 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 memdocstore + +import ( + "context" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/docstore" +) + +func TestOpenCollectionFromURL(t *testing.T) { + tests := []struct { + URL string + wantErr bool + }{ + // OK. + {"mem://coll/_id", false}, + // "coll" already has key "_id". + {"mem://coll/foo.bar", true}, + {"mem://coll2/foo.bar", false}, + // Missing collection. + {"mem://", true}, + // Missing key. + {"mem://coll", true}, + // Key with slash. + {"mem://coll/my/key", true}, + // Passing revision field. + {"mem://coll/_id?revision_field=123", false}, + // Passing filename. + {"mem://coll/_id?filename=foo.out", false}, + // Invalid parameter. + {"mem://coll/key?param=value", true}, + } + ctx := context.Background() + for _, test := range tests { + d, err := docstore.OpenCollection(ctx, test.URL) + if d != nil { + defer d.Close() + } + if (err != nil) != test.wantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.wantErr) + } + } +} diff --git a/go-cloud/docstore/mongodocstore/awsdocdb/main.tf b/go-cloud/docstore/mongodocstore/awsdocdb/main.tf new file mode 100644 index 000000000..39d3c5102 --- /dev/null +++ b/go-cloud/docstore/mongodocstore/awsdocdb/main.tf @@ -0,0 +1,85 @@ +# Specify the provider and access details +provider "aws" { + version = "~> 2.0" + region = "${var.aws_region}" +} + +resource "aws_security_group" "docdbtest" { + name_prefix = "docdbtest" + description = "Test mongo driver on docdb" + vpc_id = "${var.vpc_id}" + + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + description = "Public SSH access" + } + + ingress { + from_port = 0 + to_port = 0 + protocol = "-1" + self = true + description = "Allow traffic within the security group for port forwarding" + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +# Provisioning a DocumentDB cluster with an instance. + +resource "aws_docdb_cluster_instance" "docdbtest" { + cluster_identifier = "${aws_docdb_cluster.docdbtest.id}" + identifier_prefix = "${aws_docdb_cluster.docdbtest.id}" + instance_class = "db.r5.large" + apply_immediately = true +} + +resource "aws_docdb_cluster" "docdbtest" { + cluster_identifier = "docstore-test-cluster" + master_username = "${var.db_username}" + master_password = "${var.db_password}" + + db_cluster_parameter_group_name = "docstore-test-pg" + vpc_security_group_ids = ["${aws_security_group.docdbtest.id}"] + + skip_final_snapshot = true +} + +# Provisioning an EC2 instance within the same VPC group for port forwarding. + +resource "aws_key_pair" "docdbtest" { + key_name_prefix = "docdbtest" + public_key = "${var.ssh_public_key}" +} + +data "aws_ami" "ubuntu" { + most_recent = true + + filter { + name = "name" + values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + + owners = ["099720109477"] +} + +resource "aws_instance" "docdbtest" { + ami = "${data.aws_ami.ubuntu.id}" + instance_type = "t2.micro" + vpc_security_group_ids = ["${aws_security_group.docdbtest.id}"] + key_name = "${aws_key_pair.docdbtest.key_name}" + associate_public_ip_address = true +} diff --git a/go-cloud/docstore/mongodocstore/awsdocdb/outputs.tf b/go-cloud/docstore/mongodocstore/awsdocdb/outputs.tf new file mode 100644 index 000000000..9978fedb5 --- /dev/null +++ b/go-cloud/docstore/mongodocstore/awsdocdb/outputs.tf @@ -0,0 +1,3 @@ +output "setup_ssh_tunnel" { + value = "ssh -L 27019:${aws_docdb_cluster.docdbtest.endpoint}:27017 ubuntu@${aws_instance.docdbtest.public_dns} -N" +} diff --git a/go-cloud/docstore/mongodocstore/awsdocdb/variables.tf b/go-cloud/docstore/mongodocstore/awsdocdb/variables.tf new file mode 100644 index 000000000..75af3124f --- /dev/null +++ b/go-cloud/docstore/mongodocstore/awsdocdb/variables.tf @@ -0,0 +1,20 @@ +variable "aws_region" { + description = "The AWS region to create docdb cluster and ec2 instance in." + default = "us-east-2" +} + +variable "vpc_id" { + description = "The ID of the default VPC used by docdb cluster and ec2 instance." +} + +variable "ssh_public_key" { + description = "A public key line in .ssh/authorized_keys format to use to authenticate to your instance. This must be added to your SSH agent for provisioning to succeed." +} + +variable "db_username" { + description = "The master username to login docdb" +} + +variable "db_password" { + description = "The master password to login docdb" +} diff --git a/go-cloud/docstore/mongodocstore/codec.go b/go-cloud/docstore/mongodocstore/codec.go new file mode 100644 index 000000000..9ed976207 --- /dev/null +++ b/go-cloud/docstore/mongodocstore/codec.go @@ -0,0 +1,260 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mongodocstore + +import ( + "fmt" + "reflect" + "strings" + "time" + + "go.mongodb.org/mongo-driver/bson/primitive" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" +) + +// Encode and decode to map[string]interface{}. +// This isn't ideal, because the mongo client encodes/decodes a second time. +// TODO(jba): Benchmark the double decode to see if it's worth trying to avoid it. + +// This code is copied from memdocstore/codec.go, except for special treatment of +// primitive.Binary. + +func encodeDoc(doc driver.Document, lowercaseFields bool) (map[string]interface{}, error) { + e := encoder{lowercaseFields: lowercaseFields} + if err := doc.Encode(&e); err != nil { + return nil, err + } + return e.val.(map[string]interface{}), nil +} + +func encodeValue(x interface{}) (interface{}, error) { + var e encoder + if err := driver.Encode(reflect.ValueOf(x), &e); err != nil { + return nil, err + } + return e.val, nil +} + +type encoder struct { + val interface{} + lowercaseFields bool +} + +func (e *encoder) EncodeNil() { e.val = nil } +func (e *encoder) EncodeBool(x bool) { e.val = x } +func (e *encoder) EncodeInt(x int64) { e.val = x } +func (e *encoder) EncodeUint(x uint64) { e.val = int64(x) } +func (e *encoder) EncodeBytes(x []byte) { e.val = x } +func (e *encoder) EncodeFloat(x float64) { e.val = x } +func (e *encoder) EncodeString(x string) { e.val = x } +func (e *encoder) ListIndex(int) { panic("impossible") } +func (e *encoder) MapKey(string) { panic("impossible") } + +var ( + typeOfGoTime = reflect.TypeOf(time.Time{}) + typeOfObjectID = reflect.TypeOf(primitive.ObjectID{}) +) + +func (e *encoder) EncodeSpecial(v reflect.Value) (bool, error) { + // Treat time specially as itself (otherwise its BinaryMarshal method will be called). + // Also, ObjectIDs are already encoded. + if v.Type() == typeOfGoTime || v.Type() == typeOfObjectID { + e.val = v.Interface() + return true, nil + } + return false, nil +} + +func (e *encoder) EncodeList(n int) driver.Encoder { + // All slices and arrays are encoded as []interface{} + s := make([]interface{}, n) + e.val = s + return &listEncoder{s: s, encoder: encoder{lowercaseFields: e.lowercaseFields}} +} + +type listEncoder struct { + s []interface{} + encoder +} + +func (e *listEncoder) ListIndex(i int) { e.s[i] = e.val } + +type mapEncoder struct { + m map[string]interface{} + isStruct bool + encoder +} + +func (e *encoder) EncodeMap(n int) driver.Encoder { + m := make(map[string]interface{}, n) + e.val = m + return &mapEncoder{m: m, encoder: encoder{lowercaseFields: e.lowercaseFields}} +} + +func (e *mapEncoder) MapKey(k string) { + if e.lowercaseFields { + k = strings.ToLower(k) + } + e.m[k] = e.val +} + +//////////////////////////////////////////////////////////////// + +// decodeDoc decodes m into ddoc. +func decodeDoc(m map[string]interface{}, ddoc driver.Document, idField string, lowercaseFields bool) error { + switch idField { + case mongoIDField: // do nothing + case "": // user uses idFunc + delete(m, mongoIDField) + default: // user documents have a different ID field + m[idField] = m[mongoIDField] + delete(m, mongoIDField) + } + return ddoc.Decode(decoder{val: m, lowercaseFields: lowercaseFields}) +} + +type decoder struct { + val interface{} + lowercaseFields bool +} + +func (d decoder) String() string { + return fmt.Sprint(d.val) +} + +func (d decoder) AsNull() bool { + return d.val == nil +} + +func (d decoder) AsBool() (bool, bool) { + b, ok := d.val.(bool) + return b, ok +} + +func (d decoder) AsString() (string, bool) { + s, ok := d.val.(string) + return s, ok +} + +func (d decoder) AsInt() (int64, bool) { + switch v := d.val.(type) { + case int64: + return v, true + case int32: + return int64(v), true + default: + return 0, false + } +} + +func (d decoder) AsUint() (uint64, bool) { + i, ok := d.val.(int64) + return uint64(i), ok +} + +func (d decoder) AsFloat() (float64, bool) { + f, ok := d.val.(float64) + return f, ok +} + +func (d decoder) AsBytes() ([]byte, bool) { + switch v := d.val.(type) { + case []byte: + return v, true + case primitive.Binary: + return v.Data, true + default: + return nil, false + } +} + +func (d decoder) AsInterface() (interface{}, error) { + return toGoValue(d.val) +} + +func toGoValue(v interface{}) (interface{}, error) { + switch v := v.(type) { + case primitive.A: + r := make([]interface{}, len(v)) + for i, e := range v { + d, err := toGoValue(e) + if err != nil { + return nil, err + } + r[i] = d + } + return r, nil + case primitive.Binary: + return v.Data, nil + case primitive.DateTime: + return bsonDateTimeToTime(v), nil + case map[string]interface{}: + r := map[string]interface{}{} + for k, e := range v { + d, err := toGoValue(e) + if err != nil { + return nil, err + } + r[k] = d + } + return r, nil + default: + return v, nil + } +} + +func (d decoder) ListLen() (int, bool) { + if s, ok := d.val.(primitive.A); ok { + return len(s), true + } + return 0, false +} + +func (d decoder) DecodeList(f func(i int, d2 driver.Decoder) bool) { + for i, e := range d.val.(primitive.A) { + if !f(i, decoder{e, d.lowercaseFields}) { + return + } + } +} + +func (d decoder) MapLen() (int, bool) { + if m, ok := d.val.(map[string]interface{}); ok { + return len(m), true + } + return 0, false +} + +func (d decoder) DecodeMap(f func(key string, d2 driver.Decoder, exactMatch bool) bool) { + for k, v := range d.val.(map[string]interface{}) { + if !f(k, decoder{v, d.lowercaseFields}, !d.lowercaseFields) { + return + } + } +} + +func (d decoder) AsSpecial(v reflect.Value) (bool, interface{}, error) { + switch v := d.val.(type) { + case primitive.DateTime: + // A DateTime represents milliseconds since the Unix epoch. + return true, bsonDateTimeToTime(v), nil + default: + return false, nil, nil + } +} + +func bsonDateTimeToTime(dt primitive.DateTime) time.Time { + return time.Unix(int64(dt)/1000, int64(dt)%1000*1e6) +} diff --git a/go-cloud/docstore/mongodocstore/cosmos_test.go b/go-cloud/docstore/mongodocstore/cosmos_test.go new file mode 100644 index 000000000..6ba96e417 --- /dev/null +++ b/go-cloud/docstore/mongodocstore/cosmos_test.go @@ -0,0 +1,58 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mongodocstore + +import ( + "context" + "os" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" +) + +// Run conformance tests on Azure Cosmos. + +// See https://docs.microsoft.com/en-us/azure/cosmos-db/connect-mongodb-account +// on how to get a MongoDB connection string for Azure Cosmos. +var cosmosConnString = os.Getenv("COSMOS_CONNECTION_STRING") + +func TestConformanceCosmos(t *testing.T) { + if !*setup.Record { + t.Skip("replaying is not yet supported for Azure Cosmos") + } + if cosmosConnString == "" { + t.Fatal("test harness requires COSMOS_CONNECTION_STRING environment variable to run") + } + + ctx := context.Background() + client, err := Dial(ctx, cosmosConnString) + if err != nil { + t.Fatalf("dialing to %s: %v", cosmosConnString, err) + } + if err := client.Ping(ctx, nil); err != nil { + t.Fatalf("connecting to %s: %v", cosmosConnString, err) + } + defer func() { + // Cleanup any resource to avoid wastes. + client.Database(dbName).Drop(ctx) + client.Disconnect(ctx) + }() + + newHarness := func(context.Context, *testing.T) (drivertest.Harness, error) { + return &harness{client.Database(dbName), true}, nil + } + drivertest.RunConformanceTests(t, newHarness, codecTester{}, []drivertest.AsTest{verifyAs{}}) +} diff --git a/go-cloud/docstore/mongodocstore/docdb_test.go b/go-cloud/docstore/mongodocstore/docdb_test.go new file mode 100644 index 000000000..44c659240 --- /dev/null +++ b/go-cloud/docstore/mongodocstore/docdb_test.go @@ -0,0 +1,73 @@ +package mongodocstore + +import ( + "context" + "fmt" + "os" + "testing" + + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" +) + +const connectionStringTemplate = "mongodb://%s:%s@%s/?connect=direct&connectTimeoutMS=3000" + +// To run the conformance tests against Amazon DocumentDB: +// +// 1. Run `terraform apply` in awsdocdb directory to provision a docdb cluster and an EC2 instance. +// 2. Run the command provided by the terraform output string to setup port-forwarding. +// 3. Set the following environment variables and run this test with `-record` flag. + +var ( + username = os.Getenv("AWSDOCDB_USERNAME") + password = os.Getenv("AWSDOCDB_PASSWORD") + endpoint = os.Getenv("AWSDOCDB_ENDPOINT") // optional, default to localhost:27019 +) + +func TestConformanceDocDB(t *testing.T) { + if !*setup.Record { + t.Skip("replaying is not yet supported for Amazon DocumentDB") + } + if username == "" || password == "" { + t.Fatal("environment not setup to run DocDB test") + } + + client := newDocDBTestClient(t) + defer client.Disconnect(context.Background()) + + newHarness := func(context.Context, *testing.T) (drivertest.Harness, error) { + return &harness{db: client.Database(dbName)}, nil + } + drivertest.RunConformanceTests(t, newHarness, codecTester{}, []drivertest.AsTest{verifyAs{}}) +} + +func newDocDBTestClient(t *testing.T) *mongo.Client { + ctx := context.Background() + if endpoint == "" { + endpoint = "localhost:27019" + } + connectionURI := fmt.Sprintf(connectionStringTemplate, username, password, endpoint) + + o := options.Client().ApplyURI(connectionURI) + if err := o.Validate(); err != nil { + t.Fatal(err) + } + client, err := mongo.NewClient(o) + if err != nil { + t.Fatalf("Failed to create client: %v", err) + } + + err = client.Connect(ctx) + if err != nil { + t.Fatalf("Failed to connect to cluster: %v", err) + } + + // Force a connection to verify our connection string + err = client.Ping(ctx, nil) + if err != nil { + t.Fatalf("Failed to ping cluster: %v", err) + } + return client +} diff --git a/go-cloud/docstore/mongodocstore/docker-compose.yml b/go-cloud/docstore/mongodocstore/docker-compose.yml new file mode 100644 index 000000000..e1402bfb2 --- /dev/null +++ b/go-cloud/docstore/mongodocstore/docker-compose.yml @@ -0,0 +1,30 @@ +version: '3.8' +services: + mongo: + image: mongo:4.4 + container_name: mongo + restart: always + volumes: + - mongo_data:/data/db + ports: + - "27017:27017" + command: ["--replSet", "dbrs", "--bind_ip_all"] + + mongosetup: + image: mongo:4.4 + container_name: mongosetup + depends_on: + - mongo + entrypoint: > + bash -c "sleep 5 && + mongo --host mongo:27017 --eval ' + rs.initiate({ + _id: \"dbrs\", + members: [ + { _id: 0, host: \"mongo:27017\"} + ] + }) + '" + +volumes: + mongo_data: \ No newline at end of file diff --git a/go-cloud/docstore/mongodocstore/example_test.go b/go-cloud/docstore/mongodocstore/example_test.go new file mode 100644 index 000000000..348a5f402 --- /dev/null +++ b/go-cloud/docstore/mongodocstore/example_test.go @@ -0,0 +1,82 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mongodocstore_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/mongodocstore" +) + +func ExampleOpenCollection() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + client, err := mongodocstore.Dial(ctx, "mongodb://my-host") + if err != nil { + log.Fatal(err) + } + mcoll := client.Database("my-db").Collection("my-coll") + coll, err := mongodocstore.OpenCollection(mcoll, "userID", nil) + if err != nil { + log.Fatal(err) + } + defer coll.Close() +} + +func ExampleOpenCollectionWithIDFunc() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + type HighScore struct { + Game string + Player string + } + + client, err := mongodocstore.Dial(ctx, "mongodb://my-host") + if err != nil { + log.Fatal(err) + } + mcoll := client.Database("my-db").Collection("my-coll") + + // The name of a document is constructed from the Game and Player fields. + nameFromDocument := func(doc docstore.Document) interface{} { + hs := doc.(*HighScore) + return hs.Game + "|" + hs.Player + } + + coll, err := mongodocstore.OpenCollectionWithIDFunc(mcoll, nameFromDocument, nil) + if err != nil { + log.Fatal(err) + } + defer coll.Close() +} + +func Example_openCollectionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/docstore/mongodocstore" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // docstore.OpenCollection creates a *docstore.Collection from a URL. + coll, err := docstore.OpenCollection(ctx, "mongo://my-db/my-collection?id_field=userID") + if err != nil { + log.Fatal(err) + } + defer coll.Close() +} diff --git a/go-cloud/docstore/mongodocstore/go.mod b/go-cloud/docstore/mongodocstore/go.mod new file mode 100644 index 000000000..7d5ff5dcd --- /dev/null +++ b/go-cloud/docstore/mongodocstore/go.mod @@ -0,0 +1,80 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +module gocloud.dev/docstore/mongodocstore + +go 1.24 + +require ( + github.com/google/go-cmp v0.7.0 + github.com/google/wire v0.6.0 + go.mongodb.org/mongo-driver v1.17.4 + gocloud.dev v0.43.0 +) + +require ( + cloud.google.com/go/auth v0.16.3 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + cloud.google.com/go/compute/metadata v0.7.0 // indirect + github.com/aws/aws-sdk-go v1.55.7 // indirect + github.com/aws/aws-sdk-go-v2 v1.36.5 // indirect + github.com/aws/aws-sdk-go-v2/config v1.29.17 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.70 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 // indirect + github.com/aws/smithy-go v1.22.4 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/google/go-replayers/grpcreplay v1.3.0 // indirect + github.com/google/go-replayers/httpreplay v1.2.0 // indirect + github.com/google/martian/v3 v3.3.3 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/montanaflynn/stats v0.7.1 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect + go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/sdk v1.37.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect + go.opentelemetry.io/otel/trace v1.37.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + google.golang.org/api v0.242.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 // indirect + google.golang.org/grpc v1.73.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect +) diff --git a/go-cloud/docstore/mongodocstore/go.sum b/go-cloud/docstore/mongodocstore/go.sum new file mode 100644 index 000000000..20a5b81aa --- /dev/null +++ b/go-cloud/docstore/mongodocstore/go.sum @@ -0,0 +1,689 @@ +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +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.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= +cloud.google.com/go v0.121.4 h1:cVvUiY0sX0xwyxPwdSU2KsF9knOVmtRyAMt8xou0iTs= +cloud.google.com/go v0.121.4/go.mod h1:XEBchUiHFJbz4lKBZwYBDHV/rSyfFktk737TLDU089s= +cloud.google.com/go/auth v0.16.3 h1:kabzoQ9/bobUmnseYnBO6qQG7q4a/CffFRlJSxv2wCc= +cloud.google.com/go/auth v0.16.3/go.mod h1:NucRGjaXfzP1ltpcQ7On/VTZ0H4kWB5Jy+Y9Dnm76fA= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/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/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= +cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +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.18.0 h1:cuydCaLS7Vl2SatAeivXyhbhDEIR8BDmtn4egDhIn2s= +cloud.google.com/go/firestore v1.18.0/go.mod h1:5ye0v48PhseZBdcl0qbl3uttu7FIEwEYVaWm0UIEOEU= +cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= +cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= +cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= +cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM= +cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U= +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= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.55.0 h1:NESjdAToN9u1tmhVqhXCaCwYBuvEhZLLv0gBr+2znf0= +cloud.google.com/go/storage v1.55.0/go.mod h1:ztSmTTwzsdXe5syLVS0YsbFxXuvEmEyZj7v7zChEmuY= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0= +github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2/config v1.29.17 h1:jSuiQ5jEe4SAMH6lLRMY9OVC+TqJLP5655pBGjmnjr0= +github.com/aws/aws-sdk-go-v2/config v1.29.17/go.mod h1:9P4wwACpbeXs9Pm9w1QTh6BwWwJjwYvJ1iCt5QbCXh8= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70 h1:ONnH5CM16RTXRkS8Z1qg7/s2eDOhHhaXVd72mmyv4/0= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70/go.mod h1:M+lWhhmomVGgtuPOhO85u4pEa3SmssPTdcYpP/5J/xc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 h1:KAXP9JSHO1vKGCr5f4O6WmlVKLFFXgWYAGoJosorxzU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32/go.mod h1:h4Sg6FQdexC1yYG9RDnOvLbW1a/P986++/Y/a+GyEM8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 h1:t0E6FzREdtCsiLIoLCWsYliNsRBgyGD/MCK571qk4MI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17/go.mod h1:ygpklyoaypuyDvOM5ujWGrYWpAK3h7ugnmKCU/76Ys4= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 h1:AIRJ3lfb2w/1/8wOOSqYb9fUKGwQbtysJ2H1MofRUPg= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5/go.mod h1:b7SiVprpU+iGazDUqvRSLf5XmCdn+JtT1on7uNL6Ipc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 h1:BpOxT3yhLwSJ77qIY3DoHAQjZsc4HEGfMCE4NGy3uFg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3/go.mod h1:vq/GQR1gOFLquZMSrxUK/cpvKCNVYibNyJ1m7JrU88E= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 h1:NFOJ/NXEGV4Rq//71Hs1jC/NvPs1ezajK+yQmkwnPV0= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0/go.mod h1:7ph2tGpfQvwzgistp2+zga9f+bCjlQJPkPUmMgDSD7w= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +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= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +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/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= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +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/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= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-replayers/grpcreplay v1.3.0 h1:1Keyy0m1sIpqstQmgz307zhiJ1pV4uIlFds5weTmxbo= +github.com/google/go-replayers/grpcreplay v1.3.0/go.mod h1:v6NgKtkijC0d3e3RW8il6Sy5sqRVUwoQa4mHOGEy8DI= +github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk= +github.com/google/go-replayers/httpreplay v1.2.0/go.mod h1:WahEFFZZ7a1P4VM1qEeHy+tME4bwyqPcwWbNlUI1Mcg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= +github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +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.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= +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/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= +github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw= +go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0 h1:B+WbN9RPsvobe6q4vP6KgM8/9plR/HNjgGBrfcOlweA= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0/go.mod h1:K5zQ3TT7p2ru9Qkzk0bKtCql0RGkPj9pRjpXgZJZ+rU= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 h1:rbRJ8BBoVMsQShESYZ0FkvcITu8X8QNwJogcLUmDNNw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0/go.mod h1:ru6KHrNtNHxM4nD/vd6QrLVWgKhxPYgblq4VAtNawTQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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/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= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +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-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= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/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.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-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/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +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.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +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-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +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.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.242.0 h1:7Lnb1nfnpvbkCiZek6IXKdJ0MFuAZNAJKQfA1ws62xg= +google.golang.org/api v0.242.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= +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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +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= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 h1:Nt6z9UHqSlIdIGJdz6KhTIs2VRx/iOsA5iE8bmQNcxs= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79/go.mod h1:kTmlBHMPqR5uCZPBvwa2B18mvubkjyY3CRLI0c6fj0s= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79 h1:iOye66xuaAK0WnkPuhQPUFy8eJcmwUXqGGP3om6IxX8= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79/go.mod h1:HKJDgKsFUnv5VAGeQjz8kxcgDP0HoE0iZNp0OdZNlhE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 h1:1ZwqphdOdWYXsUHgMpU/101nCtf/kSp9hOrcvFsnl10= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +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.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/go-cloud/docstore/mongodocstore/localmongo.sh b/go-cloud/docstore/mongodocstore/localmongo.sh new file mode 100755 index 000000000..a201ccd1a --- /dev/null +++ b/go-cloud/docstore/mongodocstore/localmongo.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Starts two local MongoDB instances (v3 and v4) via Docker listening on two +# different ports. + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +set -euo pipefail + +echo "Starting MongoDB v4 listening on 27017..." +docker rm -f mongo4 mongosetup &> /dev/null || : +docker compose -f ./docstore/mongodocstore/docker-compose.yml up --wait &> /dev/null +sleep 3 +echo "...done. Run \"docker rm -f mongo4 mongosetup\" to clean up the container." +echo + +echo "Starting MongoDB v3 listening on 27020..." +docker rm -f mongo3 &> /dev/null || : +docker run -d --name mongo3 -p 27020:27017 mongo:3 &> /dev/null +echo "...done. Run \"docker rm -f mongo3\" to clean up the container." +echo + diff --git a/go-cloud/docstore/mongodocstore/mongo.go b/go-cloud/docstore/mongodocstore/mongo.go new file mode 100644 index 000000000..98c520823 --- /dev/null +++ b/go-cloud/docstore/mongodocstore/mongo.go @@ -0,0 +1,846 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mongodocstore provides a docstore implementation for MongoDB +// and MongoDB-compatible services hosted on-premise or by cloud providers, +// including Amazon DocumentDB and Azure Cosmos DB. +// +// # URLs +// +// For docstore.OpenCollection, mongodocstore registers for the scheme "mongo". +// The default URL opener will dial a Mongo server using the environment +// variable "MONGO_SERVER_URL". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # Action Lists +// +// mongodocstore uses the unordered BulkWrite call of the underlying driver for writes, and uses Find with a list of document IDs for Get. +// (These implementation choices are subject to change.) +// It calls the BeforeDo function once before each call to the underlying driver. The as function passed +// to the BeforeDo function exposes the following types: +// - Gets: *options.FindOptions +// - writes: []mongo.WriteModel and *options.BulkWriteOptions +// +// # As +// +// mongodocstore exposes the following types for As: +// - Collection: *mongo.Collection +// - Query.BeforeQuery: *options.FindOptions or bson.D (the filter for Delete and Update queries) +// - DocumentIterator: *mongo.Cursor +// - Error: mongo.CommandError, mongo.BulkWriteError, mongo.BulkWriteException +// +// # Special Considerations +// +// MongoDB represents times to millisecond precision, while Go's time.Time type has +// nanosecond precision. To save time.Times to MongoDB without loss of precision, +// save the result of calling UnixNano on the time. +// +// The official Go driver for MongoDB, go.mongodb.org/mongo-driver/mongo, lowercases +// struct field names; other docstore drivers do not. This means that you have to choose +// between interoperating with the MongoDB driver and interoperating with other docstore drivers. +// See Options.LowercaseFields for more information. +package mongodocstore // import "gocloud.dev/docstore/mongodocstore" + +// MongoDB reference manual: https://docs.mongodb.com/manual +// Client documentation: https://godoc.org/go.mongodb.org/mongo-driver/mongo +// +// The client methods accept a document of type interface{}, +// which is marshaled by the go.mongodb.org/mongo-driver/bson package. + +import ( + "context" + "reflect" + "strings" + + "github.com/google/wire" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +// Dial returns a new mongoDB client that is connected to the server URI. +func Dial(ctx context.Context, uri string) (*mongo.Client, error) { + opts := options.Client().ApplyURI(uri) + if err := opts.Validate(); err != nil { + return nil, err + } + client, err := mongo.NewClient(opts) + if err != nil { + return nil, err + } + if err := client.Connect(ctx); err != nil { + return nil, err + } + return client, nil +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + Dial, + wire.Struct(new(URLOpener), "Client"), +) + +type collection struct { + coll *mongo.Collection + idField string + idFunc func(docstore.Document) interface{} + revisionField string + opts *Options +} + +// Options holds various options. +type Options struct { + // Lowercase all field names for document encoding, field selection, update + // modifications and queries. + // + // If false (the default), then struct fields and MongoDB document fields will + // have the same names. For example, a struct field F will correspond to a + // MongoDB document field "F". This setting matches the behavior of other + // docstore drivers, making code portable across services. + // + // If true, all fields correspond to lower-cased MongoDB document fields. The + // field name F will correspond to the MongoDB document field "f", for + // instance. Use this to make code that uses this package interoperate with + // code that uses the official Go client for MongoDB, + // go.mongodb.org/mongo-driver/mongo, which lowercases field names. + LowercaseFields bool + // The name of the field holding the document revision. + // Defaults to docstore.DefaultRevisionField. + RevisionField string + // Whether Query.Update writes a new revision into the updated documents. + // The default is false, meaning that a revision will be written to all + // documents that satisfy the query's conditions. Set to true if and only if + // the collection's documents do not have revision fields. + NoWriteQueryUpdateRevisions bool +} + +// OpenCollection opens a MongoDB collection for use with Docstore. +// The idField argument is the name of the document field to use for the document ID +// (MongoDB's _id field). If it is empty, the field "_id" will be used. +func OpenCollection(mcoll *mongo.Collection, idField string, opts *Options) (*docstore.Collection, error) { + dc, err := newCollection(mcoll, idField, nil, opts) + if err != nil { + return nil, err + } + return docstore.NewCollection(dc), nil +} + +// OpenCollectionWithIDFunc opens a MongoDB collection for use with Docstore. +// The idFunc argument is function that accepts a document and returns the value to +// be used for the document ID (MongoDB's _id field). IDFunc should return nil if the +// document is missing the information to construct an ID. This will cause all +// actions, even Create, to fail. +func OpenCollectionWithIDFunc(mcoll *mongo.Collection, idFunc func(docstore.Document) interface{}, opts *Options) (*docstore.Collection, error) { + dc, err := newCollection(mcoll, "", idFunc, opts) + if err != nil { + return nil, err + } + return docstore.NewCollection(dc), nil +} + +func newCollection(mcoll *mongo.Collection, idField string, idFunc func(docstore.Document) interface{}, opts *Options) (*collection, error) { + if opts == nil { + opts = &Options{} + } + if opts.RevisionField == "" { + opts.RevisionField = docstore.DefaultRevisionField + } + c := &collection{ + coll: mcoll, + idField: idField, + idFunc: idFunc, + revisionField: opts.RevisionField, + opts: opts, + } + if c.idField == "" && c.idFunc == nil { + c.idField = mongoIDField + } + + if opts.LowercaseFields { + c.idField = strings.ToLower(c.idField) + c.revisionField = strings.ToLower(c.revisionField) + } + return c, nil +} + +func (c *collection) Key(doc driver.Document) (interface{}, error) { + if c.idField != "" { + id, _ := doc.GetField(c.idField) + return id, nil // missing field is not an error + } + id := c.idFunc(doc.Origin) + if id == nil || driver.IsEmptyValue(reflect.ValueOf(id)) { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "missing document key") + } + return id, nil +} + +func (c *collection) RevisionField() string { + return c.opts.RevisionField +} + +// From https://docs.mongodb.com/manual/core/document: "The field name _id is +// reserved for use as a primary key; its value must be unique in the collection, is +// immutable, and may be of any type other than an array." +const mongoIDField = "_id" + +func (c *collection) RunActions(ctx context.Context, actions []*driver.Action, opts *driver.RunActionsOptions) driver.ActionListError { + errs := make([]error, len(actions)) + beforeGets, gets, writes, writesTx, afterGets := driver.GroupActions(actions) + c.runGets(ctx, beforeGets, errs, opts) + ch := make(chan []error) + go func() { ch <- c.bulkWrite(ctx, writes, errs, opts) }() + ch2 := make(chan []error) + go func() { ch2 <- c.txWrite(ctx, writesTx, errs, opts) }() + c.runGets(ctx, gets, errs, opts) + writeErrs := <-ch + <-ch2 + c.runGets(ctx, afterGets, errs, opts) + alerr := driver.NewActionListError(errs) + for _, werr := range writeErrs { + alerr = append(alerr, indexedError{-1, werr}) + } + return alerr +} + +type indexedError = struct { + Index int + Err error +} + +func (c *collection) runGets(ctx context.Context, gets []*driver.Action, errs []error, opts *driver.RunActionsOptions) { + // TODO(shantuo): figure out a reasonable batch size, there is no hard limit on + // the item number or filter string length. The limit for bulk write batch size + // is 100,000. + for _, group := range driver.GroupByFieldPath(gets) { + c.bulkFind(ctx, group, errs, opts) + } +} + +func (c *collection) bulkFind(ctx context.Context, gets []*driver.Action, errs []error, dopts *driver.RunActionsOptions) { + // errors need to be mapped to the actions' indices. + setErr := func(err error) { + for _, get := range gets { + if errs[get.Index] == nil { + errs[get.Index] = err + } + } + } + + opts := options.Find() + if len(gets[0].FieldPaths) > 0 { + opts.Projection = c.projectionDoc(gets[0].FieldPaths) + } + ids := bson.A{} + idToAction := map[interface{}]*driver.Action{} + for _, a := range gets { + id, err := encodeValue(a.Key) + if err != nil { + errs[a.Index] = err + } else { + ids = append(ids, id) + idToAction[id] = a + } + } + if dopts.BeforeDo != nil { + if err := dopts.BeforeDo(driver.AsFunc(opts)); err != nil { + setErr(err) + return + } + } + cursor, err := c.coll.Find(ctx, bson.D{bson.E{Key: mongoIDField, Value: bson.D{{Key: "$in", Value: ids}}}}, opts) + if err != nil { + setErr(err) + return + } + defer cursor.Close(ctx) + + found := make(map[*driver.Action]bool) + for cursor.Next(ctx) { + var m map[string]interface{} + if err := cursor.Decode(&m); err != nil { + continue + } + a := idToAction[m[mongoIDField]] + errs[a.Index] = decodeDoc(m, a.Doc, c.idField, c.opts.LowercaseFields) + found[a] = true + } + for _, a := range gets { + if !found[a] { + errs[a.Index] = gcerr.Newf(gcerr.NotFound, nil, "item with key %v not found", a.Key) + } + } +} + +// Construct a mongo "projection document" from field paths. +// Always include the revision field. +func (c *collection) projectionDoc(fps [][]string) bson.D { + proj := bson.D{{Key: c.revisionField, Value: 1}} + for _, fp := range fps { + path := c.toMongoFieldPath(fp) + if path != c.revisionField { + proj = append(proj, bson.E{Key: path, Value: 1}) + } + } + return proj +} + +func (c *collection) toMongoFieldPath(fp []string) string { + if c.opts.LowercaseFields { + sliceToLower(fp) + } + return strings.Join(fp, ".") +} + +func sliceToLower(s []string) { + for i, e := range s { + s[i] = strings.ToLower(e) + } +} + +func (c *collection) prepareCreate(a *driver.Action) (mdoc, createdID interface{}, rev string, err error) { + id := a.Key + if id == nil { + // Create a unique ID here. (The MongoDB Go client does this for us when calling InsertOne, + // but not for BulkWrite.) + id = primitive.NewObjectID() + createdID = id + } else { + id, err = encodeValue(id) + if err != nil { + return nil, nil, "", err + } + } + mdoc, rev, err = c.encodeDoc(a.Doc, id) + if err != nil { + return nil, nil, "", err + } + return mdoc, createdID, rev, nil +} + +func (c *collection) prepareReplace(a *driver.Action) (filter bson.D, mdoc map[string]interface{}, rev string, err error) { + id, err := encodeValue(a.Key) + if err != nil { + return nil, nil, "", err + } + filter, _, err = c.makeFilter(id, a.Doc) + if err != nil { + return nil, nil, "", err + } + mdoc, rev, err = c.encodeDoc(a.Doc, id) + if err != nil { + return nil, nil, "", err + } + return filter, mdoc, rev, nil +} + +// encodeDoc encodes doc and sets its ID to the encoded value id. It also creates a new revision and sets it. +// It returns the encoded document and the new revision. +func (c *collection) encodeDoc(doc driver.Document, id interface{}) (map[string]interface{}, string, error) { + mdoc, err := encodeDoc(doc, c.opts.LowercaseFields) + if err != nil { + return nil, "", err + } + if id != nil { + if c.idField != "" { + delete(mdoc, c.idField) + } + mdoc[mongoIDField] = id + } + var rev string + if c.hasField(doc, c.revisionField) { + rev = driver.UniqueString() + mdoc[c.revisionField] = rev + } + return mdoc, rev, nil +} + +func (c *collection) prepareUpdate(a *driver.Action) (filter bson.D, updateDoc map[string]bson.D, rev string, err error) { + id, err := encodeValue(a.Key) + if err != nil { + return nil, nil, "", err + } + filter, _, err = c.makeFilter(id, a.Doc) + if err != nil { + return nil, nil, "", err + } + updateDoc, rev, err = c.newUpdateDoc(a.Mods, c.hasField(a.Doc, c.revisionField)) + if err != nil { + return nil, nil, "", err + } + return filter, updateDoc, rev, nil +} + +func (c *collection) newUpdateDoc(mods []driver.Mod, writeRevision bool) (map[string]bson.D, string, error) { + var ( + sets bson.D + unsets bson.D + incs bson.D + ) + for _, m := range mods { + key := c.toMongoFieldPath(m.FieldPath) + if m.Value == nil { + unsets = append(unsets, bson.E{Key: key, Value: ""}) + } else if inc, ok := m.Value.(driver.IncOp); ok { + val, err := encodeValue(inc.Amount) + if err != nil { + return nil, "", err + } + incs = append(incs, bson.E{Key: key, Value: val}) + } else { + val, err := encodeValue(m.Value) + if err != nil { + return nil, "", err + } + sets = append(sets, bson.E{Key: key, Value: val}) + } + } + updateDoc := map[string]bson.D{} + var rev string + if writeRevision { + rev = driver.UniqueString() + sets = append(sets, bson.E{Key: c.revisionField, Value: rev}) + } + if len(sets) > 0 { + updateDoc["$set"] = sets + } + if len(unsets) > 0 { + updateDoc["$unset"] = unsets + } + if len(incs) > 0 { + updateDoc["$inc"] = incs + } + return updateDoc, rev, nil +} + +// makeFilter constructs a filter using the given encoded id and the document's revision field, if any. +func (c *collection) makeFilter(id interface{}, doc driver.Document) (filter bson.D, rev interface{}, err error) { + rev, err = doc.GetField(c.revisionField) + if err != nil && gcerrors.Code(err) != gcerrors.NotFound { + return nil, nil, err + } + // Only select the document with the given ID. + filter = bson.D{bson.E{Key: "_id", Value: id}} + // If the given document has a revision, it must match the stored document. + if rev != nil { + filter = append(filter, bson.E{Key: c.revisionField, Value: rev}) + } + return filter, rev, nil +} + +// bulkWrite calls the Mongo driver's BulkWrite RPC in unordered mode with the +// actions, which must be writes. +// errs is the slice of errors indexed by the position of the action in the original +// action list. bulkWrite populates this slice. In addition, bulkWrite returns a list +// of errors that cannot be attributed to any single action. +func (c *collection) bulkWrite(ctx context.Context, actions []*driver.Action, errs []error, dopts *driver.RunActionsOptions) []error { + var ( + models []mongo.WriteModel + modelActions []*driver.Action // corresponding action for each model + newIDs []interface{} // new IDs for Create actions, corresponding to models slice + revs []string // new revisions, corresponding to models slice + nDeletes int64 + nNonCreateWrite int64 // total operations expected from Put, Replace and Update + ) + for _, a := range actions { + var m mongo.WriteModel + var err error + var newID interface{} + var rev string + switch a.Kind { + case driver.Create: + m, newID, rev, err = c.newCreateModel(a) + case driver.Delete: + m, err = c.newDeleteModel(a) + if err == nil { + nDeletes++ + } + case driver.Replace, driver.Put: + m, rev, err = c.newReplaceModel(a, a.Kind == driver.Put) + if err == nil { + nNonCreateWrite++ + } + case driver.Update: + m, rev, err = c.newUpdateModel(a) + if err == nil && m != nil { + nNonCreateWrite++ + } + default: + err = gcerr.Newf(gcerr.Internal, nil, "bad action %+v", a) + } + if err != nil { + errs[a.Index] = err + } else if m != nil { // m can be nil for a no-op update + models = append(models, m) + modelActions = append(modelActions, a) + newIDs = append(newIDs, newID) + revs = append(revs, rev) + } + } + if len(models) == 0 { + return nil + } + + bopts := options.BulkWrite().SetOrdered(false) + if dopts.BeforeDo != nil { + asFunc := func(target interface{}) bool { + switch t := target.(type) { + case *[]mongo.WriteModel: + *t = models + case **options.BulkWriteOptions: + *t = bopts + default: + return false + } + return true + } + if err := dopts.BeforeDo(asFunc); err != nil { + return []error{err} + } + } + + // TODO(jba): improve independent execution. I think that even if BulkWrite returns an error, + // some of the actions may have succeeded. + var reterrs []error + res, err := c.coll.BulkWrite(ctx, models, bopts) + if err != nil { + bwe, ok := err.(mongo.BulkWriteException) + if !ok { // assume everything failed with this error + return []error{err} + } + // The returned indexes of the WriteErrors are wrong. See https://jira.mongodb.org/browse/GODRIVER-1028. + // Until it's fixed, use negative values for the indexes in the errors we return. + for _, w := range bwe.WriteErrors { + reterrs = append(reterrs, gcerr.Newf(translateMongoCode(w.Code), w, "%s", w.Message)) + } + return reterrs + } + for i, newID := range newIDs { + if newID == nil { + continue + } + a := modelActions[i] + if err := a.Doc.SetField(c.idField, newID); err != nil { + errs[a.Index] = err + } + } + for i, rev := range revs { + a := modelActions[i] + if rev != "" && c.hasField(a.Doc, c.revisionField) { + if err := a.Doc.SetField(c.revisionField, rev); err != nil && errs[a.Index] == nil { + errs[a.Index] = err + } + } + } + if res.DeletedCount != nDeletes { + // Some Delete actions failed. It's not an error if a Delete failed because + // the document didn't exist, but it is an error if it failed because of a + // precondition mismatch. Find all the documents with revisions we tried to delete; if + // any are still present, that's an error. + c.determineDeleteErrors(ctx, models, modelActions, errs) + } + if res.MatchedCount+res.UpsertedCount != nNonCreateWrite { + reterrs = append(reterrs, gcerr.Newf(gcerr.NotFound, nil, "some writes failed (replaced %d, upserted %d, out of total %d)", res.MatchedCount, res.UpsertedCount, nNonCreateWrite)) + } + return reterrs +} + +func (c *collection) txWrite(ctx context.Context, actions []*driver.Action, errs []error, dopts *driver.RunActionsOptions) []error { + var ( + models []mongo.WriteModel + modelActions []*driver.Action // corresponding action for each model + newIDs []interface{} // new IDs for Create actions, corresponding to models slice + revs []string // new revisions, corresponding to models slice + nDeletes int64 + nNonCreateWrite int64 // total operations expected from Put, Replace and Update + ) + + // all actions will fail atomically even if a single action fails + setErr := func(err error) { + for _, a := range actions { + errs[a.Index] = err + } + } + + for _, a := range actions { + var m mongo.WriteModel + var err error + var newID interface{} + var rev string + switch a.Kind { + case driver.Create: + m, newID, rev, err = c.newCreateModel(a) + case driver.Delete: + m, err = c.newDeleteModel(a) + if err == nil { + nDeletes++ + } + case driver.Replace, driver.Put: + m, rev, err = c.newReplaceModel(a, a.Kind == driver.Put) + if err == nil { + nNonCreateWrite++ + } + case driver.Update: + m, rev, err = c.newUpdateModel(a) + if err == nil && m != nil { + nNonCreateWrite++ + } + default: + err = gcerr.Newf(gcerr.Internal, nil, "bad action %+v", a) + } + if err != nil { + setErr(err) + return nil + } else if m != nil { // m can be nil for a no-op update + models = append(models, m) + modelActions = append(modelActions, a) + newIDs = append(newIDs, newID) + revs = append(revs, rev) + } + } + if len(models) == 0 { + return nil + } + + bopts := options.BulkWrite().SetOrdered(true) + if dopts.BeforeDo != nil { + asFunc := func(target interface{}) bool { + switch t := target.(type) { + case *[]mongo.WriteModel: + *t = models + case **options.BulkWriteOptions: + *t = bopts + default: + return false + } + return true + } + if err := dopts.BeforeDo(asFunc); err != nil { + return []error{err} + } + } + + client := c.coll.Database().Client() + session, err := client.StartSession() + if err != nil { + setErr(err) + return nil + } + defer session.EndSession(ctx) + + callback := func(sessionCtx mongo.SessionContext) error { + if err := session.StartTransaction(); err != nil { + return err + } + + res, err := c.coll.BulkWrite(sessionCtx, models, bopts) + if res.DeletedCount != nDeletes { + // Some Delete actions failed. It's not an error if a Delete failed because + // the document didn't exist, but it is an error if it failed because of a + // precondition mismatch. Find all the documents with revisions we tried to delete; if + // any are still present, that's an error. + if c.determineDeleteErrors(ctx, models, modelActions, errs) { + setErr(gcerr.Newf(gcerr.FailedPrecondition, nil, + "wrong revision for document to be deleted")) + } + } + if res.MatchedCount+res.UpsertedCount != nNonCreateWrite { + err = gcerr.Newf(gcerr.NotFound, nil, "some writes failed (replaced %d, upserted %d, out of total %d)", res.MatchedCount, res.UpsertedCount, nNonCreateWrite) + } + if err != nil { + abortTxErr := session.AbortTransaction(context.Background()) + if abortTxErr != nil { + return err + } + return err + } + + if err = session.CommitTransaction(sessionCtx); err != nil { + return err + } + + return nil + } + + err = mongo.WithSession(ctx, session, callback) + + if err != nil { + setErr(err) + return nil + } + return nil +} + +// determineDeleteErrors find the errors for the delete and return true if found any +func (c *collection) determineDeleteErrors(ctx context.Context, models []mongo.WriteModel, actions []*driver.Action, errs []error) bool { + // TODO(jba): do this concurrently. + foundErr := false + for i, m := range models { + if dm, ok := m.(*mongo.DeleteOneModel); ok { + filter := dm.Filter.(bson.D) + if len(filter) > 1 { + // Delete with both ID and revision. See if the document is still there. + idOnlyFilter := filter[:1] + // TODO(shantuo): use Find instead of FindOne. + res := c.coll.FindOne(ctx, idOnlyFilter) + + // Assume an error means the document wasn't found. + // That means either that it was deleted successfully, or that it never + // existed. Either way, it's not an error. + // TODO(jba): distinguish between not found and other errors. + if res.Err() == nil { + // The document exists, but we didn't delete it: assume we had the wrong + // revision. + errs[actions[i].Index] = gcerr.Newf(gcerr.FailedPrecondition, nil, + "wrong revision for document with ID %v", actions[i].Key) + foundErr = true + } + } + } + } + return foundErr +} + +func (c *collection) newCreateModel(a *driver.Action) (*mongo.InsertOneModel, interface{}, string, error) { + mdoc, createdID, rev, err := c.prepareCreate(a) + if err != nil { + return nil, nil, "", err + } + return &mongo.InsertOneModel{Document: mdoc}, createdID, rev, nil +} + +func (c *collection) newDeleteModel(a *driver.Action) (*mongo.DeleteOneModel, error) { + id, err := encodeValue(a.Key) + if err != nil { + return nil, err + } + filter, _, err := c.makeFilter(id, a.Doc) + if err != nil { + return nil, err + } + return &mongo.DeleteOneModel{Filter: filter}, nil +} + +func (c *collection) newReplaceModel(a *driver.Action, upsert bool) (*mongo.ReplaceOneModel, string, error) { + filter, mdoc, rev, err := c.prepareReplace(a) + if err != nil { + return nil, "", err + } + return &mongo.ReplaceOneModel{ + Filter: filter, + Replacement: mdoc, + Upsert: &upsert, + }, rev, nil +} + +func (c *collection) newUpdateModel(a *driver.Action) (*mongo.UpdateOneModel, string, error) { + filter, updateDoc, rev, err := c.prepareUpdate(a) + if err != nil { + return nil, "", err + } + if filter == nil { // no-op + return nil, "", nil + } + return &mongo.UpdateOneModel{Filter: filter, Update: updateDoc}, rev, nil +} + +// RevisionToBytes implements driver.RevisionToBytes. +func (c *collection) RevisionToBytes(rev interface{}) ([]byte, error) { + s, ok := rev.(string) + if !ok { + return nil, gcerr.Newf(gcerr.InvalidArgument, nil, "revision %v of type %[1]T is not a string", rev) + } + return []byte(s), nil +} + +func (c *collection) hasField(doc driver.Document, field string) bool { + if c.opts.LowercaseFields { + return doc.HasFieldFold(field) + } + return doc.HasField(field) +} + +// BytesToRevision implements driver.BytesToRevision. +func (c *collection) BytesToRevision(b []byte) (interface{}, error) { + return string(b), nil +} + +// As implements driver.As. +func (c *collection) As(i interface{}) bool { + p, ok := i.(**mongo.Collection) + if !ok { + return false + } + *p = c.coll + return true +} + +// ErrorAs implements driver.Collection.ErrorAs +func (c *collection) ErrorAs(err error, i interface{}) bool { + switch e := err.(type) { + case mongo.CommandError: + if p, ok := i.(*mongo.CommandError); ok { + *p = e + return true + } + case mongo.BulkWriteError: + if p, ok := i.(*mongo.BulkWriteError); ok { + *p = e + return true + } + case mongo.BulkWriteException: + if p, ok := i.(*mongo.BulkWriteException); ok { + *p = e + return true + } + } + return false +} + +// ErrorCode implements driver.Collection.ErrorCode. +func (c *collection) ErrorCode(err error) gcerrors.ErrorCode { + if g, ok := err.(*gcerr.Error); ok { + return g.Code + } + if err == mongo.ErrNoDocuments { + return gcerrors.NotFound + } + if wexc, ok := err.(mongo.WriteException); ok && len(wexc.WriteErrors) > 0 { + return translateMongoCode(wexc.WriteErrors[0].Code) + } + return gcerrors.Unknown +} + +// Close implements driver.Collection.Close. +func (c *collection) Close() error { return nil } + +// Error code for a write error when no documents match a filter. +// (The Go mongo driver doesn't define an exported constant for this.) +const mongoDupKeyCode = 11000 + +func translateMongoCode(code int) gcerrors.ErrorCode { + switch code { + case mongoDupKeyCode: + return gcerrors.AlreadyExists + default: + return gcerrors.Unknown + } +} diff --git a/go-cloud/docstore/mongodocstore/mongo_test.go b/go-cloud/docstore/mongodocstore/mongo_test.go new file mode 100644 index 000000000..5aadea8cb --- /dev/null +++ b/go-cloud/docstore/mongodocstore/mongo_test.go @@ -0,0 +1,332 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mongodocstore + +// To run these tests against a real MongoDB server, first run ./localmongo.sh. +// Then wait a few seconds for the server to be ready. + +import ( + "context" + "errors" + "fmt" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/docstore/drivertest" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" +) + +const ( + serverURIV3 = "mongodb://localhost:27020" + serverURIV4 = "mongodb://localhost:27017/?directConnection=true" + dbName = "docstore-test" + collectionName1 = "docstore-test-1" + collectionName2 = "docstore-test-2" + collectionName3 = "docstore-test-3" +) + +type harness struct { + db *mongo.Database + supportAtomicWrites bool +} + +func (h *harness) MakeCollection(ctx context.Context, kind drivertest.CollectionKind) (driver.Collection, error) { + var coll *collection + var err error + switch kind { + case drivertest.SingleKey: + coll, err = newCollection(h.db.Collection(collectionName1), drivertest.KeyField, nil, nil) + case drivertest.TwoKey: + coll, err = newCollection(h.db.Collection(collectionName2), "", drivertest.HighScoreKey, nil) + case drivertest.AltRev: + coll, err = newCollection(h.db.Collection(collectionName1), drivertest.KeyField, nil, + &Options{RevisionField: drivertest.AlternateRevisionField}) + case drivertest.NoRev: + coll, err = newCollection(h.db.Collection(collectionName1), drivertest.KeyField, nil, + &Options{NoWriteQueryUpdateRevisions: true}) + default: + panic("bad kind") + } + if err != nil { + return nil, err + } + // It seems that the client doesn't actually connect until the first RPC. So + // time out quickly if there's a problem. + tctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + if err := coll.coll.Drop(tctx); err != nil { + return nil, err + } + return coll, nil +} + +func (h *harness) SupportsAtomicWrites() bool { return h.supportAtomicWrites } + +func (*harness) BeforeDoTypes() []interface{} { + return []interface{}{ + []mongo.WriteModel{}, + &options.FindOptions{}, + } +} + +func (*harness) BeforeQueryTypes() []interface{} { + return []interface{}{&options.FindOptions{}, bson.D{}} +} + +func (*harness) RevisionsEqual(rev1, rev2 interface{}) bool { + return rev1 == rev2 +} + +func (*harness) Close() {} + +type codecTester struct{} + +func (codecTester) UnsupportedTypes() []drivertest.UnsupportedType { + return []drivertest.UnsupportedType{drivertest.NanosecondTimes} +} + +func (codecTester) DocstoreEncode(x interface{}) (interface{}, error) { + m, err := encodeDoc(drivertest.MustDocument(x), true) + if err != nil { + return nil, err + } + return bson.Marshal(m) +} + +func (codecTester) DocstoreDecode(value, dest interface{}) error { + var m map[string]interface{} + if err := bson.Unmarshal(value.([]byte), &m); err != nil { + return err + } + return decodeDoc(m, drivertest.MustDocument(dest), mongoIDField, true) +} + +func (codecTester) NativeEncode(x interface{}) (interface{}, error) { + return bson.Marshal(x) +} + +func (codecTester) NativeDecode(value, dest interface{}) error { + return bson.Unmarshal(value.([]byte), dest) +} + +type verifyAs struct{} + +func (verifyAs) Name() string { + return "verify As" +} + +func (verifyAs) CollectionCheck(coll *docstore.Collection) error { + var mc *mongo.Collection + if !coll.As(&mc) { + return errors.New("Collection.As failed") + } + return nil +} + +func (verifyAs) QueryCheck(it *docstore.DocumentIterator) error { + var c *mongo.Cursor + if !it.As(&c) { + return errors.New("DocumentIterator.As failed") + } + return nil +} + +func (verifyAs) ErrorCheck(c *docstore.Collection, err error) error { + var cmderr mongo.CommandError + var bwerr mongo.BulkWriteError + var bwexc mongo.BulkWriteException + if !c.ErrorAs(err, &cmderr) && !c.ErrorAs(err, &bwerr) && !c.ErrorAs(err, &bwexc) { + if e, ok := err.(*gcerr.Error); ok { + err = e.Unwrap() + } + return fmt.Errorf("Collection.ErrorAs failed, got %T", err) + } + return nil +} + +func TestConformance(t *testing.T) { + // mongo 3 doesn't support atomic writes + t.Run("V3", func(t *testing.T) { testConformance(t, serverURIV3, false) }) + t.Run("V4", func(t *testing.T) { testConformance(t, serverURIV4, true) }) +} + +func testConformance(t *testing.T, serverURI string, supportsAtomicWrites bool) { + client := newTestClient(t, serverURI) + defer client.Disconnect(context.Background()) + + newHarness := func(context.Context, *testing.T) (drivertest.Harness, error) { + return &harness{client.Database(dbName), supportsAtomicWrites}, nil + } + drivertest.RunConformanceTests(t, newHarness, codecTester{}, []drivertest.AsTest{verifyAs{}}) +} + +func newTestClient(t *testing.T, serverURI string) *mongo.Client { + if !setup.HasDockerTestEnvironment() { + t.Skip("Skipping Mongo tests since the Mongo server is not available") + } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + client, err := Dial(ctx, serverURI) + if err != nil { + t.Fatalf("dialing to %s: %v", serverURI, err) + } + if err := client.Ping(ctx, nil); err != nil { + t.Fatalf("connecting to %s: %v", serverURI, err) + } + return client +} + +func BenchmarkConformance(b *testing.B) { + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + // Only run benchmark once (against MongoDB v4). + client, err := Dial(ctx, serverURIV4) + if err != nil { + b.Fatalf("dialing to %s: %v", serverURIV4, err) + } + if err := client.Ping(ctx, nil); err != nil { + b.Fatalf("connecting to %s: %v", serverURIV4, err) + } + defer func() { client.Disconnect(context.Background()) }() + + db := client.Database(dbName) + coll, err := newCollection(db.Collection(collectionName3), drivertest.KeyField, nil, nil) + if err != nil { + b.Fatal(err) + } + drivertest.RunBenchmarks(b, docstore.NewCollection(coll)) +} + +// Mongo-specific tests. + +// Testing the driver lower all fields in lowercaseFields mode to match the +// behavior of the official Go MongoDB client library. +func TestLowercaseFields(t *testing.T) { + // Verify that the LowercaseFields option works in all cases. + must := func(err error) { + t.Helper() + if err != nil { + t.Fatal(err) + } + } + + ctx := context.Background() + client := newTestClient(t, serverURIV4) + defer func() { client.Disconnect(ctx) }() + db := client.Database(dbName) + dc, err := newCollection(db.Collection("lowercase-fields"), "id", nil, &Options{LowercaseFields: true}) + if err != nil { + t.Fatal(err) + } + coll := docstore.NewCollection(dc) + defer coll.Close() + defer drivertest.ClearCollection(t, coll) + + type S struct { + ID, F, G int + DocstoreRevision interface{} + } + + // driver.Document.GetField is case-insensitive on structs. + doc := drivertest.MustDocument(&S{ID: 1, DocstoreRevision: 1}) + for _, f := range []string{"ID", "Id", "id", "DocstoreRevision", "docstorerevision"} { + got, err := doc.GetField(f) + if err != nil { + t.Errorf("%s: %v", f, err) + } + if got != 1 { + t.Errorf("got %q, want 1", got) + } + } + + check := func(got, want interface{}) { + t.Helper() + if !cmp.Equal(got, want) { + t.Errorf("\ngot %+v\nwant %+v", got, want) + } + } + + sdoc := &S{ID: 1, F: 2, G: 3} + must(coll.Put(ctx, sdoc)) + if sdoc.DocstoreRevision == nil { + t.Fatal("revision is nil") + } + + // Get with a struct. + got := S{ID: 1} + must(coll.Get(ctx, &got)) + check(got, S{ID: 1, F: 2, G: 3, DocstoreRevision: sdoc.DocstoreRevision}) + + // Get with map. + got2 := map[string]interface{}{"id": 1} + must(coll.Get(ctx, got2)) + check(got2, map[string]interface{}{ + "id": int64(1), "f": int64(2), "g": int64(3), + "docstorerevision": sdoc.DocstoreRevision, + }) + + // Field paths in Get. + got3 := S{ID: 1} + must(coll.Get(ctx, &got3, "G")) + check(got3, S{ID: 1, F: 0, G: 3, DocstoreRevision: sdoc.DocstoreRevision}) + + // Field paths in Update. + got4 := map[string]interface{}{"id": 1} + udoc := &S{ID: 1} + must(coll.Actions().Update(udoc, docstore.Mods{"F": 4}).Get(got4).Do(ctx)) + check(got4, map[string]interface{}{ + "id": int64(1), "f": int64(4), "g": int64(3), + "docstorerevision": udoc.DocstoreRevision, + }) + + // Query filters. + var got5 S + must(coll.Query().Where("ID", "=", 1).Where("G", ">", 2).Get(ctx).Next(ctx, &got5)) + check(got5, S{ID: 1, F: 4, G: 3, DocstoreRevision: udoc.DocstoreRevision}) + + // Query orders. + sdoc2 := &S{ID: 2, F: 5, G: 6} + must(coll.Put(ctx, sdoc2)) + var got6 S + must(coll.Query().OrderBy("G", docstore.Descending).Get(ctx).Next(ctx, &got6)) + check(got6, *sdoc2) + + // List queries + // select F from coll WHERE G IN (50, 51) ORDER BY G DESC + // test that F is 99 + sdoc3 := &S{ID: 3, F: 99, G: 50} + sdoc4 := &S{ID: 4, F: 99, G: 51} + must(coll.Put(ctx, sdoc3)) + must(coll.Put(ctx, sdoc4)) + var got7, got8 S + iter := coll.Query().Where("G", "in", []int{50, 51}).OrderBy("G", docstore.Descending).Get(ctx) + must(iter.Next(ctx, &got7)) + must(iter.Next(ctx, &got8)) + check(got7, *sdoc4) + check(got8, *sdoc3) + + // same query with not-in, expect to get sdoc2 back even though G is higher for sdoc3 and sdoc4 + var got9 S + must(coll.Query().Where("G", "not-in", []int{50, 51}).OrderBy("G", docstore.Descending).Get(ctx).Next(ctx, &got9)) + check(got9, *sdoc2) +} diff --git a/go-cloud/docstore/mongodocstore/query.go b/go-cloud/docstore/mongodocstore/query.go new file mode 100644 index 000000000..3ba115b51 --- /dev/null +++ b/go-cloud/docstore/mongodocstore/query.go @@ -0,0 +1,202 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mongodocstore + +import ( + "context" + "fmt" + "io" + "strings" + + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" +) + +func (c *collection) RunGetQuery(ctx context.Context, q *driver.Query) (driver.DocumentIterator, error) { + opts := options.Find() + if len(q.FieldPaths) > 0 { + opts.Projection = c.projectionDoc(q.FieldPaths) + } + if q.Offset > 0 { + offset := int64(q.Offset) + opts.Skip = &offset + } + if q.Limit > 0 { + lim := int64(q.Limit) + opts.Limit = &lim + } + if q.OrderByField != "" { + f := q.OrderByField + if c.opts.LowercaseFields { + f = strings.ToLower(f) + } + var dir int + if q.OrderAscending { + dir = 1 + } else { + dir = -1 + } + opts.Sort = bson.D{{Key: f, Value: dir}} + } + + filter := bson.D{} // must be a zero-length slice, not nil + for _, f := range q.Filters { + bf, err := c.filterToBSON(f) + if err != nil { + return nil, err + } + filter = append(filter, bf) + } + if q.BeforeQuery != nil { + if err := q.BeforeQuery(driver.AsFunc(opts)); err != nil { + return nil, err + } + } + cursor, err := c.coll.Find(ctx, filter, opts) + if err != nil { + return nil, err + } + return &docIterator{cursor: cursor, idField: c.idField, ctx: ctx, lowercaseFields: c.opts.LowercaseFields}, nil +} + +var mongoQueryOps = map[string]string{ + driver.EqualOp: "$eq", + ">": "$gt", + ">=": "$gte", + "<": "$lt", + "<=": "$lte", + "in": "$in", + "not-in": "$nin", +} + +// filtersToBSON converts a []driver.Filter to the MongoDB equivalent, expressed +// as a bson.D (list of key-value pairs). +func (c *collection) filtersToBSON(fs []driver.Filter) (bson.D, error) { + filter := bson.D{} // must be a zero-length slice, not nil + for _, f := range fs { + bf, err := c.filterToBSON(f) + if err != nil { + return nil, err + } + filter = append(filter, bf) + } + return filter, nil +} + +// filterToBSON converts a driver.Filter to the MongoDB equivalent, expressed +// as a bson.E (key-value pair). +// The MongoDB document corresponding to "field op value" is +// +// {field: {mop: value}} +// +// where mop is the mongo version of op (see the mongoQueryOps map above). +func (c *collection) filterToBSON(f driver.Filter) (bson.E, error) { + key := c.toMongoFieldPath(f.FieldPath) + if c.idField != "" && key == c.idField { + key = mongoIDField + } + val, err := encodeValue(f.Value) + if err != nil { + return bson.E{}, err + } + op := mongoQueryOps[f.Op] + if op == "" { + return bson.E{}, fmt.Errorf("no mongo operator for %q", f.Op) + } + return bson.E{Key: key, Value: bson.D{{Key: op, Value: val}}}, nil +} + +type docIterator struct { + cursor *mongo.Cursor + idField string + ctx context.Context // remember for Stop + lowercaseFields bool +} + +func (it *docIterator) Next(ctx context.Context, doc driver.Document) error { + m, err := it.nextMap(ctx) + if err != nil { + return err + } + return decodeDoc(m, doc, it.idField, it.lowercaseFields) +} + +func (it *docIterator) nextMap(ctx context.Context) (map[string]interface{}, error) { + if !it.cursor.Next(ctx) { + if it.cursor.Err() != nil { + return nil, it.cursor.Err() + } + return nil, io.EOF + } + var m map[string]interface{} + if err := it.cursor.Decode(&m); err != nil { + return nil, fmt.Errorf("cursor.Decode: %v", err) + } + return m, nil +} + +func (it *docIterator) Stop() { + // Ignore error on Close. + _ = it.cursor.Close(it.ctx) +} + +func (it *docIterator) As(i interface{}) bool { + p, ok := i.(**mongo.Cursor) + if !ok { + return false + } + *p = it.cursor + return true +} + +func (c *collection) QueryPlan(q *driver.Query) (string, error) { + return "unknown", nil +} + +func (c *collection) RunDeleteQuery(ctx context.Context, q *driver.Query) error { + filter, err := c.filtersToBSON(q.Filters) + if err != nil { + return err + } + if q.BeforeQuery != nil { + if err := q.BeforeQuery(driver.AsFunc(filter)); err != nil { + return err + } + } + _, err = c.coll.DeleteMany(ctx, filter) + return err +} + +func (c *collection) RunUpdateQuery(ctx context.Context, q *driver.Query, mods []driver.Mod) error { + filter, err := c.filtersToBSON(q.Filters) + if err != nil { + return err + } + // TODO(#2458): provide an option for the user to choose whether or not to + // update the revision. + updateDoc, _, err := c.newUpdateDoc(mods, !c.opts.NoWriteQueryUpdateRevisions) + if err != nil { + return err + } + if q.BeforeQuery != nil { + if err := q.BeforeQuery(driver.AsFunc(filter)); err != nil { + return err + } + } + _, err = c.coll.UpdateMany(ctx, filter, updateDoc) + return err +} diff --git a/go-cloud/docstore/mongodocstore/testdata/README b/go-cloud/docstore/mongodocstore/testdata/README new file mode 100644 index 000000000..17d5ffaa7 --- /dev/null +++ b/go-cloud/docstore/mongodocstore/testdata/README @@ -0,0 +1,2 @@ +This directory is here just so that the prerelease script (internal/testing/prerelease.sh) +will run this package's tests with -record. diff --git a/go-cloud/docstore/mongodocstore/urls.go b/go-cloud/docstore/mongodocstore/urls.go new file mode 100644 index 000000000..6b47b0677 --- /dev/null +++ b/go-cloud/docstore/mongodocstore/urls.go @@ -0,0 +1,110 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mongodocstore + +import ( + "context" + "errors" + "fmt" + "net/url" + "os" + "strings" + "sync" + + "go.mongodb.org/mongo-driver/mongo" + "github.com/DataDog/iceberg-go/go-cloud/docstore" +) + +func init() { + docstore.DefaultURLMux().RegisterCollection(Scheme, new(defaultDialer)) +} + +// defaultDialer dials a default Mongo server based on the environment variable +// MONGO_SERVER_URL. +type defaultDialer struct { + mongoServerURL string + mu sync.Mutex + opener *URLOpener + err error +} + +func (o *defaultDialer) OpenCollectionURL(ctx context.Context, u *url.URL) (*docstore.Collection, error) { + o.mu.Lock() + defer o.mu.Unlock() + currentEnv := os.Getenv("MONGO_SERVER_URL") + + if currentEnv == "" { + o.err = errors.New("MONGO_SERVER_URL environment variable is not set") + return nil, fmt.Errorf("open collection %s: %v", u, o.err) + } + + // If MONGO_SERVER_URL has been updated, then update o.opener as well + if currentEnv != o.mongoServerURL { + client, err := Dial(ctx, currentEnv) + if err != nil { + o.err = fmt.Errorf("failed to dial default Mongo server at %q: %v", currentEnv, err) + return nil, fmt.Errorf("open collection %s: %v", u, o.err) + } + o.mongoServerURL = currentEnv + o.opener = &URLOpener{Client: client} + } + return o.opener.OpenCollectionURL(ctx, u) +} + +// Scheme is the URL scheme mongodocstore registers its URLOpener under on +// docstore.DefaultMux. +const Scheme = "mongo" + +// URLOpener opens URLs like "mongo://mydb/mycollection". +// See https://docs.mongodb.com/manual/reference/limits/#naming-restrictions for +// naming restrictions. +// +// The URL Host is used as the database name. +// The URL Path is used as the collection name. +// +// The following query parameters are supported: +// +// - id_field (optional): the field name to use for the "_id" field. +type URLOpener struct { + // A Client is a MongoDB client that performs operations on the db, must be + // non-nil. + Client *mongo.Client + + // Options specifies the options to pass to OpenCollection. + Options Options +} + +// OpenCollectionURL opens the Collection URL. +func (o *URLOpener) OpenCollectionURL(ctx context.Context, u *url.URL) (*docstore.Collection, error) { + q := u.Query() + idField := q.Get("id_field") + q.Del("id_field") + o.Options.RevisionField = q.Get("revision_field") + q.Del("revision_field") + + for param := range q { + return nil, fmt.Errorf("open collection %s: invalid query parameter %q", u, param) + } + + dbName := u.Host + if dbName == "" { + return nil, fmt.Errorf("open collection %s: URL must have a non-empty Host (database name)", u) + } + collName := strings.TrimPrefix(u.Path, "/") + if collName == "" { + return nil, fmt.Errorf("open collection %s: URL must have a non-empty Path (collection name)", u) + } + return OpenCollection(o.Client.Database(dbName).Collection(collName), idField, &o.Options) +} diff --git a/go-cloud/docstore/mongodocstore/urls_test.go b/go-cloud/docstore/mongodocstore/urls_test.go new file mode 100644 index 000000000..92014f83b --- /dev/null +++ b/go-cloud/docstore/mongodocstore/urls_test.go @@ -0,0 +1,136 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mongodocstore + +import ( + "context" + "net/url" + "os" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/docstore" +) + +func fakeConnectionStringInEnv() func() { + oldURLVal := os.Getenv("MONGO_SERVER_URL") + os.Setenv("MONGO_SERVER_URL", "mongodb://localhost") + return func() { + os.Setenv("MONGO_SERVER_URL", oldURLVal) + } +} + +func TestOpenCollectionURL(t *testing.T) { + cleanup := fakeConnectionStringInEnv() + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"mongo://mydb/mycollection", false}, + // Missing database name. + {"mongo:///mycollection", true}, + // Missing collection name. + {"mongo://mydb/", true}, + // Passing id_field parameter. + {"mongo://mydb/mycollection?id_field=foo", false}, + // Passing revision field. + {"mongo://mydb/mycollection?id_field=foo&revision_field=123", false}, + // Invalid parameter. + {"mongo://mydb/mycollection?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + d, err := docstore.OpenCollection(ctx, test.URL) + if d != nil { + defer d.Close() + } + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + } +} + +func TestDefaultDialerOpenCollectionURL(t *testing.T) { + // Defer cleanup + oldURLVal := os.Getenv("MONGO_SERVER_URL") + defer os.Setenv("MONGO_SERVER_URL", oldURLVal) + + tests := []struct { + name string + currentMongoServerURL string + currentWantErr bool + newMongoServerURL string + newWantErr bool + }{ + { + name: "fail when MONGO_SERVER_URL is empty / unset", + currentMongoServerURL: "", + currentWantErr: true, + newMongoServerURL: "", + newWantErr: true, + }, + { + name: "fail when updated MONGO_SERVER_URL is empty / unset", + currentMongoServerURL: "mongodb://localhost", + currentWantErr: false, + newMongoServerURL: "", + newWantErr: true, + }, + { + name: "pass when MONGO_SERVER_URL is updated to new value", + currentMongoServerURL: "mongodb://localhost", + currentWantErr: false, + newMongoServerURL: "mongodb://localhost:27017", + newWantErr: false, + }, + } + + // Set starting conditions + d := new(defaultDialer) + ctx := context.Background() + mongoURLString := "mongo://mydb/mycollection" + u, err := url.Parse(mongoURLString) + if err != nil { + t.Error(err) + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + // Set MONGO_SERVER_URL + os.Setenv("MONGO_SERVER_URL", test.currentMongoServerURL) + _, err = d.OpenCollectionURL(ctx, u) + if err != nil && !test.currentWantErr { + t.Error(err) + } + + // Update MONGO_SERVER_URL + os.Setenv("MONGO_SERVER_URL", test.newMongoServerURL) + _, err = d.OpenCollectionURL(ctx, u) + if err != nil && !test.newWantErr { + t.Error(err) + } + + // Check if the MONGO_SERVER_URL was updated after rotation + if !test.newWantErr { + if d.mongoServerURL != test.newMongoServerURL { + t.Errorf("expected updated MONGO_SERVER_URL to be set to: %s, but got: %s", test.newMongoServerURL, d.mongoServerURL) + } + } + }) + } +} diff --git a/go-cloud/docstore/otel_test.go b/go-cloud/docstore/otel_test.go new file mode 100644 index 000000000..2457a7b08 --- /dev/null +++ b/go-cloud/docstore/otel_test.go @@ -0,0 +1,63 @@ +// Copyright 2019-2025 The Go Cloud Development Kit 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 +// +// https://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 docstore_test + +import ( + "context" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/docstore/memdocstore" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/oteltest" + "testing" +) + +func TestOpenTelemetry(t *testing.T) { + ctx := context.Background() + + // Setup the test exporter for both trace and metrics. + te := oteltest.NewTestExporter(t, docstore.OpenTelemetryViews) + defer te.Shutdown(ctx) + + // Open a collection for testing. + coll, err := memdocstore.OpenCollection("_id", nil) + if err != nil { + t.Fatal(err) + } + defer coll.Close() + + // Test ActionList.Do by creating a document. + if err := coll.Create(ctx, map[string]interface{}{"_id": "a", "count": 0}); err != nil { + t.Fatal(err) + } + + // Test Query.Get. + iter := coll.Query().Get(ctx) + iter.Stop() + + spanStubs := te.GetSpans() + metrics := te.GetMetrics(ctx) + const ( + pkgName = "gocloud.dev/docstore" + driver = "gocloud.dev/docstore/memdocstore" + ) + + diff := oteltest.Diff(spanStubs.Snapshots(), metrics, pkgName, driver, []oteltest.Call{ + {Method: "ActionList.Do", Code: gcerrors.OK}, + {Method: "Query.Get", Code: gcerrors.OK}, + }) + if diff != "" { + t.Error(diff) + } +} diff --git a/go-cloud/docstore/query.go b/go-cloud/docstore/query.go new file mode 100644 index 000000000..c4406812f --- /dev/null +++ b/go-cloud/docstore/query.go @@ -0,0 +1,319 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 docstore + +import ( + "context" + "io" + "reflect" + "time" + + "go.opentelemetry.io/otel/trace" + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +// Query represents a query over a collection. +type Query struct { + coll *Collection + dq *driver.Query + err error +} + +// Query creates a new Query over the collection. +func (c *Collection) Query() *Query { + return &Query{coll: c, dq: &driver.Query{}} +} + +// Where expresses a condition on the query. +// Valid ops are: "=", ">", "<", ">=", "<=, "in", "not-in". +// Valid values are strings, integers, floating-point numbers, time.Time and boolean (only for "=", "in" and "not-in") values. +func (q *Query) Where(fp FieldPath, op string, value interface{}) *Query { + if q.err != nil { + return q + } + pfp, err := parseFieldPath(fp) + if err != nil { + q.err = err + return q + } + validator, ok := validOp[op] + if !ok { + return q.invalidf("invalid filter operator: %q. Use one of: =, >, <, >=, <=, in, not-in", op) + } + if !validator(value) { + return q.invalidf("invalid filter value: %v", value) + } + q.dq.Filters = append(q.dq.Filters, driver.Filter{ + FieldPath: pfp, + Op: op, + Value: value, + }) + return q +} + +type valueValidator func(interface{}) bool + +var validOp = map[string]valueValidator{ + "=": validEqualValue, + ">": validFilterValue, + "<": validFilterValue, + ">=": validFilterValue, + "<=": validFilterValue, + "in": validFilterSlice, + "not-in": validFilterSlice, +} + +func validEqualValue(v interface{}) bool { + if v == nil { + return false + } + if reflect.TypeOf(v).Kind() == reflect.Bool { + return true + } + return validFilterValue(v) +} + +func validFilterValue(v interface{}) bool { + if v == nil { + return false + } + if _, ok := v.(time.Time); ok { + return true + } + switch reflect.TypeOf(v).Kind() { + case reflect.String: + return true + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return true + case reflect.Float32, reflect.Float64: + return true + default: + return false + } +} + +func validFilterSlice(v interface{}) bool { + if v == nil || reflect.TypeOf(v).Kind() != reflect.Slice { + return false + } + vv := reflect.ValueOf(v) + for i := 0; i < vv.Len(); i++ { + if !validEqualValue(vv.Index(i).Interface()) { + return false + } + } + return true +} + +// Offset (also commonly referred to as `Skip`) specifies the number of +// documents to skip before returning results. +// n must be non-negative. +// It is an error to specify Offset more than once in a Get query, or +// at all in a Delete or Update query. +func (q *Query) Offset(n int) *Query { + if q.err != nil { + return q + } + if n < 0 { + return q.invalidf("offset value of %d must be non-negative", n) + } + if q.dq.Offset > 0 { + return q.invalidf("query can have at most one offset clause") + } + q.dq.Offset = n + return q +} + +// Limit will limit the results to at most n documents. +// n must be positive. +// It is an error to specify Limit more than once in a Get query, or +// at all in a Delete or Update query. +func (q *Query) Limit(n int) *Query { + if q.err != nil { + return q + } + if n <= 0 { + return q.invalidf("limit value of %d must be greater than zero", n) + } + if q.dq.Limit > 0 { + return q.invalidf("query can have at most one limit clause") + } + q.dq.Limit = n + return q +} + +// Ascending and Descending are constants for use in the OrderBy method. +const ( + Ascending = "asc" + Descending = "desc" +) + +// OrderBy specifies that the returned documents appear sorted by the given field in +// the given direction. +// A query can have at most one OrderBy clause. If it has none, the order of returned +// documents is unspecified. +// If a query has a Where clause and an OrderBy clause, the OrderBy clause's field +// must appear in a Where clause. +// It is an error to specify OrderBy in a Delete or Update query. +func (q *Query) OrderBy(field, direction string) *Query { + if q.err != nil { + return q + } + if field == "" { + return q.invalidf("OrderBy: empty field") + } + if direction != Ascending && direction != Descending { + return q.invalidf("OrderBy: direction must be one of %q or %q", Ascending, Descending) + } + if q.dq.OrderByField != "" { + return q.invalidf("a query can have at most one OrderBy") + } + q.dq.OrderByField = field + q.dq.OrderAscending = (direction == Ascending) + return q +} + +// BeforeQuery takes a callback function that will be called before the Query is +// executed to the underlying service's query functionality. The callback takes +// a parameter, asFunc, that converts its argument to driver-specific types. +// See https://gocloud.dev/concepts/as/ for background information. +func (q *Query) BeforeQuery(f func(asFunc func(interface{}) bool) error) *Query { + q.dq.BeforeQuery = f + return q +} + +// Get returns an iterator for retrieving the documents specified by the query. If +// field paths are provided, only those paths are set in the resulting documents. +// +// Call Stop on the iterator when finished. +func (q *Query) Get(ctx context.Context, fps ...FieldPath) *DocumentIterator { + return q.get(ctx, true, fps...) +} + +// get implements Get, with optional OpenTelemetry tracing so it can be used internally. +func (q *Query) get(ctx context.Context, withTracing bool, fps ...FieldPath) *DocumentIterator { + dcoll := q.coll.driver + if err := q.initGet(fps); err != nil { + return &DocumentIterator{err: wrapError(dcoll, err)} + } + + var err error + + if withTracing { + var span trace.Span + ctx, span = q.coll.tracer.Start(ctx, "Query.Get") + defer func() { + q.coll.tracer.End(ctx, span, err) + }() + } + it, err := dcoll.RunGetQuery(ctx, q.dq) + return &DocumentIterator{iter: it, coll: q.coll, err: wrapError(dcoll, err)} +} + +func (q *Query) initGet(fps []FieldPath) error { + if q.err != nil { + return q.err + } + if err := q.coll.checkClosed(); err != nil { + return errClosed + } + pfps, err := parseFieldPaths(fps) + if err != nil { + return err + } + q.dq.FieldPaths = pfps + if q.dq.OrderByField != "" && len(q.dq.Filters) > 0 { + found := false + for _, f := range q.dq.Filters { + if len(f.FieldPath) == 1 && f.FieldPath[0] == q.dq.OrderByField { + found = true + break + } + } + if !found { + return gcerr.Newf(gcerr.InvalidArgument, nil, "OrderBy field %s must appear in a Where clause", + q.dq.OrderByField) + } + } + return nil +} + +func (q *Query) invalidf(format string, args ...interface{}) *Query { + q.err = gcerr.Newf(gcerr.InvalidArgument, nil, format, args...) + return q +} + +// DocumentIterator iterates over documents. +// +// Always call Stop on the iterator. +type DocumentIterator struct { + iter driver.DocumentIterator + coll *Collection + err error // already wrapped +} + +// Next stores the next document in dst. It returns io.EOF if there are no more +// documents. +// Once Next returns an error, it will always return the same error. +func (it *DocumentIterator) Next(ctx context.Context, dst Document) error { + if it.err != nil { + return it.err + } + if err := it.coll.checkClosed(); err != nil { + it.err = err + return it.err + } + ddoc, err := driver.NewDocument(dst) + if err != nil { + it.err = wrapError(it.coll.driver, err) + return it.err + } + it.err = wrapError(it.coll.driver, it.iter.Next(ctx, ddoc)) + return it.err +} + +// Stop stops the iterator. Calling Next on a stopped iterator will return io.EOF, or +// the error that Next previously returned. +func (it *DocumentIterator) Stop() { + if it.err != nil { + return + } + it.err = io.EOF + it.iter.Stop() +} + +// As converts i to driver-specific types. +// See https://gocloud.dev/concepts/as/ for background information, the "As" +// examples in this package for examples, and the driver package +// documentation for the specific types supported for that driver. +func (it *DocumentIterator) As(i interface{}) bool { + if i == nil || it.iter == nil { + return false + } + return it.iter.As(i) +} + +// Plan describes how the query would be executed if its Get method were called with +// the given field paths. Plan uses only information available to the client, so it +// cannot know whether a service uses indexes or scans internally. +func (q *Query) Plan(fps ...FieldPath) (string, error) { + if err := q.initGet(fps); err != nil { + return "", err + } + return q.coll.driver.QueryPlan(q.dq) +} diff --git a/go-cloud/docstore/query_test.go b/go-cloud/docstore/query_test.go new file mode 100644 index 000000000..155b73e93 --- /dev/null +++ b/go-cloud/docstore/query_test.go @@ -0,0 +1,90 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 docstore + +import ( + "context" + "strings" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/docstore/driver" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +func TestQueryValidFilter(t *testing.T) { + for _, fp := range []FieldPath{"", ".a", "a..b", "b."} { + q := Query{dq: &driver.Query{}} + q.Where(fp, ">", 1) + if got := gcerrors.Code(q.err); got != gcerrors.InvalidArgument { + t.Errorf("fieldpath %q: got %s, want InvalidArgument", fp, got) + } + } + for _, op := range []string{"==", "!="} { + q := Query{dq: &driver.Query{}} + q.Where("a", op, 1) + if got := gcerrors.Code(q.err); got != gcerrors.InvalidArgument { + t.Errorf("op %s: got %s, want InvalidArgument", op, got) + } + } + for _, v := range []interface{}{nil, 5 + 2i, []byte("x"), func() {}, []int{}, map[string]bool{}} { + q := Query{dq: &driver.Query{}} + q.Where("a", "=", v) + if got := gcerrors.Code(q.err); got != gcerrors.InvalidArgument { + t.Errorf("value %+v: got %s, want InvalidArgument", v, got) + } + } +} + +func TestInvalidQuery(t *testing.T) { + ctx := context.Background() + // We detect that these queries are invalid before they reach the driver. + c := &Collection{} + + for _, test := range []struct { + desc string + appliesToGet bool + q *Query + contains string // error text must contain this string + }{ + {"negative Limit", true, c.Query().Limit(-1), "limit"}, + {"zero Limit", true, c.Query().Limit(0), "limit"}, + {"two Limits", true, c.Query().Limit(1).Limit(2), "limit"}, + {"negative Offset", true, c.Query().Offset(-1), "offset"}, + {"two Offsets", true, c.Query().Offset(1).Offset(2), "offset"}, + {"zero Offset and Limit", true, c.Query().Offset(0).Limit(0), "limit"}, + {"negative Offset and Limit", true, c.Query().Offset(-1).Limit(-1), "offset"}, + {"zero Offset and negative Limit", true, c.Query().Offset(0).Limit(-1), "limit"}, + {"empty OrderBy field", true, c.Query().OrderBy("", Ascending), "empty field"}, + {"bad OrderBy direction", true, c.Query().OrderBy("x", "y"), "direction"}, + {"two OrderBys", true, c.Query().OrderBy("x", Ascending).OrderBy("y", Descending), "orderby"}, + {"OrderBy not in Where", true, c.Query().OrderBy("x", Ascending).Where("y", ">", 1), "orderby"}, + {"any Limit", false, c.Query().Limit(1), "limit"}, + {"any Offset", false, c.Query().Offset(1), "offset"}, + {"any OrderBy", false, c.Query().OrderBy("x", Descending), "orderby"}, + } { + check := func(err error) { + if gcerrors.Code(err) != gcerrors.InvalidArgument { + t.Errorf("%s: got %v, want InvalidArgument", test.desc, err) + return + } + if !strings.Contains(strings.ToLower(err.Error()), test.contains) { + t.Errorf("%s: got %q, wanted it to contain %q", test.desc, err.Error(), test.contains) + } + } + if test.appliesToGet { + check(test.q.Get(ctx).Next(ctx, nil)) + } + } +} diff --git a/go-cloud/docstore/urls.go b/go-cloud/docstore/urls.go new file mode 100644 index 000000000..8a315f9b3 --- /dev/null +++ b/go-cloud/docstore/urls.go @@ -0,0 +1,89 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 docstore + +import ( + "context" + "net/url" + + "github.com/DataDog/iceberg-go/go-cloud/internal/openurl" +) + +// CollectionURLOpener opens a collection of documents based on a URL. +// The opener must not modify the URL argument. It must be safe to call from +// multiple goroutines. +// +// This interface is generally implemented by types in driver packages. +type CollectionURLOpener interface { + OpenCollectionURL(ctx context.Context, u *url.URL) (*Collection, error) +} + +// URLMux is a URL opener multiplexer. It matches the scheme of the URLs against +// a set of registered schemes and calls the opener that matches the URL's +// scheme. See https://gocloud.dev/concepts/urls/ for more information. +// +// The zero value is a multiplexer with no registered scheme. +type URLMux struct { + schemes openurl.SchemeMap +} + +// CollectionSchemes returns a sorted slice of the registered Collection schemes. +func (mux *URLMux) CollectionSchemes() []string { return mux.schemes.Schemes() } + +// ValidCollectionScheme returns true iff scheme has been registered for Collections. +func (mux *URLMux) ValidCollectionScheme(scheme string) bool { return mux.schemes.ValidScheme(scheme) } + +// RegisterCollection registers the opener with the given scheme. If an opener +// already exists for the scheme, RegisterCollection panics. +func (mux *URLMux) RegisterCollection(scheme string, opener CollectionURLOpener) { + mux.schemes.Register("docstore", "Collection", scheme, opener) +} + +// OpenCollection calls OpenCollectionURL with the URL parsed from urlstr. +// OpenCollection is safe to call from multiple goroutines. +func (mux *URLMux) OpenCollection(ctx context.Context, urlstr string) (*Collection, error) { + opener, u, err := mux.schemes.FromString("Collection", urlstr) + if err != nil { + return nil, err + } + return opener.(CollectionURLOpener).OpenCollectionURL(ctx, u) +} + +// OpenCollectionURL dispatches the URL to the opener that is registered with +// the URL's scheme. OpenCollectionURL is safe to call from multiple goroutines. +func (mux *URLMux) OpenCollectionURL(ctx context.Context, u *url.URL) (*Collection, error) { + opener, err := mux.schemes.FromURL("Collection", u) + if err != nil { + return nil, err + } + return opener.(CollectionURLOpener).OpenCollectionURL(ctx, u) +} + +var defaultURLMux = new(URLMux) + +// DefaultURLMux returns the URLMux used by OpenCollection. +// +// Driver packages can use this to register their CollectionURLOpener on the mux. +func DefaultURLMux() *URLMux { + return defaultURLMux +} + +// OpenCollection opens the collection identified by the URL given. +// See the URLOpener documentation in driver subpackages for details +// on supported URL formats, and https://gocloud.dev/concepts/urls/ for more +// information. +func OpenCollection(ctx context.Context, urlstr string) (*Collection, error) { + return defaultURLMux.OpenCollection(ctx, urlstr) +} diff --git a/go-cloud/docstore/urls_test.go b/go-cloud/docstore/urls_test.go new file mode 100644 index 000000000..90b356e7b --- /dev/null +++ b/go-cloud/docstore/urls_test.go @@ -0,0 +1,127 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 docstore + +import ( + "context" + "errors" + "net/url" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestURLMux(t *testing.T) { + ctx := context.Background() + + mux := new(URLMux) + fake := &fakeOpener{} + mux.RegisterCollection("foo", fake) + mux.RegisterCollection("err", fake) + + if diff := cmp.Diff(mux.CollectionSchemes(), []string{"err", "foo"}); diff != "" { + t.Errorf("Schemes: %s", diff) + } + if !mux.ValidCollectionScheme("foo") || !mux.ValidCollectionScheme("err") { + t.Errorf("ValidCollectionScheme didn't return true for valid scheme") + } + if mux.ValidCollectionScheme("foo2") || mux.ValidCollectionScheme("http") { + t.Errorf("ValidCollectionScheme didn't return false for invalid scheme") + } + + for _, tc := range []struct { + name string + url string + wantErr bool + }{ + { + name: "empty URL", + wantErr: true, + }, + { + name: "invalid URL", + url: ":foo", + wantErr: true, + }, + { + name: "invalid URL no scheme", + url: "foo", + wantErr: true, + }, + { + name: "unregistered scheme", + url: "bar://mycollection", + wantErr: true, + }, + { + name: "func returns error", + url: "err://mycollection", + wantErr: true, + }, + { + name: "no query options", + url: "foo://mycollection", + }, + { + name: "empty query options", + url: "foo://mycollection?", + }, + { + name: "using api scheme prefix", + url: "docstore+foo://bar", + }, + { + name: "using api+type scheme prefix", + url: "docstore+collection+foo://bar", + }, + } { + t.Run(tc.name, func(t *testing.T) { + _, gotErr := mux.OpenCollection(ctx, tc.url) + if (gotErr != nil) != tc.wantErr { + t.Fatalf("got err %v, want error %v", gotErr, tc.wantErr) + } + if gotErr != nil { + return + } + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + // Repeat with OpenCollectionURL. + parsed, err := url.Parse(tc.url) + if err != nil { + t.Fatal(err) + } + _, gotErr = mux.OpenCollectionURL(ctx, parsed) + if gotErr != nil { + t.Fatalf("got err %v want nil", gotErr) + } + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + }) + } +} + +type fakeOpener struct { + u *url.URL // last url passed to OpenCollectionURL +} + +func (o *fakeOpener) OpenCollectionURL(ctx context.Context, u *url.URL) (*Collection, error) { + if u.Scheme == "err" { + return nil, errors.New("fail") + } + o.u = u + return nil, nil +} diff --git a/go-cloud/gcerrors/errors.go b/go-cloud/gcerrors/errors.go new file mode 100644 index 000000000..bfcad6467 --- /dev/null +++ b/go-cloud/gcerrors/errors.go @@ -0,0 +1,91 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcerrors provides support for getting error codes from +// errors returned by Go CDK APIs. +package gcerrors + +import ( + "context" + "errors" + + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +// An ErrorCode describes the error's category. Programs should act upon an error's +// code, not its message. +type ErrorCode = gcerr.ErrorCode + +const ( + // OK is returned by the Code function on a nil error. It is not a valid + // code for an error. + OK ErrorCode = gcerr.OK + + // Unknown means that the error could not be categorized. + Unknown ErrorCode = gcerr.Unknown + + // NotFound means that the resource was not found. + NotFound ErrorCode = gcerr.NotFound + + // AlreadyExists means that the resource exists, but it should not. + AlreadyExists ErrorCode = gcerr.AlreadyExists + + // InvalidArguments means that a value given to a Go CDK API is incorrect. + InvalidArgument ErrorCode = gcerr.InvalidArgument + + // Internal means that something unexpected happened. Internal errors always indicate + // bugs in the Go CDK (or possibly the underlying service). + Internal ErrorCode = gcerr.Internal + + // Unimplemented means that the feature is not implemented. + Unimplemented ErrorCode = gcerr.Unimplemented + + // FailedPrecondition means that the system was in the wrong state. + FailedPrecondition ErrorCode = gcerr.FailedPrecondition + + // PermissionDenied means that the caller does not have permission to execute the specified operation. + PermissionDenied ErrorCode = gcerr.PermissionDenied + + // ResourceExhausted means that some resource has been exhausted, typically because a service resource limit + // has been reached. + ResourceExhausted ErrorCode = gcerr.ResourceExhausted + + // Canceled means that the operation was canceled. + Canceled ErrorCode = gcerr.Canceled + + // DeadlinedExceeded means that the operation timed out. + DeadlineExceeded ErrorCode = gcerr.DeadlineExceeded +) + +// Code returns the ErrorCode of err if it, or some error it wraps, is an *Error. +// If err is context.Canceled or context.DeadlineExceeded, or wraps one of those errors, +// it returns the Canceled or DeadlineExceeded codes, respectively. +// If err is nil, it returns the special code OK. +// Otherwise, it returns Unknown. +func Code(err error) ErrorCode { + if err == nil { + return OK + } + var e *gcerr.Error + if errors.As(err, &e) { + return e.Code + } + if errors.Is(err, context.Canceled) { + return Canceled + } + if errors.Is(err, context.DeadlineExceeded) { + return DeadlineExceeded + } + return Unknown +} diff --git a/go-cloud/gcerrors/errors_test.go b/go-cloud/gcerrors/errors_test.go new file mode 100644 index 000000000..6545cbbf6 --- /dev/null +++ b/go-cloud/gcerrors/errors_test.go @@ -0,0 +1,52 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcerrors + +import ( + "context" + "io" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" +) + +type wrappedErr struct { + err error +} + +func (w wrappedErr) Error() string { return "wrapped" } + +func (w wrappedErr) Unwrap() error { return w.err } + +func TestCode(t *testing.T) { + for _, test := range []struct { + in error + want ErrorCode + }{ + {nil, OK}, + {gcerr.New(AlreadyExists, nil, 1, ""), AlreadyExists}, + {wrappedErr{gcerr.New(PermissionDenied, nil, 1, "")}, PermissionDenied}, + {context.Canceled, Canceled}, + {context.DeadlineExceeded, DeadlineExceeded}, + {wrappedErr{context.Canceled}, Canceled}, + {wrappedErr{context.DeadlineExceeded}, DeadlineExceeded}, + {io.EOF, Unknown}, + } { + got := Code(test.in) + if got != test.want { + t.Errorf("%v: got %s, want %s", test.in, got, test.want) + } + } +} diff --git a/go-cloud/gcp/cloudsql/cloudsql.go b/go-cloud/gcp/cloudsql/cloudsql.go new file mode 100644 index 000000000..2fdc84cf3 --- /dev/null +++ b/go-cloud/gcp/cloudsql/cloudsql.go @@ -0,0 +1,43 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 cloudsql contains Wire providers that are common across Google Cloud +// SQL. +package cloudsql // import "gocloud.dev/gcp/cloudsql" + +import ( + "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/certs" + "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/proxy" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "golang.org/x/oauth2" +) + +// CertSourceSet is a Wire provider set that binds a Cloud SQL proxy +// certificate source from an GCP-authenticated HTTP client. +var CertSourceSet = wire.NewSet( + NewCertSource, + wire.Bind(new(proxy.CertSource), new(*certs.RemoteCertSource))) + +// NewCertSource creates a local certificate source that uses the given +// HTTP client. The client is assumed to make authenticated requests. +func NewCertSource(c *gcp.HTTPClient) *certs.RemoteCertSource { + return certs.NewCertSourceOpts(&c.Client, certs.RemoteOpts{}) +} + +// NewCertSourceWithIAM creates a local certificate source, including Token source for token information used in +// cert creation, that uses the given HTTP client. The client is assumed to make authenticated requests. +func NewCertSourceWithIAM(c *gcp.HTTPClient, t oauth2.TokenSource) *certs.RemoteCertSource { + return certs.NewCertSourceOpts(&c.Client, certs.RemoteOpts{EnableIAMLogin: true, TokenSource: t}) +} diff --git a/go-cloud/gcp/gcp.go b/go-cloud/gcp/gcp.go new file mode 100644 index 000000000..5c0bed4c2 --- /dev/null +++ b/go-cloud/gcp/gcp.go @@ -0,0 +1,101 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcp provides fundamental Wire providers and types for Google Cloud Platform (GCP). +package gcp // import "gocloud.dev/gcp" + +import ( + "context" + "errors" + "net/http" + + "github.com/google/wire" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" +) + +// DefaultIdentity is a Wire provider set that provides the project ID +// and token source from Application Default Credentials (ADC). +var DefaultIdentity = wire.NewSet( + CredentialsTokenSource, + DefaultCredentials, + DefaultProjectID) + +// ProjectID is a GCP Project ID. +type ProjectID string + +// TokenSource wraps a GCP token source that provides Cloud-Platform- +// scoped tokens. +type TokenSource oauth2.TokenSource + +// HTTPClient is an HTTP client that makes requests authenticated with Cloud- +// Platform-scoped authentication tokens. +type HTTPClient struct { + http.Client +} + +// NewAnonymousHTTPClient creates a new anonymous HTTP client. +func NewAnonymousHTTPClient(transport http.RoundTripper) *HTTPClient { + return &HTTPClient{ + Client: http.Client{ + Transport: transport, + }, + } +} + +// NewHTTPClient creates a new authenticated HTTP client. +func NewHTTPClient(transport http.RoundTripper, ts TokenSource) (*HTTPClient, error) { + if ts == nil { + return nil, errors.New("gcp: no credentials available") + } + return &HTTPClient{ + Client: http.Client{ + Transport: &oauth2.Transport{ + Base: transport, + Source: ts, + }, + }, + }, nil +} + +// DefaultTransport returns http.DefaultTransport. +func DefaultTransport() http.RoundTripper { + return http.DefaultTransport +} + +// DefaultCredentials obtains the default GCP credentials with Cloud Platform +// scope. +func DefaultCredentials(ctx context.Context) (*google.Credentials, error) { + adc, err := google.FindDefaultCredentials(ctx, "https://www.googleapis.com/auth/cloud-platform") + if err != nil { + return nil, err + } + return adc, nil +} + +// CredentialsTokenSource extracts the token source from GCP credentials. +func CredentialsTokenSource(creds *google.Credentials) TokenSource { + if creds == nil { + return nil + } + return TokenSource(creds.TokenSource) +} + +// DefaultProjectID obtains the project ID from the default GCP credentials. +func DefaultProjectID(creds *google.Credentials) (ProjectID, error) { + if creds == nil { + return "", errors.New("gcp: no project found in credentials") + } + return ProjectID(creds.ProjectID), nil +} diff --git a/go-cloud/gcp/gcp_test.go b/go-cloud/gcp/gcp_test.go new file mode 100644 index 000000000..06b98bca2 --- /dev/null +++ b/go-cloud/gcp/gcp_test.go @@ -0,0 +1,69 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcp_test + +import ( + "context" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" +) + +func TestNewHTTPClient(t *testing.T) { + transport := gcp.DefaultTransport() + _, err := gcp.NewHTTPClient(transport, nil) + if err == nil { + t.Error("got nil want error") + } + creds, err := setup.FakeGCPCredentials(context.Background()) + if err != nil { + t.Fatal(err) + } + _, err = gcp.NewHTTPClient(transport, gcp.CredentialsTokenSource(creds)) + if err != nil { + t.Error(err) + } +} + +func TestCredentialsTokenSource(t *testing.T) { + ts := gcp.CredentialsTokenSource(nil) + if ts != nil { + t.Error("got non-nil TokenSource from nil creds, want nil") + } + creds, err := setup.FakeGCPCredentials(context.Background()) + if err != nil { + t.Fatal(err) + } + ts = gcp.CredentialsTokenSource(creds) + if ts == nil { + t.Error("got nil TokenSource from creds, want non-nil") + } +} + +func TestDefaultProjectID(t *testing.T) { + _, err := gcp.DefaultProjectID(nil) + if err == nil { + t.Error("got nil error from nil creds, want error") + } + creds, err := setup.FakeGCPCredentials(context.Background()) + if err != nil { + t.Fatal(err) + } + _, err = gcp.DefaultProjectID(creds) + if err != nil { + t.Error(err) + } +} diff --git a/go-cloud/gcp/gcpcloud/example_test.go b/go-cloud/gcp/gcpcloud/example_test.go new file mode 100644 index 000000000..b4d639780 --- /dev/null +++ b/go-cloud/gcp/gcpcloud/example_test.go @@ -0,0 +1,76 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcpcloud_test + +import ( + "context" + "fmt" + "log" + "net/http" + + "github.com/google/wire" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "github.com/DataDog/iceberg-go/go-cloud/gcp/gcpcloud" + "github.com/DataDog/iceberg-go/go-cloud/server" + "github.com/DataDog/iceberg-go/go-cloud/server/health" +) + +// This is an example of how to bootstrap an HTTP server running on +// Google Cloud Platform (GCP). The code in this function would be +// placed in main(). +func Example() { + // Connect and authenticate to GCP. + srv, cleanup, err := setup(context.Background()) + if err != nil { + log.Fatal(err) + } + defer cleanup() + + // Set up the HTTP routes. + http.HandleFunc("/", greet) + + // Run the server. This behaves much like http.ListenAndServe, + // including that passing a nil handler will use http.DefaultServeMux. + log.Fatal(srv.ListenAndServe(":8080")) +} + +// setup is a Wire injector function that creates an HTTP server +// configured to send diagnostics to Stackdriver. The second return +// value is a clean-up function that can be called to shut down any +// resources created by setup. +// +// The body of this function will be filled in by running Wire. While +// the name of the function does not matter, the signature signals to +// Wire what provider functions to call. See +// https://github.com/google/wire/blob/master/docs/guide.md#injectors +// for more details. +func setup(ctx context.Context) (*server.Server, func(), error) { + wire.Build( + // The GCP set includes all the default wiring for GCP, including + // for *server.Server. + gcpcloud.GCP, + // Providing nil instructs the server to use the default sampling policy. + wire.Value(sdktrace.Sampler(nil)), + // Health checks can be added to delay your server reporting healthy + // to the load balancer before critical dependencies are available. + wire.Value([]health.Checker{}), + ) + return nil, nil, nil +} + +// greet is an ordinary http.HandleFunc. +func greet(w http.ResponseWriter, req *http.Request) { + fmt.Fprintln(w, "Hello, World!") +} diff --git a/go-cloud/gcp/gcpcloud/gcpcloud.go b/go-cloud/gcp/gcpcloud/gcpcloud.go new file mode 100644 index 000000000..4f786f019 --- /dev/null +++ b/go-cloud/gcp/gcpcloud/gcpcloud.go @@ -0,0 +1,48 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcpcloud contains Wire providers for GCP services. +package gcpcloud // import "gocloud.dev/gcp/gcpcloud" + +import ( + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/blob/gcsblob" + "github.com/DataDog/iceberg-go/go-cloud/docstore/gcpfirestore" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/gcp/cloudsql" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/gcppubsub" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/gcpruntimeconfig" + "github.com/DataDog/iceberg-go/go-cloud/secrets/gcpkms" + "github.com/DataDog/iceberg-go/go-cloud/server/sdserver" +) + +// GCP is a Wire provider set that includes all Google Cloud Platform services +// in this repository and authenticates using Application Default Credentials. +var GCP = wire.NewSet(Services, gcp.DefaultIdentity) + +// Services is a Wire provider set that includes the default wiring for all +// Google Cloud Platform services in this repository, but does not include +// credentials. Individual services may require additional configuration. +var Services = wire.NewSet( + gcp.DefaultTransport, + gcp.NewHTTPClient, + + gcpruntimeconfig.Set, + gcpkms.Set, + gcppubsub.Set, + gcsblob.Set, + cloudsql.CertSourceSet, + gcpfirestore.Set, + sdserver.Set, +) diff --git a/go-cloud/gocloud.code-workspace b/go-cloud/gocloud.code-workspace new file mode 100644 index 000000000..b6210cc29 --- /dev/null +++ b/go-cloud/gocloud.code-workspace @@ -0,0 +1,120 @@ +{ + "folders": [ + { + "path": "." + }, + { + "path": "internal/cmd/gocdk" + }, + { + "path": "internal/website" + }, + { + "path": "samples" + } + ], + "settings": { + "cSpell.words": [ + "Hashicorp", + "MongoDB", + "MongoDB's", + "NATS", + "Nanos", + "Newf", + "RPC", + "RPCs", + "Shopify", + "URL's", + "ack", + "acked", + "acking", + "acks", + "amazonaws", + "amqp", + "appengine", + "awserr", + "awserror", + "awskms", + "awsmysql", + "awsparamstore", + "awspostgres", + "awssns", + "awssnssqs", + "awssqs", + "azuresb", + "biome's", + "bson", + "cloudkms", + "curr", + "dbname", + "dynamodb", + "etag", + "etcd", + "etcdvar", + "fsnotify", + "gRPC", + "gcaws", + "gcerr", + "gcerrors", + "gcpkms", + "gcpmysql", + "gcppostgres", + "gcppubsub", + "gcsblob", + "gocdk", + "gocloud", + "googleapis", + "healthz", + "knative", + "memblob", + "mempubsub", + "mongodocstore", + "msg", + "msgs", + "mybucket", + "mycfg", + "mycollection", + "mydb", + "myinstance", + "mykey", + "myproject", + "mysub", + "mysubject", + "mysubscription", + "mytable", + "mytopic", + "myvar", + "nackable", + "nacked", + "nacking", + "nacks", + "natspubsub", + "oauth", + "oauth2", + "ocsql", + "pctx", + "postgres", + "protobuf", + "protos", + "ptypes", + "sarama", + "sess", + "specifier", + "specifier's", + "structs", + "tfstate", + "unacked", + "uploader", + "upsert", + "usagef", + "uuid", + "vals", + "vkit", + "waitc", + "xerrors" + ], + "files.associations": { + "*.htmlt": "html" + } + } +} diff --git a/go-cloud/internal/docs/README.md b/go-cloud/internal/docs/README.md new file mode 100644 index 000000000..27aa1ba9f --- /dev/null +++ b/go-cloud/internal/docs/README.md @@ -0,0 +1,7 @@ +# Docs + +This is the documentation for developers of the Go CDK, describing various +coding practices and project processes. + +- [Design Decisions](design.md) +- [Releases](release.md) diff --git a/go-cloud/internal/docs/design.md b/go-cloud/internal/docs/design.md new file mode 100644 index 000000000..b7284692c --- /dev/null +++ b/go-cloud/internal/docs/design.md @@ -0,0 +1,830 @@ +# Design Decisions + +This document outlines important design decisions made for this repository and +attempts to provide succinct rationales. Recording these decisions helps +maintain consistency across packages, especially as an open source project where +contributors can join at any point during development. + +A broad design goal for the Go Cloud Development Kit (Go CDK) is for the API +style to be consistent. Consistency aids users in building a mental model of how +to use the APIs. As such, the design of individual packages must also consider +their impact on the Go CDK as a whole. + +This is a [Living Document](https://en.wikipedia.org/wiki/Living_document). The +decisions in here are not set in stone, but simply describe our current thinking +about how to guide the Go Cloud Development Kit project. While it is useful to +link to this document when having discussions in an issue, it is not to be used +as a means of closing issues without discussion at all. Discussion on an issue +can lead to revisions of this document. + +## Developers and Operators + +The Go CDK is designed with two different personas in mind: the developer and +the operator. In the world of DevOps, these may be the same person. A developer +may be directly deploying their application into production, especially on +smaller teams. In a larger organization, these may be different teams entirely, +but working closely together. Regardless, these two personas have two very +different ways of looking at a Go program: + +- The developer persona wants to write business logic that is agnostic of + underlying cloud provider. Their focus is on making software correct for the + requirements at hand. +- The operator persona wants to incorporate the business logic into the + organization's policies and provision resources for the logic to run. Their + focus is making software run predictably and reliably with the resources at + hand. + +The Go CDK uses Go interfaces at the boundary between these two personas: a +developer is meant to use an interface, and an operator is meant to provide an +implementation of that interface. This distinction prevents the Go CDK going +down a path of complexity that makes application portability difficult. The +[`blob.Bucket`][] type is a prime example: the API does not provide a way of +creating a new bucket. To properly and safely create such a bucket requires +careful consideration, getting something like ACLs wrong could lead to a +catastrophic data leak. To generate the ACLs correctly requires modeling of IAM +users and roles for each cloud platform, and some way of mapping those users and +roles across clouds. While not impossible, the level of complexity and the high +likelihood of a leaky abstraction leads us to believe this is not the right +direction for the Go CDK. + +Instead of adding large amounts of leaky complexity to the Go CDK, we expect the +operator role to handle the management of non-portable platform-specific +resources. An implementor of the `Bucket` interface does not need to determine +the content type of incoming data, as that is a developer's concern. This +separation of concerns allows these two personas to communicate using a shared +language while focusing on their respective areas of expertise. + +[`blob.Bucket`]: https://godoc.org/github.com/google/go-cloud/blob#Bucket + +## Portable Types and Drivers + +The portable APIs that the Go CDK exports (like [`blob.Bucket`][] or +[`runtimevar.Variable`][]) are concrete types, not interfaces. To understand +why, imagine if we used a plain interface: + +![Diagram showing user code depending on blob.Bucket, which is implemented by +awsblob.Bucket.](img/user-facing-type-no-driver.png) + +Consider the [`Bucket.NewWriter` method][], which infers the content type of the +blob based on the first bytes written to it. If `blob.Bucket` was an interface, +each implementation of `blob.Bucket` would have to replicate this behavior +precisely. This does not scale: conformance tests would be needed to ensure that +each interface method actually behaves in the way that the docs describe. This +makes the interfaces hard to implement, which runs counter to the goals of the +project. + +Instead, we follow the example of [`database/sql`][] and separate out the +implementation-agnostic logic from the interface. The implementation-agnostic +logic-containing concrete type is the **portable type**. We call the interface +the **driver**. Visually, it looks like this: + +![Diagram showing user code depending on blob.Bucket, which holds a +driver.Bucket implemented by awsblob.Bucket.](img/user-facing-type.png) + +This has a number of benefits: + +- The portable type can perform higher level logic without making the + interface complex to implement. In the blob example, the portable type's + `NewWriter` method can do the content type detection and then pass the final + result to the driver type. +- Methods can be added to the portable type without breaking compatibility. + Contrast with adding methods to an interface, which is a breaking change. +- When new operations on the driver are added as new optional interfaces, the + portable type can hide the need for type-assertions from the user. + +As a rule, if a method `Foo` has the same inputs and semantics in the portable +type and the driver type, then the driver method may be called `Foo`, even +though the return signatures may differ. Otherwise, the driver method name +should be different to reduce confusion. + +New Go CDK APIs should always follow this portable type and driver pattern. + +[`runtimevar.Variable`]: +https://godoc.org/github.com/google/go-cloud/runtimevar#Variable +[`Bucket.NewWriter` method]: +https://godoc.org/github.com/google/go-cloud/blob#Bucket.NewWriter +[`database/sql`]: https://godoc.org/database/sql + +## Minimize Global State + +As a library, the Go CDK should not introduce global state. Global state is +difficult to reason about in large codebases, where it can be necessary for +different parts of the application to use different states. Instead of adding +global state, push responsibility to the application to inject the state where +it is needed. + +The exception we permit is URL scheme registration as documented under +[URLs](#urls). The amount of boilerplate setup code required for URL muxes for +multiple drivers without use of a tool like Wire is an unreasonable burden for +users of Go CDK. We want the Go CDK to be usable both with and without Wire. A +global registry is acceptable as long as its use is not mandatory, but the +burden is to prove the benefit over the cost. + +## Driver Package Naming Conventions + +Inside this repository, we name packages that handle cloud services after the +service name, not the providing cloud (`s3blob` instead of `awsblob`). While a +cloud provider may provide a unique offering for a particular API, they may not +always provide only one, so distinguishing them in this way keeps the API +symbols stable over time. + +The naming convention is ``, where: + +* `` is the provider name, like `aws` or `gcp` or `azure`. + * Omit for 3rd party/open source/local packages. + * May also be omitted in cases where the product name is sufficient (e.g., + `s3blob` not `awss3blob` since S3 is well-known, `gcsblob` not + `gcpgcsblob` since GCS already references Google). + * Required if the product name is not unique across providers (e.g., + `gcpkms` and `awskms`). +* ``is the product/service name. +* `` is the portable API name. + * Include for local/test packages like (e.g., `fileblob`, `mempubsub`). + * May be omitted when it makes the package name too long (e.g. `awssnssqs` + is long enough, don't add `pubsub`). + * Encouraged when it helps distinguish the package from the service's own + package name (e.g., `s3blob` not `s3`). + +## Portable Type Constructors + +Portable type constructors are the functions defined in driver packages that end +users call to get an instance of the portable type. For example, +`gcsblob.OpenBucket`, which returns an instance of the `*blob.Bucket` portable +type backed by GCS. + +- Portable type constructors should be top-level functions that return the + portable type directly. Avoid helpers (e.g., a `Client` struct with a + function that returns the portable type instead of it being top-level) and + wrappers (e.g., a `fooblob.Bucket` type returned from `fooblob.OpenBucket` + that wraps the portable type). Top level functions without wrappers are + easier to use, especially when we're consistent about it. +- Order arguments that are less likely to change across multiple calls to the + constructor before ones that are likely to change. For example, connection + and authorization related arguments should go before names, so + `OpenBucket(ctx, client, "mybucket")` instead of `OpenBucket(ctx, + "mybucket", client)`. +- All public constructors should take an `Options` struct (see next section). + +### Option Structs + +All public constructors should take an `Options` struct, even if it is currently +empty, to ensure that we can add arguments to the APIs in the future without +breaking backward compatibility. + +- This includes driver constructors (e.g., `gcsblob.OpenBucket`) as well as + API functions (e.g., `blob.NewReader`). When in doubt, if you think it's + possible that we'll add arguments, add `Options`. +- The argument should be of type `*Options`, so that `nil` can be passed in + the default case. +- Name the `Options` struct appropriately. `Options` is usually fine for + portable type constructors since the package generally only exposes a + constructor. Inside a driver interface or in a portable type like `blob`, + use more descriptive names like `ReaderOptions` or `WriterOptions`. +- If a function already has a struct argument, don't add a separate `Options` + struct. Example: the various `sql.Open` functions take a `Params` struct + with connection parameters; we chose to add new options to `Params` instead + of introducing a separate `Options` struct. This keeps the function + signature simpler and avoid confusion about which struct new parameters + should be added to. +- When similar `Options` are part of a driver interface and also part of the + portable type (e.g., `blob.WriterOptions`), duplicate the struct instead of + aliasing or embedding it, and copy the struct fields explicitly where + needed. This allows the godoc for each type to be tailored to the + appropriate audience (e.g. end-users for the portable type, driver + implementors for the driver interface), and also allows the structs to + diverge over time if appropriate. +- Required arguments must not be in an `Options` struct, and all fields of the + `Options` struct must have reasonable defaults. Exception: struct arguments + that don't have `Options` in the name can contain required arguments (e.g., + see the `Params` example for `sql.Open` above). + +Regarding empty `Options` structs: we considered only adding them when the first +option is added, and using a separate constructor for compatibility (e.g., start +with `foo.New(...)` and later add `foo.NewWithOptions(..., opts *Options)` if +needed). However, this would result in inconsistent names over time (e.g., some +packages would expose `New` with an `Options`, while others would expose +`NewWithOptions`). + +### Compound IDs + +Many cloud providers have resource IDs that are made up of subcomponents in +some well-defined syntax. For example, [GCP KMS key IDs][] take the form +`projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEY_RING]/cryptoKeys/[KEY]`. +We call these _compound IDs_. + +There are two broad compound ID usage patterns we have observed: + +1. Applications will keep resources in the same location, so the application + will build the ID from the subcomponents rather than passing the entire + resource ID around. +2. Applications will pass a verbatim string from configuration down to the + API, since this is what was easily copy-pasteable from the cloud console UI. + +Go CDK constructors that take in compound IDs should take in a `string` with the +full compound ID. Helper functions to build these compound IDs from +subcomponents may be provided as needed. URL openers (described below) should +prefer to use the full compound ID in their URL format. + +[GCP KMS key IDs]: https://cloud.google.com/kms/docs/object-hierarchy#key + +### URLs + +To enable the [Backing services factor][] of a Twelve-Factor Application, Go +Cloud includes the ability to construct each of its API objects using +identifying URLs. The portable type's package should include APIs like the +following: + +```go +// Package foo is a portable API. foo could be something like blob or pubsub. +// +// Throughout this example, Widget is used as a stand-in for a portable type +// inside foo, like Bucket or Subscription. +package foo + +// A type that implements WidgetURLOpener can open widgets based on a URL. +// The opener must not modify the URL argument. OpenWidgetURL must be safe to +// call from multiple goroutines. +// +// WidgetURLOpeners should not assume that the URL has a particular scheme. +type WidgetURLOpener interface { + OpenWidgetURL(ctx context.Context, u *url.URL) (*Widget, error) +} + +// URLMux is a URL opener multiplexer. It matches the scheme of the URLs +// against a set of registered schemes and calls the opener that matches the +// URL's scheme. +// +// The zero value is a multiplexer with no registered schemes. +type URLMux struct { + // ... +} + +// RegisterWidget registers the opener with the given scheme. If an opener +// already exists for the scheme, RegisterWidget panics. +func (mux *URLMux) RegisterWidget(scheme string, opener WidgetURLOpener) { + // ... +} + +// OpenWidget calls OpenWidgetURL with the URL parsed from urlstr. +// OpenWidget is safe to call from multiple goroutines. +func (mux *URLMux) OpenWidget(ctx context.Context, urlstr string) (*Widget, error) { + u, err := url.Parse(urlstr) + if err != nil { + return nil, fmt.Errorf("open widget: %v", err) + } + return mux.OpenWidgetURL(ctx, u) +} + +// OpenWidgetURL dispatches the URL to the opener that is registered with the +// URL's scheme. OpenWidgetURL is safe to call from multiple goroutines. +func (mux *URLMux) OpenWidgetURL(ctx context.Context, u *url.URL) (*Widget, error) { + // ... +} + +// DefaultURLMux returns the URLMux used by OpenWidget. +func DefaultURLMux() *URLMux { + return defaultURLMux +} + +var defaultURLMux = new(URLMux) + +// OpenWidget opens the Widget identified by the URL given. URL openers must be +// registered in the DefaultURLMux, which is typically done in driver +// packages' initialization. +func OpenWidget(ctx context.Context, urlstr string) (*Widget, error) { + return DefaultURLMux().OpenWidget(urlstr) +} +``` + +The repetition of `Widget` in the method names permits a type to handle multiple +resources within the API. Exporting the `URLMux` allows applications to build +their own muxes, potentially wrapping existing ones. + +Driver packages should include their own `URLOpener` struct type which +implements all the relevant `WidgetURLOpener` methods. The URL should only serve +to identify which resource to open. Any credentials or other complex values +should be taken in as struct fields, not as input from URL. If the driver +package registers its `URLOpener` with the `DefaultURLMux`, then it should +populate these complex fields from environment variables. If doing so is +undesirable or expensive, then it should not register with the `DefaultURLMux` +and instead rely on users to create their own mux. If there already exists a +well-established URI format for the backend (like S3 URLs or database connection +URIs), then drivers should honor them where possible. + +[Backing services factor]: https://12factor.net/backing-services + +#### URL Examples + +A `WidgetURLOpener` implementation for a hypothetical GCP service: + +```go +package gcpfoo + +// ... + +const Scheme = "gcpwidget" + +type URLOpener struct { + Client *gcp.HTTPClient + Options Options +} + +func (o *URLOpener) OpenWidgetURL(ctx context.Context, u *url.URL) (*foo.Widget, error) { + // ... + return OpenWidget(ctx, o.Client, u.Host, &o.Options) +} + +type lazyURLOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazyURLOpener) OpenWidgetURL(ctx context.Context, u *url.URL) (*foo.Widget, error) { + o.init.Once(func() { + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + o.err = err + return + } + o.opener = new(URLOpener) + o.opener.Client, _ = gcp.NewHTTPClient(http.DefaultTransport, creds.TokenSource) + }) + if o.err != nil { + return nil, o.err + } + return o.opener.OpenWidgetURL(ctx, u) +} + +func init() { + foo.DefaultURLMux().Register(Scheme, new(lazyURLOpener)) +} + +// OpenWidget is the exported non-URL constructor. +func OpenWidget(ctx context.Context, c *gcp.HTTPClient, name string, opts *Options) (*foo.Widget, error) { + // ... +} +``` + +Using the global default mux: + +```go +import _ "gocloud.dev/foo/gcpfoo" + +// ... + +widget, err := foo.OpenWidget(context.Background(), "gcpwidget://xyzzy") +``` + +Using a custom mux created during server initialization: + +```go +myMux := new(foo.URLMux) +myMux.Register(gcpfoo.Scheme, &gcpfoo.URLOpener{ + Client: client, +}) +widget, err := myMux.OpenWidget(context.Background(), "gcpwidget://xyzzy") +``` + +## Errors + +### General + +- The callee is expected to return `error`s with messages that include + information about the particular call, as opposed to the caller adding this + information. This aligns with common Go practice. + +### Drivers + +Driver implementations should: + +- Return the raw errors from the underlying service, and not wrap them in + `fmt.Errorf` calls, so that they can be exposed to end users via `ErrorAs`. + +### Portable Types + +Portable types should: + +- Wrap errors returned from driver implementations before returning them to + end users, so that users can't peek into driver-specific error details + without using `As`. Make sure not to double-wrap. + +- Use `internal/gcerr.New` when wrapping driver errors, like so: `if err := + driver.Call(xyz); err != nil { return gcerr.New(code, err, 1, "blob") }` The + first argument is an error code. See below for advice on choosing the + appropriate code. + + The third argument is the distance in stack frames from the function whose + location should be associated with the error. It should be `1` if you are + calling `New` from the same function that made the driver call, `2` if you + are calling new from a helper function, and so on. The fourth argument is an + additional string that will display with the error. You should pass the API + name. + +- By default, choose the code `Unknown`, keeping details of returned `error`s + unspecified. The most common case is that the caller will only care whether + an operation succeeds or not. + +- If certain `error`s are interesting for callers to distinguish, choose one + of the other codes from the `gcerrors.ErrorCode` enum, so user programs can + act on the kind of error without having to look at driver-specific errors. + + - If more than one error code makes sense, choose the most specific one. + - If none make sense, choose `Unknown`. + - If none make sense but you want something more specific than `Unknown`: + - If you can generalize your code to make it applicable to more than + just your API, add it to `gcerrors.ErrorCode`. Look at the + [gRPC error codes](https://github.com/grpc/grpc-go/blob/master/codes/codes.go) + for inspiration. + - Otherwise, you can define a custom code in your portable API + package. Your code should use a negative integer. + +- For now, your package should expose an `ErrorAs` function to allow users to + access driver-specific error types. We may review this choice if + `golang.org/x/xerrors.As` becomes part of the standard library. + +- Handle transient network errors. Retry logic is best handled as low in the + stack as possible to avoid [cascading failure][]. APIs should try to surface + "permanent" errors (e.g. malformed request, bad permissions) where + appropriate so that application logic does not attempt to retry + non-idempotent operations, but the responsibility is largely on the library, + not on the application. + +[cascading failure]: +https://landing.google.com/sre/book/chapters/addressing-cascading-failures.html + +## Escape Hatches using As + +The Go CDK allows users to escape the abstraction as needed using `As` +functions, described in more detail in the +[concept guide](https://gocloud.dev/concepts/as/). `As` functions take an +`interface{}` and return a `bool`; they return `true` if the underlying concrete +type could be converted into the type provided as the `interface{}`. + +An alternative approach would have been something like +[`os.ProcessState.Sys`](https://golang.org/pkg/os/#ProcessState.Sys), which +returns an `interface{}` that the user can then type cast/assert to +service-specific types. + +We ended up going with `As` because: + +1. Most portable types have an `As` function for errors; choosing `As` results + in an easy and natural implementation for chained errors once the + [Go 2 proposal for errors](https://go.googlesource.com/proposal/+/master/design/29934-error-values.md) + arrives. It is currently implemented in + [xerrors](https://godoc.org/golang.org/x/xerrors#As), and we're already + using that in some drivers. +2. `As` adds more flexibility for drivers to support conversions to multiple + types. Specifically, not the case where there are multiple possible + underlying types, but rather that a single underlying type can be converted + to multiple types. + * Chained errors is one example of this, where the top-level error may + always be the same type, but may also represent a chain of other errors + with different types. + * Another example is that a driver might choose to support `As`-level + compatibility with another driver; e.g., driver `foo` could support all + of the `As` types defined by `s3blob`, converting them internally, and + then any code that runs with driver `s3blob` would also work with driver + `foo` (even if it uses the `As` escape hatches). + +## Enforcing Portability + +The Go CDK APIs will end up exposing functionality that is not supported by all +services. In addition, some functionality details will differ across services. +Some theoretical examples using [`blob.Bucket`][]: + +1. **Top-level APIs**: There might be a service that supports reads, but not + writes or deletes. +1. **Data fields**. Some services may support key/value metadata associated + with a blob, others may not. +1. **Naming rules**. Different services may allow different name lengths, or + allow/disallow non-ASCII unicode characters. See [Strings](#strings) below + for more on handling string differences. +1. **Semantic guarantees**. Different services may have different consistency + guarantees; for example, S3 only provides eventually consistency while GCS + provides strong consistency. + +How can we maintain portability while these differences exist? + +### Guiding Principle + +Any incompatibilities between drivers should be visible to the user as soon as +possible. From best to worst: + +1. At compile time +1. At configuration/app startup time (e.g., when the portable type is created) +1. At runtime (e.g., when the incompatible behavior is accessed), via a non-nil + error +1. At runtime, via panic + +### Approaches Considered + +1. **Documentation**. We could try to document non-uniform or optional + functionality across drivers. Optional fields or functionality would + return "not implemented" errors or zero values. +1. **Restrict functionality to the intersection**. We could explicitly only + support the intersection of all services. For example, if not all services + allow unicode characters in names, then **blob** would not allow it either. +1. **Enforced feature codes**: Go CDK APIs could enumerate the ways in which + drivers differ as a `FeatureCode` enum. + * Drivers would declare which feature codes they support, enforced by + extensions to the existing conformance tests. + * API users would declare which feature codes they need. + * Mismatches between what a user requests and what the driver supports + would be enforced at initialization time. + * As much as possible, the API (via the portable type) would enforce that + the user is only exposed to optional functionality that they asked for. + * For example, the default legal name for a blob might be ASCII only, with + a `FeatureUnicodeNames` feature code. Users that don't request this + feature code would only be able to use blobs with ASCII names, even if + the underlying service supports unicode. If the user requested + `FeatureUnicodeNames`, and their driver supports it, they could then + use blobs with unicode; if their driver doesn't support it, they would + get an initialization-time error. + +``` +b, err := blob.NewBucket(d, blob.FeatureUnicodeNames) +... +``` + +Design discussions regarding enforcing portability are ongoing; we welcome input +on the [mailing list](https://groups.google.com/forum/#!forum/go-cloud). + +### Strings + +Services often differ on what they accept in particular strings (e.g., blob +names, metadata keys, etc.). A couple of specific examples: + +* Azure Blob only + [accepts C# identifiers](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-properties-metadata) + as metadata keys. +* S3 drops double slashes in blob names (e.g., `foo//bar` will end up being + saved as `foo/bar`). + +These differences lead to a loss of portability and predictability for users. + +To resolve this issue, we insist that Go CDK can handle any UTF-8 string, and +force drivers to use escaping mechanisms to handle strings that the underlying +service can't handle. We enforce driver compliance with conformance tests. +Behavior for non-UTF-8 strings is undefined (but see +https://github.com/google/go-cloud/issues/1281 and +https://github.com/google/go-cloud/issues/1260). + +We try to use URL encoding as the escaping mechanism where possible; however, +sometimes it is not and we'll use custom escaping. As an example, a driver for a +service that only allows underscores and ASCII alphanumeric characters might +escape the string `foo.bar` to `foo__0x2e__bar` (URL escaping won't work because +`%` isn't allowed). + +Pros of this approach: + +* Go CDK APIs are internally consistent in that a user can write any string to + any service and get the original string back when they read it back. +* Go CDK APIs have visibility into all existing strings for all services. + +Cons: + +* Go CDK could overwrite existing data if a Go CDK-written key escapes to an + already-existing value (e.g., if the `foo__0x2e__bar` string already + existed, it would be overwritten by a Go CDK write to `foo.bar`). +* Escaping may push a string over the maximum allowed string length for a + service. Escaping does not solve (and in fact may exacerbate) problems with + different maximum string lengths across services. +* Existing strings that happen to look like Go CDK-escaped strings will be + unescaped by Go CDK (e.g., an existing string `foo__0x2e__bar` would appear + as `foo.bar` when read through the Go CDK). +* Strings that were written through the Go CDK and needed escaping will appear + in their escaped form when viewed outside of Go CDK (e.g., `foo__0x2e__bar` + would appear on the service's UI). + +Most of these cons are mitigated by choosing unusual-looking escape mechanisms +that are unlikely to appear in existing data. + +Drivers should escape strings when writing to the underlying service, and +unescape them when reading them back. The Go CDK will provide helpers for these +operations, as well as a test suite of strings for conformance tests. + +Sample code for the helper for escaping strings: + +``` +// package escape provides helpers for escaping and unescaping strings. +package escape + +// Escape returns s, with all runes for which shouldEscape returns true +// escaped to "__0xXXXX__", where XXXX is the hex representation of the rune +// value. For example, " " would escape to "__0x20__". +// +// Non-UTF-8 strings will have their non-UTF-8 characters escaped to +// unicode.ReplacementChar; the original value is lost. Please file an +// issue if you need non-UTF8 support. +// +// Note: shouldEscape takes the whole string as a slice of runes and an +// index. Passing it a single byte or a single rune doesn't provide +// enough context for some escape decisions; for example, the caller might +// want to escape the second "/" in "//" but not the first one. +// We pass a slice of runes instead of the string or a slice of bytes +// because some decisions will be made on a rune basis (e.g., encode +// all non-ASCII runes). +func Escape(s string, shouldEscape func(s []rune, i int) bool) string { ... } + +// Unescape reverses Escape. +func Unescape(s string) string {...} +``` + +Sample code for how a driver might use it, using metadata keys for a `blob` as +the example string: + +``` +// When writing metadata keys, escape the keys: +// ... gcdkMetadata is the metadata passed to the GCDK API. +for k, v := range gcdkMetadata { + e := escape.Escape(k, func (r []rune, i int) bool {...}) + if _, ok := serviceMetadata[e]; ok { + return fmt.Errorf("duplicate keys after escaping: %q => %q", k, e) + } + serviceMetadata[e] = v +} +// ... write serviceMetadata to the service. + +// When reading metadata keys, unescape them: +// ... serviceMetadata is the metadata read from the service. +for k, v := range serviceMetadata { + gcdkMetadata[escape.Unescape(k)] = v +} +// ... return gcdkMetadata. +``` + +The details of what runes need to be escaped will vary from service to +service. The details of how to escape may also vary, although we expect to use +URL encoding where possible, and a common custom escaping where not. For the +custom escaping, we plan to escape each rune for which `shouldEscape` returns +true with `__0xXXX__`, where `XCX` is the hex representation of the rune value. + +### Alternatives Considered + +* We considered restricting Go CDK's APIs to strings that all services + support. For example, we could have asserted that Go CDK's `blob` only + supports ASCII plus `/` for blob names (and no `//`!). However, such a rule + would mean that we couldn't cleanly handle existing strings created through + some mechanism other than through Go CDK APIs that violate the rule. For + example, an existing blob in S3 with a unicode name. Filtering out such + strings so that they aren't visible at all through the Go CDK would be both + surprising and limiting, and could easily result in data loss (e.g., if a + user read a set of metadata for a blob via the Go CDK, and some keys were + filtered out, and then wrote the metadata back, the filtered keys would be + lost). Not filtering such strings would mean that the Go CDK isn't + internally consistent (i.e., you can read some strings but not write them). + Overall, we decided that this approach is unacceptable. + +* We could expose the escaper used by drivers in their `Options` structs + (including options like disabling it, overriding the set of bytes to be + escaped, or overriding the escaping mechanism), but we'll wait to see if + there's demand for that. + +## Coding Conventions + +We try to adhere to commonly accepted Go coding conventions, some of which are +described on the +[Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments) +wiki page. We also adopt the following guidelines: + +- Prefer `map[K]V{}` to `make(map[K]V)`. It's more concise. +- When writing a loop appending to a slice `s`, prefer + + ``` + var s []T + for ... { + ... + s = append(s, ...) + ... + } + ``` + + to + + ``` + s := make([]T, 0, N) + for ... { + ... + s = append(s, ...) + ... + } + ``` + + or + + ``` + s := make([]T, N) + for ... { + ... + s[i] = ... + ... + } + ``` + + (Exception: the loop body is trivial and the loop is performance-sensitive.) + The first version is shorter and easier to read, and it is impossible to get + the length wrong. + +- Prefer `log.Fatal` to `panic` in example tests. + +- Ensure you've run `goimports` on your code to properly group import + statements. + +- Order arguments that are less likely to change across multiple calls to the + constructor before ones that are likely to change. For example, connection + and authorization related arguments should go before names, so + `OpenBucket(ctx, client, "mybucket")` instead of `OpenBucket(ctx, + "mybucket", client)`. + +## Tests + +### Conformance Tests + +Since our goal is for users to be able to use drivers interchangeably, it is +critical that they behave similarly. To this end, each portable API (e.g., +`blob`) must provide a suite of conformance tests that driver implementations +should run. The conformance tests should be comprehensive; drivers should not +need additional unit tests for the core driver semantics. + +### Provisioning For Tests + +Portable API integration tests require developer-specific resources to be +created and destroyed. We use [Terraform](http://terraform.io) to do so, and +record the resource info and network interactions so that they can be replayed +as fast and repeatable unit tests. + +### Replay Mode + +Tests normally run in replay mode. In this mode, they don't require any +provisioned resources or network interactions. Replay tests verify that: + +- The same test inputs produce the same requests (e.g., HTTP requests) to the + cloud service. Some parts of the request may be dynamic (e.g., dates in the + HTTP request headers), so the replay tests do some scrubbing when verifying + that requests match. Some parts of this scrubbing are service-specific. + +- The replayed service responses produce the expected results from the + portable API library. + +### Record Mode + +In `-record` mode, tests run as integration tests, making live requests to +backend servers and recording the requests/responses for later use in replay +mode. + +To use `-record`: + +1. Provision resources. + + - For example, the tests for the AWS implementation of Blob requires a + bucket to be provisioned. + - TODO(issue #300): Use Terraform scripts to provision the resources + needed for a given test. + - For now, do this manually. + +2. Run the test with `-record`. + + - TODO(issue #300): The test will read the Terraform output to find its + inputs. + - For now, pass the required resources via test-specific flags. + - When changing or adding tests, please only record the tests that are + changed/affected by passing the `-run` flag to `go test` with the + name of the test(s). Re-recording all tests of a driver creates a lot + of noise and a large diff that's difficult to review. + +3. The test will save the network interactions for subsequent replays. + + - TODO(issue #300): The test will save the Terraform output to a file in + order to replay using the same inputs. + - Commit the new replay files along with your code change. Expect to see + lots of diffs; see below for more discussion. + +### Diffs in replay files + +Each time portable API tests are run in `-record` mode, the resulting replay +files are different. Looking at diffs of these files isn't particularly useful. + +We [considered](https://github.com/google/go-cloud/issues/276) trying to scrub +the files of dynamic data so that diffs would be useful. We ended up deciding +not to do this, for several reasons: + +- There's a lot of dynamic data, in structured data of various forms (e.g., + HTTP headers, XML/JSON body, etc.). It would be difficult and fragile to + scrub it all. + +- The scrub process would also be fragile relative to changes in services + (e.g., adding a new dynamic HTTP response header). + +- The scrub process would need to be implemented for every new service, + increasing the barrier to entry for new implementations. + +- Scrubbing would likely be even more difficult for services using a + non-HTTP-based protocol (e.g., gRPC). + +- Scrubbing the data decreases the fidelity of the replay test, since it + wouldn't be operating on the original data. + +Overall, massive diffs in the replay files are expected and fine. As part of a +code change, you may want to check for things like the number of RPCs made to +identify performance regressions. diff --git a/go-cloud/internal/docs/img/user-facing-type-no-driver.png b/go-cloud/internal/docs/img/user-facing-type-no-driver.png new file mode 100644 index 000000000..61a6f23e3 Binary files /dev/null and b/go-cloud/internal/docs/img/user-facing-type-no-driver.png differ diff --git a/go-cloud/internal/docs/img/user-facing-type.png b/go-cloud/internal/docs/img/user-facing-type.png new file mode 100644 index 000000000..a802caee8 Binary files /dev/null and b/go-cloud/internal/docs/img/user-facing-type.png differ diff --git a/go-cloud/internal/docs/pubsub/design.md b/go-cloud/internal/docs/pubsub/design.md new file mode 100644 index 000000000..925cb5d66 --- /dev/null +++ b/go-cloud/internal/docs/pubsub/design.md @@ -0,0 +1,948 @@ +# Go CDK `pubsub` Design + +## Summary + +This document proposes a new `pubsub` package for the Go CDK. + +## Motivation + +A developer designing a new system with cross-cloud portability in mind could +choose a messaging system supporting pubsub, such as ZeroMQ, Kafka or RabbitMQ. +These pubsub systems run on AWS, Azure, GCP and others, so they pose no obstacle +to portability between clouds. They can also be run on-prem. Users wanting +managed pubsub could go with Confluent Cloud for Kafka (AWS, GCP), or CloudAMQP +for RabbitMQ (AWS, Azure) without losing much in the way of portability. + +So what’s missing? The solution described above means being locked into a +particular implementation of pubsub. There is also a potential for lock-in when +building systems in terms of the cloud-specific services such as AWS SNS+SQS, +GCP PubSub or Azure Service Bus. + +Developers may wish to compare different pubsub systems in terms of their +performance, reliability, cost or other factors, and they may want the option to +move between these systems without too much friction. A `pubsub` package in the +Go CDK could lower the cost of such experiments and migrations. + +## Goals + +* Publish messages to an existing topic. +* Receive messages from an existing subscription. +* Perform not much worse than 90% compared to directly using the APIs of + various pubsub systems. +* Work well with managed pubsub services on AWS, Azure, GCP and the most used + open source pubsub systems. + +## Non-goals + +* Create new topics in the cloud. The Go CDK focuses on developer concerns, + but topic creation is an + [operator concern](https://github.com/google/go-cloud/blob/master/internal/docs/design.md#developers-and-operators). + +* Create new subscriptions in the cloud. The subscribers are assumed to + correspond to components of a distributed system rather than to users of + that system. + +## Background + +[Pubsub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) is a +frequently requested feature for the Go CDK project +\[[github issue](https://github.com/google/go-cloud/issues/312)]. A key use case +motivating these requests is to support +[event driven architectures](https://en.wikipedia.org/wiki/Event-driven_architecture). + +There are several pubsub systems available that could be made to work with the +Go CDK by writing drivers for them. Here is a +[table](https://docs.google.com/a/google.com/spreadsheets/d/e/2PACX-1vQ2CML8muCrqhinxOeKTcWtwAeGk-RFFFMjB3O2u5DbbBt9R3YnUQcgRjRp6TySXe1CzSOtPVCsKACY/pubhtml) +comparing some of them. + +## Design overview + +### Developer’s perspective + +Given a topic that has already been created on the pubsub server, messages can +be sent to that topic by calling `acmepubsub.OpenTopic` and calling the `Send` +method of the returned `Topic`, like this (assuming a fictional pubsub service +called "acme"): + +```go +package main + +import ( + "context" + "log" + "net/http" + + rawacmepubsub "github.com/acme/pubsub" + "github.com/google/go-cloud/pubsub" + "github.com/google/go-cloud/pubsub/acmepubsub" +) + +func main() { + log.Fatal(serve()) +} + +func serve() error { + ctx := context.Background() + client, err := rawacmepubsub.NewClient(ctx, "unicornvideohub") + if err != nil { + return err + } + t, err := acmepubsub.OpenTopic(ctx, client, "user-signup", nil) + if err != nil { + return err + } + defer t.Close() + http.HandleFunc("/signup", func(w http.ResponseWriter, r *http.Request) { + err := t.Send(r.Context(), pubsub.Message{Body: []byte("Someone signed up")}) + if err != nil { + log.Println(err) + } + }) + return http.ListenAndServe(":8080", nil) +} +``` + +The call to `Send` will only return after the message has been sent to the +server or its sending has failed. + +Messages can be received from an existing subscription to a topic by calling the +`Receive` method on a `Subscription` object returned from +`acmepubsub.OpenSubscription`, like this: + +```go +package main + +import ( + "context" + "fmt" + "log" + + rawacmepubsub "github.com/acme/pubsub" + "github.com/google/go-cloud/pubsub" + "github.com/google/go-cloud/pubsub/acmepubsub" +) + +func main() { + if err := receive(); err != nil { + log.Fatal(err) + } +} + +func receive() error { + ctx := context.Background() + client, err := rawacmepubsub.NewClient(ctx, "unicornvideohub") + if err != nil { + return err + } + s, err := acmepubsub.OpenSubscription(ctx, client, "user-signup-minder", nil) + if err != nil { + return err + } + defer s.Close() + msg, err := s.Receive(ctx) + if err != nil { + return err + } + // Do something with msg. + fmt.Printf("Got message: %s\n", msg.Body) + // Acknowledge that we handled the message. + msg.Ack() +} +``` + +A more realistic subscriber client would process messages in a loop, like this: + +```go +package main + +import ( + "context" + "log" + "os" + "os/signal" + + "github.com/google/go-cloud/pubsub" + "github.com/google/go-cloud/pubsub/acmepubsub" +) + +func main() { + if err := receive(); err != nil { + log.Fatal(err) + } +} + +func receive() error { + ctx := context.Background() + client, err := rawacmepubsub.NewClient(ctx, "unicornvideohub") + if err != nil { + return err + } + s, err := acmepubsub.OpenSubscription(ctx, client, "signup-minder", nil) + if err != nil { + return err + } + defer s.Close() + + // Process messages. + for { + msg, err := s.Receive(ctx) + if err { + return err + } + log.Printf("Got message: %s\n", msg.Body) + msg.Ack() + } +} +``` + +The messages can be processed concurrently with an +[inverted worker pool](https://www.youtube.com/watch?v=5zXAHh5tJqQ&t=26m58s), +like this: + +```go +package main + +import ( + "context" + "log" + "os" + "os/signal" + + "github.com/google/go-cloud/pubsub" + "github.com/google/go-cloud/pubsub/acmepubsub" +) + +func main() { + if err := receive(); err != nil { + log.Fatal(err) + } +} + +func receive() error { + ctx := context.Background() + client, err := rawacmepubsub.NewClient(ctx, "unicornvideohub") + if err != nil { + return err + } + s, err := acmepubsub.OpenSubscription(ctx, client, "user-signup-minder", nil) + if err != nil { + return err + } + defer s.Close() + + // Process messages. + const poolSize = 10 + // Use a buffered channel as a semaphore. + sem := make(chan struct{}, poolSize) + for { + msg, err := s.Receive(ctx) + if err { + return err + } + sem <- struct{}{} + go func() { + log.Printf("Got message: %s", msg.Body) + msg.Ack() + <-sem + }() + } + for n := poolSize; n > 0; n-- { + sem <- struct{}{} + } +} +``` + +### Driver implementer’s perspective + +Adding support for a new pubsub system involves the following steps, continuing +with the "acme" example: + +1. Add a new package called `acmepubsub`. +2. Add private `topic` and `subscription` types to `acmepubsub` implementing + the corresponding interfaces in the `github.com/go-cloud/pubsub/driver` + package. +3. Add `func OpenTopic(...)` that creates an `acmepubsub.topic` and returns a + concrete `pubsub.Topic` object made from it. +4. Add `func OpenSubscription(...)` that creates an `acmepubsub.subscription` + and returns a `pubsub.Subscription` object made from it. + +Here is a sketch of what the `acmepubsub` package could look like: + +```go +package acmepubsub + +import ( + "context" + + rawacmepubsub "github.com/acme/pubsub" + "github.com/google/go-cloud/pubsub" + "github.com/google/go-cloud/pubsub/driver" +) + +// OpenTopic opens an existing topic on the pubsub server and returns a Topic +// that can be used to send messages to that topic. +func OpenTopic(ctx context.Context, client *rawacmepubsub.Client, topicName string) (*pubsub.Topic, error) { + rt, err := client.Topic(ctx, topicName) + if err != nil { + return nil, err + } + rt, err := client.Topic(ctx, topicName) + if err != nil { + return err + } + t := &topic{ rawTopic: rt } + return pubsub.NewTopic(t) +} + +// OpenSubscription opens an existing subscription on the server and returns a +// Subscription that can be used to receive messages. +func OpenSubscription(ctx context.Context, client *rawacmepubsub.Client, subscriptionName string) (*pubsub.Subscription, error) { + rs, err := client.Subscription(ctx, subscriptionName) + if err != nil { + return err + } + s := &subscription{ rawSub: rs } + return pubsub.NewSubscription(s) +} + +type topic struct { + rawTopic *rawacmepubsub.Topic +} + +func (t *topic) SendBatch(ctx context.Context, []*pubsub.Message) error { + // ... +} + +func (t *topic) Close() error { + // ... +} + +type subscription struct { + rawSub *rawacmepubsub.Subscription +} + +func (s *subscription) ReceiveBatch(ctx context.Context) ([]*pubsub.Message, error) { + // ... +} + +func (s *subscription) SendAcks(ctx context.Context, []pubsub.AckID) error { + // ... +} + +func (s *subscription) Close() error { + // ... +} +``` + +The driver interfaces are batch-oriented because some pubsub systems can more +efficiently deal with batches of messages than with one at a time. Streaming was +considered but it does not appear to provide enough of a performance gain to be +worth the additional complexity of supporting it across different pubsub systems +\[[benchmarks](https://github.com/ijt/pubsub/tree/master/benchmarks)]. + +The driver interfaces will be located in the +`github.com/google/go-cloud/pubsub/driver` package and will look something like +this: + +```go +package driver + +type AckID interface{} + +type Message struct { + // Body contains the content of the message. + Body []byte + + // Attributes has key/value metadata for the message. + Attributes map[string]string + + // AckID identifies the message on the server. + // It can be used to ack the message after it has been received. + AckID AckID +} + +// Topic publishes messages. +type Topic interface { + // SendBatch publishes all the messages in ms. + SendBatch(ctx context.Context, ms []*Message) error + + // Close disconnects the Topic. + Close() error +} + +// Subscription receives published messages. +type Subscription interface { + // ReceiveBatch should return a batch of messages that have queued up + // for the subscription on the server. + // + // If there is a transient failure, this method should not retry but + // should return a nil slice and an error. The concrete API will take + // care of retry logic. + // + // If the service returns no messages for some other reason, this + // method should return the empty slice of messages and not attempt to + // retry. + // + // ReceiveBatch is only called sequentially for individual + // Subscriptions. + ReceiveBatch(ctx context.Context) ([]*Message, error) + + // SendAcks acknowledges the messages with the given ackIDs on the + // server so that they + // will not be received again for this subscription. This method + // returns only after all the ackIDs are sent. + SendAcks(ctx context.Context, ackIDs []interface{}) error + + // Close disconnects the Subscription. + Close() error +} +``` + +## Detailed design + +The developer experience of using Go CDK's pubsub involves sending, receiving +and acknowledging one message at a time, all in terms of synchronous calls. +Behind the scenes, the driver implementations deal with batches of messages and +acks. The concrete API, to be written by the Go CDK team, takes care of creating +the batches in the case of Send or Ack, and dealing out messages one at a time +in the case of Receive. + +The concrete API will be located at `github.com/google/go-cloud/pubsub` and will +look something like this: + +```go +package pubsub + +import ( + "context" + "github.com/google/go-cloud/pubsub/driver" +) + +// Message contains data to be published. +type Message struct { + // Body contains the content of the message. + Body []byte + + // Attributes contains key/value pairs with metadata about the message. + Attributes map[string]string + + // ackID is an ID for the message on the server, used for acking. + ackID AckID + + // sub is the Subscription this message was received from. + sub *Subscription + + // isAcked is true if Ack has been called on this message. + isAcked bool +} + +type AckID interface{} + +// Ack acknowledges the message, telling the server that it does not need to +// be sent again to the associated Subscription. This method returns +// immediately. If Ack has already been called on the message, Ack panics. +func (m *Message) Ack() { + // Send the ack ID back to the subscriber for batching. + // The ack is sent to the server in a separate goroutine + // managed by the Subscription from which this message was + // received. + // ... +} + +// Topic publishes messages to all its subscribers. +type Topic struct { + driver driver.Topic + mcChan chan msgCtx + doneChan chan struct{} +} + +// msgCtx pairs a Message with the Context of its Send call. +type msgCtx struct { + msg *Message + ctx context.Context +} + +// Send publishes a message. It only returns after the message has been +// sent, or failed to be sent. The call will fail if ctx is canceled. +// Send can be called from multiple goroutines at once. +func (t *Topic) Send(ctx context.Context, m *Message) error { + // Send this message over t.mcChan and then wait for the batch including + // this message to be sent to the server. + // ... +} + +// Close disconnects the Topic. +func (t *Topic) Close() error { + close(t.doneChan) + return t.driver.Close() +} + +// NewTopic makes a pubsub.Topic from a driver.Topic. +func NewTopic(d driver.Topic) *Topic { + t := &Topic{ + driver: d, + mcChan: make(chan msgCtx), + doneChan: make(chan struct{}), + } + go func() { + // Pull messages from t.mcChan and put them in batches. Send the current + // batch whenever it is large enough or enough time has elapsed since + // the last send. + // ... + }() + return t +} + +// Subscription receives published messages. +type Subscription struct { + driver driver.Subscription + + // ackChan conveys ackIDs from Message.Ack to the ack batcher goroutine. + ackChan chan AckID + + // ackErrChan reports errors back to Message.Ack. + ackErrChan chan error + + // doneChan tells the goroutine from startAckBatcher to finish. + doneChan chan struct{} + + // q is the local queue of messages downloaded from the server. + q []*Message +} + +// Receive receives and returns the next message from the Subscription's queue, +// blocking if none are available. This method can be called concurrently from +// multiple goroutines. On systems that support acks, the Ack() method of the +// returned Message has to be called once the message has been processed, to +// prevent it from being received again. +func (s *Subscription) Receive(ctx context.Context) (*Message, error) { + if len(s.q) == 0 { + // Get the next batch of messages from the server. + // ... + } + m := s.q[0] + s.q = s.q[1:] + return m, nil +} + +// Close disconnects the Subscription. +func (s *Subscription) Close() error { + close(s.doneChan) + return s.driver.Close() +} + +// NewSubscription creates a Subscription from a driver.Subscription and opts to +// tune sending and receiving of acks and messages. Behind the scenes, +// NewSubscription spins up a goroutine to gather acks into batches and +// periodically send them to the server. +func NewSubscription(s driver.Subscription) *Subscription { + // Details similar to the body of NewTopic should go here. +} +``` + +Topics will gather messages into batches for sending. The batch size will be +dynamically tuned according to how many messages are being sent concurrently. + +Subscriptions will gather message acks into batches the same way, also +dynamically tuning the batch size. If sending acks back to the server fails +transiently then it will be retried, most likely within a loop in the concrete +API. If an unrecoverable error occurs while sending acks then a flag will be set +on the `pubsub.Subscription` saying that the whole `Subscription` is no longer +usable. Calls to `Receive` will fail from then on. + +## Alternative designs considered + +### Batch oriented concrete API + +In this alternative, the application code sends, receives and acknowledges +messages in batches. Here is an example of how it would look from the +developer's perspective, in a situation where not too many signups are happening +per second. + +```go +package main + +import ( + "context" + "log" + "net/http" + + rawacmepubsub "github.com/acme/pubsub" + "github.com/google/go-cloud/pubsub" + "github.com/google/go-cloud/pubsub/acmepubsub" +) + +func main() { + log.Fatal(serve()) +} + +func serve() error { + ctx := context.Background() + client, err := rawacmepubsub.NewClient(ctx, "unicornvideohub") + if err != nil { + return err + } + t, err := acmepubsub.OpenTopic(ctx, client, "user-signup", nil) + if err != nil { + return err + } + defer t.Close() + http.HandleFunc("/signup", func(w http.ResponseWriter, r *http.Request) { + err := t.Send(r.Context(), []pubsub.Message{{Body: []byte("Someone signed up")}}) + if err != nil { + log.Println(err) + } + }) + return http.ListenAndServe(":8080", nil) +} +``` + +For a company experiencing explosive growth or enthusiastic spammers creating +more signups than this simple-minded implementation can handle, the app would +have to be adapted to create non-singleton batches, like this: + +```go +package main + +import ( + "context" + "log" + "net/http" + + rawacmepubsub "github.com/acme/pubsub" + "github.com/google/go-cloud/pubsub" + "github.com/google/go-cloud/pubsub/acmepubsub" +) + +const batchSize = 1000 + +func main() { + log.Fatal(serve()) +} + +func serve() error { + ctx := context.Background() + client, err := rawacmepubsub.NewClient(ctx, "unicornvideohub") + if err != nil { + return err + } + t, err := acmepubsub.OpenTopic(ctx, client, "user-signup", nil) + if err != nil { + return err + } + defer t.Close() + c := make(chan *pubsub.Message) + go sendBatches(ctx, t, c) + http.HandleFunc("/signup", func(w http.ResponseWriter, r *http.Request) { + c <- &pubsub.Message{Body: []byte("Someone signed up")} + }) + return http.ListenAndServe(":8080", nil) +} + +func sendBatches(ctx context.Context, t *pubsub.Topic, c chan *pubsub.Message) { + batch := make([]*pubsub.Message, batchSize) + for { + for i := 0; i < batchSize; i++ { + batch[i] = <-c + } + if err := t.Send(ctx, batch); err != nil { + log.Println(err) + } + } +} +``` + +This shows how the complexity of batching has been pushed onto the application +code. Removing messages from the batch when HTTP/2 requests are canceled would +require the application code to be even more complex, adding more risk of bugs. + +In this API, the application code has to either request batches of size 1, +meaning more network traffic, or it has to explicitly manage the batches of +messages it receives. Here is an example of how this API would be used for +serial message processing: + +```go +package main + +import ( + "context" + "log" + "os" + "os/signal" + + rawacmepubsub "github.com/acme/pubsub" + "github.com/google/go-cloud/pubsub" + "github.com/google/go-cloud/pubsub/acmepubsub" +) + +const batchSize = 10 + +func main() { + if err := receive(); err != nil { + log.Fatal(err) + } +} + +func receive() error { + ctx := context.Background() + client, err := rawacmepubsub.NewClient(ctx, "unicornvideohub") + if err != nil { + return err + } + s, err := acmepubsub.OpenSubscription(ctx, client, "signup-minder", nil) + if err != nil { + return err + } + defer s.Close() + + // Process messages. + for { + msgs, err := s.Receive(ctx, batchSize) + if err { + return err + } + acks := make([]pubsub.AckID, 0, batchSize) + for _, msg := range msgs { + // Do something with msg. + fmt.Printf("Got message: %q\n", msg.Body) + acks = append(acks, msg.AckID) + } + err := s.SendAcks(ctx, acks) + if err != nil { + return err + } + } +} +``` + +Here’s what it might look like to use this batch-only API with the inverted +worker pool pattern: + +```go +package main + +import ( + "context" + "log" + "os" + "os/signal" + + rawacmepubsub "github.com/acme/pubsub" + "github.com/google/go-cloud/pubsub" + "github.com/google/go-cloud/pubsub/acmepubsub" +) + +const batchSize = 100 +const poolSize = 10 + +func main() { + if err := receive(); err != nil { + log.Fatal(err) + } +} + +func receive() error { + ctx := context.Background() + client, err := rawacmepubsub.NewClient(ctx, "unicornvideohub") + if err != nil { + return err + } + s, err := acmepubsub.OpenSubscription(ctx, client, "user-signup-minder", nil) + if err != nil { + return err + } + defer s.Close() + + // Receive the messages and forward them to a chan. + msgsChan := make(chan *pubsub.Message) + go func() { + for { + msgs, err := s.Receive(ctx, batchSize) + if err { + log.Fatal(err) + } + for _, m := range msgs { + msgsChan <- m + } + } + } + + // Get the acks from a chan and send them back to the + // server in batches. + acksChan := make(chan pubsub.AckID) + go func() { + for { + batch := make([]pubsub.AckID, batchSize) + for i := 0; i < len(batch); i++ { + batch[i] = <-acksChan + } + if err := s.SendAcks(ctx, batch); err != nil { + /* handle err */ + } + } + } + + // Use a buffered channel as a semaphore. + sem := make(chan struct{}, poolSize) + for msg := range msgsChan { + sem <- struct{}{} + go func(msg *pubsub.Message) { + log.Printf("Got message: %s", msg.Body) + acksChan <- msg.AckID + <-sem + }(msg) + } + for n := poolSize; n > 0; n-- { + sem <- struct{}{} + } +} +``` + +Here are some trade-offs of this design: + +Pro: + +* The semantics are simple, making it + * straightforward to implement the concrete API and the drivers for most + pubsub services + * easy for developers to reason about how it will behave + * less risky that bugs will be present in the concrete API +* Fairly efficient sending and receiving of messages is possible by tuning + batch size and the number of goroutines sending or receiving messages. + +Con: + +* This style of API makes the inverted worker pool pattern verbose. +* Apps needing to send or receive a large volume of messages must have their + own logic to create batches of size greater than 1. + +### go-micro + +Here is an example of what application code could look like for a pubsub API +inspired by [`go-micro`](https://github.com/micro/go-micro)'s `broker` package: + +```go +b := somepubsub.NewBroker(...) +if err := b.Connect(); err != nil { + /* handle err */ +} +topic := "user-signups" +subID := "user-signups-subscription-1" +s, err := b.Subscription(ctx, topic, subID, func(pub broker.Publication) error { + fmt.Printf("%s\n", pub.Message.Body) + return nil +}) +if err := b.Publish(ctx, topic, &broker.Message{ Body: []byte("alice signed up") }); err != nil { + /* handle err */ +} +// Sometime later: +if err := s.Unsubscribe(ctx); err != nil { + /* handle err */ +} +``` + +Pro: + +* The callback to the subscription returning an error to decide whether to + acknowledge the message means the developer cannot forget to ack. + +Con: + +* Go micro has code to auto-create + [topics](https://github.com/micro/go-plugins/blob/f3fcfcdf77392b4e053c8d5b361abfabc0c623d3/broker/googlepubsub/googlepubsub.go#L152) + and + [subscriptions](https://github.com/micro/go-plugins/blob/f3fcfcdf77392b4e053c8d5b361abfabc0c623d3/broker/googlepubsub/googlepubsub.go#L185) + as needed, but this is not consistent with the Go CDK’s design principle to + not get involved in operations. +* The subscription callback idea does not appear to be compatible with + inverted worker pools. + +## Acknowledgements + +In pubsub systems with acknowledgement, messages are kept in a queue associated +with the subscription on the server. When a client receives one of these +messages, its counterpart on the server is marked as being processed. Once the +client finishes processing the message, it sends an acknowledgement (or "ack") +to the server and the server removes the message from the subscription queue. +There may be a deadline for the acknowledgement, past which the server unmarks +the message so that it can be received again for another try at processing. + +Redis Pub/Sub and ZeroMQ don’t support acking, but many others do including GCP +PubSub, Azure Service Bus, RabbitMQ, and +[Redis Streams](https://redis.io/topics/streams-intro). Given the wide support +and usefulness, it makes sense to support message acking in the Go CDK. + +As of this writing, it is an open question as to what should be done about +pubsub systems that do not support acks. Some possibilities have been discussed, +but no clear best option has emerged yet: + +1. simulating acknowledgement by constructing queues on the server. Con: the + magically created queues would probably be a less than pleasant surprise for + some users. +2. making ack a no-op for systems that don't support it. With this, do we + return a sentinel error from `Ack`, and if so then doesn't that unduly + complicate the code for apps that never use non-acking systems? This option + is also potentially misleading for developers who would naturally assume + that un-acked messages would be redelivered. + +### Rejected acknowledgement API: `Receive` method returns an `ack` func + +In this alternative, the application code would look something like this: + +```go +msg, ack, err := s.Receive(ctx) +log.Printf("Received message: %q", msg.Body) +ack(msg) +``` + +Pro: + +* The compiler will complain if the returned `ack` function is not used. + +Con: + +* Receive has one more return value. +* Passing `ack` around along with `msg` is inconvenient. + +## Tests + +### Unit tests for the concrete API (`github.com/go-cloud/pubsub`) + +We can test that the batched sending, receiving and acking work as intended by +making mock implementations of the driver interfaces. + +At least the following things should be tested: + +* Calling `pubsub.Message.Ack` causes `driver.Subscription.SendAcks` to be + called. +* Calling `pubsub.Topic.Send` causes `driver.Topic.SendBatch` to be called. +* Calling `pubsub.Subscription.Receive` causes + `driver.Subscription.ReceiveBatch` to be called. + +### Conformance tests for specific implementations (*e.g.*, `github.com/go-cloud/pubsub/acmepubsub`) + +* Sent messages with random contents are received with the same contents. +* Sent messages with random attributes are received with the same attributes. +* Error occurs when making a local topic with an ID that doesn’t exist on the + server. +* Error occurs when making a subscription with an ID that doesn’t exist on the + server. +* Message gets sent again after ack deadline if a message is never + acknowledged. +* ~~Acked messages don't get received again after waiting twice the ack + deadline.~~ :point_left: This test would probably be too flakey. + +## Benchmarks + +What is the throughput and latency of the Go CDK's `pubsub` package, relative to +directly using the APIs for various services? + +* send, for 1, 10, 100 topics, and for 1, 10, 100 goroutines sending messages + to those topics +* receive, for 1, 10, 100 subscriptions, and for 1, 10, 100 goroutines + receiving from each subscription + +## References + +* https://github.com/google/go-cloud/issues/312 +* http://queues.io/ diff --git a/go-cloud/internal/docs/release.md b/go-cloud/internal/docs/release.md new file mode 100644 index 000000000..85deda596 --- /dev/null +++ b/go-cloud/internal/docs/release.md @@ -0,0 +1,63 @@ +# Releases + +To do a release: + +- Pick the new release name; it's probably `v0.x.0` where `x` is whatever the + [last release](https://github.com/google/go-cloud/releases/latest) was plus + one, but follow [semantic versioning](https://semver.org/). + +- Consider updating dependencies via `internal/testing/update_deps.sh` if it + hasn't been done recently. Do this as a separte step before the release. + +- Create a new branch for the release (`git checkout -B prerelease`). + +- Update the `User-Agent` version in internal/useragent/useragent.go. + +- Run the release helper tool to remove `replace` lines from the `go.mod` + files of submodules: + + ```bash + $ go run internal/releasehelper/releasehelper.go dropreplace + ``` + +- Run the release helper tool to set the version in `require` directives of + submodules to the new (yet unreleased) version: + + ```bash + $ go run internal/releasehelper/releasehelper.go setversion v0.x.0 + ``` + +- Commit and create a PR. Tests will fail for this PR because submodules depend on a + version of the main module that wasn't tagged yet, so you may have to + force-merge the PR. Note that this does not affect users, since a new + version hasn't been tagged yet. + +- `git sync` your local client and move to the master branch. + +- Tag new versions by running `./internal/testing/git_tag_modules.sh v0.X.0`. + +- Push tags to upstream with `git push upstream --tags` + +- Go to [Releases](https://github.com/google/go-cloud/releases). Click `Draft + a new release`, enter your release name, select your tag from the dropdown, + and enter release notes by clicking "Generate Release Notes". + + - Add a section for breaking changes, if any. They should be marked with + `BREAKING_CHANGE` in the PR title; however, that's not enforced so do + your best to look for them. + - Update the list of changes to remove anything that's not interesting + (e.g., updating dependencies, prerelease, minor cleanups, etc.). + +- Send an email to + [go-cloud@googlegroups.com](https://groups.google.com/forum/#!forum/go-cloud) + announcing the release, and including the release notes. + +- Create a new branch for the postrelease (`git checkout -B postrelease`). + +- Add back `replace` lines: + + ```bash + $ go run internal/releasehelper/releasehelper.go addreplace + ``` + + Run tests and send out a PR as usual. diff --git a/go-cloud/internal/escape/escape.go b/go-cloud/internal/escape/escape.go new file mode 100644 index 000000000..089a7af60 --- /dev/null +++ b/go-cloud/internal/escape/escape.go @@ -0,0 +1,214 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 escape includes helpers for escaping and unescaping strings. +package escape + +import ( + "fmt" + "net/url" + "strconv" + "strings" +) + +// NonUTF8String is a string for which utf8.ValidString returns false. +const NonUTF8String = "\xbd\xb2" + +// IsASCIIAlphanumeric returns true iff r is alphanumeric: a-z, A-Z, 0-9. +func IsASCIIAlphanumeric(r rune) bool { + switch { + case 'A' <= r && r <= 'Z': + return true + case 'a' <= r && r <= 'z': + return true + case '0' <= r && r <= '9': + return true + } + return false +} + +// HexEscape returns s, with all runes for which shouldEscape returns true +// escaped to "__0xXXX__", where XXX is the hex representation of the rune +// value. For example, " " would escape to "__0x20__". +// +// Non-UTF-8 strings will have their non-UTF-8 characters escaped to +// unicode.ReplacementChar; the original value is lost. Please file an +// issue if you need non-UTF8 support. +// +// Note: shouldEscape takes the whole string as a slice of runes and an +// index. Passing it a single byte or a single rune doesn't provide +// enough context for some escape decisions; for example, the caller might +// want to escape the second "/" in "//" but not the first one. +// We pass a slice of runes instead of the string or a slice of bytes +// because some decisions will be made on a rune basis (e.g., encode +// all non-ASCII runes). +func HexEscape(s string, shouldEscape func(s []rune, i int) bool) string { + // Do a first pass to see which runes (if any) need escaping. + runes := []rune(s) + var toEscape []int + for i := range runes { + if shouldEscape(runes, i) { + toEscape = append(toEscape, i) + } + } + if len(toEscape) == 0 { + return s + } + // Each escaped rune turns into at most 14 runes ("__0x7fffffff__"), + // so allocate an extra 13 for each. We'll reslice at the end + // if we didn't end up using them. + escaped := make([]rune, len(runes)+13*len(toEscape)) + n := 0 // current index into toEscape + j := 0 // current index into escaped + for i, r := range runes { + if n < len(toEscape) && i == toEscape[n] { + // We were asked to escape this rune. + for _, x := range fmt.Sprintf("__%#x__", r) { + escaped[j] = x + j++ + } + n++ + } else { + escaped[j] = r + j++ + } + } + return string(escaped[0:j]) +} + +// unescape tries to unescape starting at r[i]. +// It returns a boolean indicating whether the unescaping was successful, +// and (if true) the unescaped rune and the last index of r that was used +// during unescaping. +func unescape(r []rune, i int) (bool, rune, int) { + // Look for "__0x". + if r[i] != '_' { + return false, 0, 0 + } + i++ + if i >= len(r) || r[i] != '_' { + return false, 0, 0 + } + i++ + if i >= len(r) || r[i] != '0' { + return false, 0, 0 + } + i++ + if i >= len(r) || r[i] != 'x' { + return false, 0, 0 + } + i++ + // Capture the digits until the next "_" (if any). + var hexdigits []rune + for ; i < len(r) && r[i] != '_'; i++ { + hexdigits = append(hexdigits, r[i]) + } + // Look for the trailing "__". + if i >= len(r) || r[i] != '_' { + return false, 0, 0 + } + i++ + if i >= len(r) || r[i] != '_' { + return false, 0, 0 + } + // Parse the hex digits into an int32. + retval, err := strconv.ParseInt(string(hexdigits), 16, 32) + if err != nil { + return false, 0, 0 + } + return true, rune(retval), i +} + +// HexUnescape reverses HexEscape. +func HexUnescape(s string) string { + var unescaped []rune + runes := []rune(s) + for i := 0; i < len(runes); i++ { + if ok, newR, newI := unescape(runes, i); ok { + // We unescaped some runes starting at i, resulting in the + // unescaped rune newR. The last rune used was newI. + if unescaped == nil { + // This is the first rune we've encountered that + // needed unescaping. Allocate a buffer and copy any + // previous runes. + unescaped = make([]rune, i) + copy(unescaped, runes) + } + unescaped = append(unescaped, newR) + i = newI + } else if unescaped != nil { + unescaped = append(unescaped, runes[i]) + } + } + if unescaped == nil { + return s + } + return string(unescaped) +} + +// URLEscape uses url.PathEscape to escape s. +func URLEscape(s string) string { + return url.PathEscape(s) +} + +// URLUnescape reverses URLEscape using url.PathUnescape. If the unescape +// returns an error, it returns s. +func URLUnescape(s string) string { + if u, err := url.PathUnescape(s); err == nil { + return u + } + return s +} + +func makeASCIIString(start, end int) string { + var s []byte + for i := start; i < end; i++ { + if i >= 'a' && i <= 'z' { + continue + } + if i >= 'A' && i <= 'Z' { + continue + } + if i >= '0' && i <= '9' { + continue + } + s = append(s, byte(i)) + } + return string(s) +} + +// WeirdStrings are unusual/weird strings for use in testing escaping. +// The keys are descriptive strings, the values are the weird strings. +var WeirdStrings = map[string]string{ + "fwdslashes": "foo/bar/baz", + "repeatedfwdslashes": "foo//bar///baz", + "dotdotslash": "../foo/../bar/../../baz../", + "backslashes": "foo\\bar\\baz", + "repeatedbackslashes": "..\\foo\\\\bar\\\\\\baz", + "dotdotbackslash": "..\\foo\\..\\bar\\..\\..\\baz..\\", + "quote": "foo\"bar\"baz", + "spaces": "foo bar baz", + "startwithdigit": "12345", + "unicode": strings.Repeat("☺", 3), + // The ASCII characters 0-128, split up to avoid the possibly-escaped + // versions from getting too long. + "ascii-1": makeASCIIString(0, 16), + "ascii-2": makeASCIIString(16, 32), + "ascii-3": makeASCIIString(32, 48), + "ascii-4": makeASCIIString(48, 64), + "ascii-5": makeASCIIString(64, 80), + "ascii-6": makeASCIIString(80, 96), + "ascii-7": makeASCIIString(96, 112), + "ascii-8": makeASCIIString(112, 128), +} diff --git a/go-cloud/internal/escape/escape_test.go b/go-cloud/internal/escape/escape_test.go new file mode 100644 index 000000000..bf313595c --- /dev/null +++ b/go-cloud/internal/escape/escape_test.go @@ -0,0 +1,99 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 escape + +import ( + "testing" +) + +func TestHexEscape(t *testing.T) { + always := func([]rune, int) bool { return true } + + for _, tc := range []struct { + description, s, want string + should func([]rune, int) bool + }{ + { + description: "empty string", + s: "", + want: "", + should: always, + }, + { + description: "first rune", + s: "hello world", + want: "__0x68__ello world", + should: func(_ []rune, i int) bool { return i == 0 }, + }, + { + description: "last rune", + s: "hello world", + want: "hello worl__0x64__", + should: func(r []rune, i int) bool { return i == len(r)-1 }, + }, + { + description: "runes in middle", + s: "hello world", + want: "hello__0x20____0x20__world", + should: func(r []rune, i int) bool { return r[i] == ' ' }, + }, + { + description: "unicode", + s: "☺☺", + should: always, + want: "__0x263a____0x263a__", + }, + } { + got := HexEscape(tc.s, tc.should) + if got != tc.want { + t.Errorf("%s: got escaped %q want %q", tc.description, got, tc.want) + } + got = HexUnescape(got) + if got != tc.s { + t.Errorf("%s: got unescaped %q want %q", tc.description, got, tc.s) + } + } +} + +func TestHexEscapeUnescapeWeirdStrings(t *testing.T) { + for name, s := range WeirdStrings { + escaped := HexEscape(s, func(r []rune, i int) bool { return !IsASCIIAlphanumeric(r[i]) }) + unescaped := HexUnescape(escaped) + if unescaped != s { + t.Errorf("%s: got unescaped %q want %q", name, unescaped, s) + } + } +} + +func TestHexUnescapeOnInvalid(t *testing.T) { + // Unescaping of valid escape sequences is tested in TestEscape. + // This only tests invalid escape sequences, so Unescape is expected + // to do nothing. + for _, s := range []string{ + "0x68", + "_0x68_", + "__0x68_", + "_0x68__", + "__1x68__", + "__0y68__", + "__0xag__", // invalid hex digit + "__0x8fffffff__", // out of int32 range + } { + got := HexUnescape(s) + if got != s { + t.Errorf("%s: got %q want %q", s, got, s) + } + } +} diff --git a/go-cloud/internal/gcerr/errorcode_string.go b/go-cloud/internal/gcerr/errorcode_string.go new file mode 100644 index 000000000..009f4922d --- /dev/null +++ b/go-cloud/internal/gcerr/errorcode_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type=ErrorCode"; DO NOT EDIT. + +package gcerr + +import "strconv" + +const _ErrorCode_name = "OKUnknownNotFoundAlreadyExistsInvalidArgumentInternalUnimplementedFailedPreconditionPermissionDeniedResourceExhaustedCanceledDeadlineExceeded" + +var _ErrorCode_index = [...]uint8{0, 2, 9, 17, 30, 45, 53, 66, 84, 100, 117, 125, 141} + +func (i ErrorCode) String() string { + if i < 0 || i >= ErrorCode(len(_ErrorCode_index)-1) { + return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _ErrorCode_name[_ErrorCode_index[i]:_ErrorCode_index[i+1]] +} diff --git a/go-cloud/internal/gcerr/gcerr.go b/go-cloud/internal/gcerr/gcerr.go new file mode 100644 index 000000000..bf2b42036 --- /dev/null +++ b/go-cloud/internal/gcerr/gcerr.go @@ -0,0 +1,205 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcerr provides an error type for Go CDK APIs. +package gcerr + +import ( + "context" + "errors" + "fmt" + "io" + "reflect" + + "github.com/DataDog/iceberg-go/go-cloud/internal/retry" + "golang.org/x/xerrors" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// An ErrorCode describes the error's category. +type ErrorCode int + +const ( + // OK is returned by the Code function on a nil error. It is not a valid + // code for an error. + OK ErrorCode = 0 + + // Unknown means that the error could not be categorized. + Unknown ErrorCode = 1 + + // NotFound means that the resource was not found. + NotFound ErrorCode = 2 + + // AlreadyExists means that the resource exists, but it should not. + AlreadyExists ErrorCode = 3 + + // InvalidArguments means that a value given to a Go CDK API is incorrect. + InvalidArgument ErrorCode = 4 + + // Internal means that something unexpected happened. Internal errors always indicate + // bugs in the Go CDK (or possibly the underlying service). + Internal ErrorCode = 5 + + // Unimplemented means that the feature is not implemented. + Unimplemented ErrorCode = 6 + + // FailedPrecondition means that the system was in the wrong state. + FailedPrecondition ErrorCode = 7 + + // PermissionDenied means that the caller does not have permission to execute the specified operation. + PermissionDenied ErrorCode = 8 + + // ResourceExhausted means that some resource has been exhausted, typically because a service resource limit + // has been reached. + ResourceExhausted ErrorCode = 9 + + // Canceled means that the operation was canceled. + Canceled ErrorCode = 10 + + // DeadlineExceeded means that The operation timed out. + DeadlineExceeded ErrorCode = 11 +) + +// When adding a new error code, try to use the names defined in google.golang.org/grpc/codes. + +// Do not change the numbers assigned to codes: past values may be stored in metric databases. + +// Call "go generate" whenever you change the above list of error codes. +// To get stringer: +// go get golang.org/x/tools/cmd/stringer +// Make sure $GOPATH/bin or $GOBIN in on your path. + +//go:generate stringer -type=ErrorCode + +// An Error describes a Go CDK error. +type Error struct { + // Code is the error code. + Code ErrorCode + msg string + frame xerrors.Frame + err error +} + +// Error returns the error as a string. +func (e *Error) Error() string { + return fmt.Sprint(e) +} + +// Format formats the error. +func (e *Error) Format(s fmt.State, c rune) { + xerrors.FormatError(e, s, c) +} + +// FormatError formats the errots. +func (e *Error) FormatError(p xerrors.Printer) (next error) { + if e.msg == "" { + p.Printf("code=%v", e.Code) + } else { + p.Printf("%s (code=%v)", e.msg, e.Code) + } + e.frame.Format(p) + return e.err +} + +// Unwrap returns the error underlying the receiver, which may be nil. +func (e *Error) Unwrap() error { + return e.err +} + +// New returns a new error with the given code, underlying error and message. Pass 1 +// for the call depth if New is called from the function raising the error; pass 2 if +// it is called from a helper function that was invoked by the original function; and +// so on. +func New(c ErrorCode, err error, callDepth int, msg string) *Error { + return &Error{ + Code: c, + msg: msg, + frame: xerrors.Caller(callDepth), + err: err, + } +} + +// Newf uses format and args to format a message, then calls New. +func Newf(c ErrorCode, err error, format string, args ...any) *Error { + return New(c, err, 2, fmt.Sprintf(format, args...)) +} + +// DoNotWrap reports whether an error should not be wrapped in the Error +// type from this package. +// It returns true if err is a retry error, a context error, io.EOF, or if it wraps +// one of those. +func DoNotWrap(err error) bool { + if errors.Is(err, io.EOF) { + return true + } + if errors.Is(err, context.Canceled) { + return true + } + if errors.Is(err, context.DeadlineExceeded) { + return true + } + var r *retry.ContextError + return errors.As(err, &r) +} + +// GRPCCode extracts the gRPC status code and converts it into an ErrorCode. +// It returns Unknown if the error isn't from gRPC. +func GRPCCode(err error) ErrorCode { + switch status.Code(err) { + case codes.NotFound: + return NotFound + case codes.AlreadyExists: + return AlreadyExists + case codes.InvalidArgument: + return InvalidArgument + case codes.Internal: + return Internal + case codes.Unimplemented: + return Unimplemented + case codes.FailedPrecondition: + return FailedPrecondition + case codes.PermissionDenied: + return PermissionDenied + case codes.ResourceExhausted: + return ResourceExhausted + case codes.Canceled: + return Canceled + case codes.DeadlineExceeded: + return DeadlineExceeded + default: + return Unknown + } +} + +// ErrorAs is a helper for the ErrorAs method of an API's portable type. +// It performs some initial nil checks, and does a single level of unwrapping +// when err is a *gcerr.Error. Then it calls its errorAs argument, which should +// be a driver implementation of ErrorAs. +func ErrorAs(err error, target any, errorAs func(error, any) bool) bool { + if err == nil { + return false + } + if target == nil { + panic("ErrorAs target cannot be nil") + } + val := reflect.ValueOf(target) + if val.Type().Kind() != reflect.Ptr || val.IsNil() { + panic("ErrorAs target must be a non-nil pointer") + } + if e, ok := err.(*Error); ok { + err = e.Unwrap() + } + return errorAs(err, target) +} diff --git a/go-cloud/internal/gcerr/gcerr_test.go b/go-cloud/internal/gcerr/gcerr_test.go new file mode 100644 index 000000000..ddf1365b2 --- /dev/null +++ b/go-cloud/internal/gcerr/gcerr_test.go @@ -0,0 +1,118 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 gcerr + +import ( + "errors" + "fmt" + "regexp" + "strconv" + "strings" + "testing" +) + +func TestNewf(t *testing.T) { + e := Newf(Internal, nil, "a %d b", 3) + got := e.Error() + want := "a 3 b (code=Internal)" + if got != want { + t.Errorf("got %q, want %q", got, want) + } +} + +func TestFormatting(t *testing.T) { + for i, test := range []struct { + err *Error + verb string + want []string // regexps, one per line + }{ + { + New(NotFound, nil, 1, "message"), + "%v", + []string{`^message \(code=NotFound\)$`}, + }, + { + New(NotFound, nil, 1, "message"), + "%+v", + []string{ + `^message \(code=NotFound\):$`, + `\s+gocloud.dev/internal/gcerr.TestFormatting$`, + `\s+.*/internal/gcerr/gcerr_test.go:\d+$`, + }, + }, + { + New(AlreadyExists, errors.New("wrapped"), 1, "message"), + "%v", + []string{`^message \(code=AlreadyExists\): wrapped$`}, + }, + { + New(AlreadyExists, errors.New("wrapped"), 1, "message"), + "%+v", + []string{ + `^message \(code=AlreadyExists\):`, + `^\s+gocloud.dev/internal/gcerr.TestFormatting$`, + `^\s+.*/internal/gcerr/gcerr_test.go:\d+$`, + `^\s+- wrapped$`, + }, + }, + { + New(AlreadyExists, errors.New("wrapped"), 1, ""), + "%v", + []string{`^code=AlreadyExists: wrapped`}, + }, + { + New(AlreadyExists, errors.New("wrapped"), 1, ""), + "%+v", + []string{ + `^code=AlreadyExists:`, + `^\s+gocloud.dev/internal/gcerr.TestFormatting$`, + `^\s+.*/internal/gcerr/gcerr_test.go:\d+$`, + `^\s+- wrapped$`, + }, + }, + } { + t.Run(strconv.Itoa(i), func(t *testing.T) { + gotString := fmt.Sprintf(test.verb, test.err) + gotLines := strings.Split(gotString, "\n") + if got, want := len(gotLines), len(test.want); got != want { + t.Fatalf("got %d lines, want %d. got:\n%s", got, want, gotString) + } + for j, gl := range gotLines { + matched, err := regexp.MatchString(test.want[j], gl) + if err != nil { + t.Fatal(err) + } + if !matched { + t.Fatalf("line #%d: got %q, which doesn't match %q", j, gl, test.want[j]) + } + } + }) + } +} + +func TestError(t *testing.T) { + // Check that err.Error() == fmt.Sprintf("%s", err) + for _, err := range []*Error{ + New(NotFound, nil, 1, "message"), + New(AlreadyExists, errors.New("wrapped"), 1, "message"), + New(AlreadyExists, errors.New("wrapped"), 1, ""), + } { + got := err.Error() + want := fmt.Sprint(err) + if got != want { + t.Errorf("%v: got %q, want %q", err, got, want) + } + } +} diff --git a/go-cloud/internal/openurl/openurl.go b/go-cloud/internal/openurl/openurl.go new file mode 100644 index 000000000..718f60fa8 --- /dev/null +++ b/go-cloud/internal/openurl/openurl.go @@ -0,0 +1,103 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 openurl provides helpers for URLMux and URLOpeners in portable APIs. +package openurl // import "gocloud.dev/internal/openurl" + +import ( + "fmt" + "net/url" + "sort" + "strings" +) + +// SchemeMap maps URL schemes to values. The zero value is an empty map, ready for use. +// All schemes are stored and compared case-insensitively. +type SchemeMap struct { + api string + m map[string]any +} + +// Register registers scheme for value; subsequent calls to FromString or +// FromURL with scheme will return value. +// api is the portable API name (e.g., "blob"); the same value should always +// be passed. It should be in all lowercase. +// typ is the portable type (e.g., "Bucket"). +// Register panics if scheme has already been registered. +func (m *SchemeMap) Register(api, typ, scheme string, value any) { + if m.m == nil { + m.m = map[string]any{} + } + if api != strings.ToLower(api) { + panic(fmt.Errorf("api should be lowercase: %q", api)) + } + if m.api == "" { + m.api = api + } else if m.api != api { + panic(fmt.Errorf("previously registered using api %q (now %q)", m.api, api)) + } + scheme = strings.ToLower(scheme) + if _, exists := m.m[scheme]; exists { + panic(fmt.Errorf("scheme %q already registered for %s.%s", scheme, api, typ)) + } + m.m[scheme] = value +} + +// FromString parses urlstr as an URL and looks up the value for the URL's scheme. +func (m *SchemeMap) FromString(typ, urlstr string) (any, *url.URL, error) { + u, err := url.Parse(urlstr) + if err != nil { + return nil, nil, fmt.Errorf("open %s.%s: %v", m.api, typ, err) + } + val, err := m.FromURL(typ, u) + if err != nil { + return nil, nil, err + } + return val, u, nil +} + +// FromURL looks up the value for u's scheme. +func (m *SchemeMap) FromURL(typ string, u *url.URL) (any, error) { + scheme := strings.ToLower(u.Scheme) + if scheme == "" { + return nil, fmt.Errorf("open %s.%s: no scheme in URL %q", m.api, typ, u) + } + for _, prefix := range []string{ + fmt.Sprintf("%s+%s+", m.api, strings.ToLower(typ)), + fmt.Sprintf("%s+", m.api), + } { + scheme = strings.TrimPrefix(scheme, prefix) + } + v, ok := m.m[scheme] + if !ok { + return nil, fmt.Errorf("open %s.%s: no driver registered for %q for URL %q; available schemes: %v", m.api, typ, scheme, u, strings.Join(m.Schemes(), ", ")) + } + return v, nil +} + +// Schemes returns a sorted slice of the registered schemes. +func (m *SchemeMap) Schemes() []string { + var schemes []string + for s := range m.m { + schemes = append(schemes, s) + } + sort.Strings(schemes) + return schemes +} + +// ValidScheme returns true iff scheme has been registered. +func (m *SchemeMap) ValidScheme(scheme string) bool { + _, exists := m.m[strings.ToLower(scheme)] + return exists +} diff --git a/go-cloud/internal/openurl/openurl_test.go b/go-cloud/internal/openurl/openurl_test.go new file mode 100644 index 000000000..bb3e9f093 --- /dev/null +++ b/go-cloud/internal/openurl/openurl_test.go @@ -0,0 +1,76 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 openurl_test + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/internal/openurl" +) + +func TestSchemeMap(t *testing.T) { + const foo, bar = "foo value", "bar value" + + tests := []struct { + url string + wantErr bool + want any + }{ + {"invalid url", true, nil}, + {"foo://a/b/c", false, foo}, + {"api+foo://a/b/c", false, foo}, + {"api+type+foo://a/b/c", false, foo}, + {"bar://a?p=v", false, bar}, + {"api+bar://a", false, bar}, + {"api+type+bar://a", false, bar}, + {"typ+bar://a", true, nil}, + {"api+typ+bar://a", true, nil}, + } + + var emptyM, m openurl.SchemeMap + m.Register("api", "Type", "foo", foo) + m.Register("api", "Type", "bar", bar) + + if diff := cmp.Diff(m.Schemes(), []string{"bar", "foo"}); diff != "" { + t.Errorf("Schemes: %s", diff) + } + if !m.ValidScheme("foo") || !m.ValidScheme("bar") { + t.Errorf("ValidScheme didn't return true for valid scheme") + } + if m.ValidScheme("foo2") || m.ValidScheme("http") { + t.Errorf("ValidScheme didn't return false for invalid scheme") + } + + for _, test := range tests { + // Empty SchemeMap should always return an error. + if _, _, err := emptyM.FromString("type", test.url); err == nil { + t.Errorf("%s: empty SchemeMap got nil error, wanted non-nil error", test.url) + } + + got, gotURL, gotErr := m.FromString("type", test.url) + if (gotErr != nil) != test.wantErr { + t.Errorf("%s: got error %v, want error: %v", test.url, gotErr, test.wantErr) + } + if gotErr != nil { + continue + } + if got := gotURL.String(); got != test.url { + t.Errorf("%s: got URL %q want %v", test.url, got, test.url) + } + if got != test.want { + t.Errorf("%s: got %v want %v", test.url, got, test.want) + } + } +} diff --git a/go-cloud/internal/otel/metrics.go b/go-cloud/internal/otel/metrics.go new file mode 100644 index 000000000..c0f086726 --- /dev/null +++ b/go-cloud/internal/otel/metrics.go @@ -0,0 +1,170 @@ +// Copyright 2019-2025 The Go Cloud Development Kit 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 +// +// https://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 otel supports OpenTelemetry tracing and metrics for the Go Cloud Development Kit. +package otel + +import ( + "fmt" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "strings" +) + +// Units are encoded according to the case-sensitive abbreviations from the +// Unified Code for Units of Measure: http://unitsofmeasure.org/ucum.html. +const ( + unitDimensionless = "1" + unitMilliseconds = "ms" + unitBytes = "By" +) + +var ( + defaultMillisecondsBoundaries = []float64{ + 0.0, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0, + 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0, + 13.0, 16.0, 20.0, 25.0, 30.0, 40.0, + 50.0, 65.0, 80.0, 100.0, 130.0, 160.0, + 200.0, 250.0, 300.0, 400.0, 500.0, + 650.0, 800.0, 1000.0, 2000.0, 5000.0, 10000.0, + } +) + +func Views(pkg string) []sdkmetric.View { + + return []sdkmetric.View{ + + // View for latency histogram. + func(inst sdkmetric.Instrument) (sdkmetric.Stream, bool) { + if inst.Kind == sdkmetric.InstrumentKindHistogram { + if inst.Name == pkg+"/latency" { + return sdkmetric.Stream{ + Name: inst.Name, + Description: "Distribution of method latency, by provider and method.", + Aggregation: sdkmetric.AggregationExplicitBucketHistogram{ + Boundaries: defaultMillisecondsBoundaries, + }, + AttributeFilter: func(kv attribute.KeyValue) bool { + return kv.Key == packageKey || kv.Key == methodKey + }, + }, true + } + } + + return sdkmetric.Stream{}, false + }, + + // View for completed_calls count. + func(inst sdkmetric.Instrument) (sdkmetric.Stream, bool) { + if inst.Kind == sdkmetric.InstrumentKindHistogram { + if inst.Name == pkg+"/latency" { + return sdkmetric.Stream{ + Name: strings.Replace(inst.Name, "/latency", "/completed_calls", 1), + Description: "Count of method calls by provider, method and status.", + Aggregation: sdkmetric.DefaultAggregationSelector(sdkmetric.InstrumentKindCounter), + AttributeFilter: func(kv attribute.KeyValue) bool { + return kv.Key == methodKey || kv.Key == statusKey + }, + }, true + } + } + return sdkmetric.Stream{}, false + }, + } +} + +// CounterView returns summation views that add up individual measurements the counter takes. +func CounterView(pkg string, meterName string, description string) []sdkmetric.View { + return []sdkmetric.View{ + // View for gauge counts. + func(inst sdkmetric.Instrument) (sdkmetric.Stream, bool) { + if inst.Kind == sdkmetric.InstrumentKindCounter { + if inst.Name == pkg+meterName { + return sdkmetric.Stream{ + Name: inst.Name, + Description: description, + Aggregation: sdkmetric.DefaultAggregationSelector(sdkmetric.InstrumentKindCounter), + }, true + } + } + return sdkmetric.Stream{}, false + }, + } +} + +// LatencyMeasure returns the measure for method call latency used by Go CDK APIs. +func LatencyMeasure(pkg string, provider string) metric.Float64Histogram { + + attrs := []attribute.KeyValue{ + packageKey.String(pkg), + providerKey.String(provider), + } + + pkgMeter := otel.Meter(pkg, metric.WithInstrumentationAttributes(attrs...)) + + m, err := pkgMeter.Float64Histogram( + pkg+"/latency", + metric.WithDescription("Latency distribution of method calls"), + metric.WithUnit(unitMilliseconds), + ) + + if err != nil { + // The only possible errors are from invalid key or value names, and those are programming + // errors that will be found during testing. + panic(fmt.Sprintf("fullName=%q, provider=%q: %v", pkg, pkgMeter, err)) + } + + return m +} + +// DimensionlessMeasure creates a simple counter specifically for dimensionless measurements. +func DimensionlessMeasure(pkg string, provider string, meterName string, description string) metric.Int64Counter { + + attrs := []attribute.KeyValue{ + packageKey.String(pkg), + providerKey.String(provider), + } + + pkgMeter := otel.Meter(pkg, metric.WithInstrumentationAttributes(attrs...)) + + m, err := pkgMeter.Int64Counter(pkg+meterName, metric.WithDescription(description), metric.WithUnit(unitDimensionless)) + + if err != nil { + // The only possible errors are from invalid key or value names, + // and those are programming errors that will be found during testing. + panic(fmt.Sprintf("fullName=%q, provider=%q: %v", pkg, pkgMeter, err)) + } + return m +} + +// BytesMeasure creates a counter for bytes measurements. +func BytesMeasure(pkg string, provider string, meterName string, description string) metric.Int64Counter { + + attrs := []attribute.KeyValue{ + packageKey.String(pkg), + providerKey.String(provider), + } + + pkgMeter := otel.Meter(pkg, metric.WithInstrumentationAttributes(attrs...)) + m, err := pkgMeter.Int64Counter(pkg+meterName, metric.WithDescription(description), metric.WithUnit(unitBytes)) + + if err != nil { + // The only possible errors are from invalid key or value names, and those are programming + // errors that will be found during testing. + panic(fmt.Sprintf("fullName=%q, provider=%q: %v", pkg, pkgMeter, err)) + } + return m +} diff --git a/go-cloud/internal/otel/trace.go b/go-cloud/internal/otel/trace.go new file mode 100644 index 000000000..aa30a51a6 --- /dev/null +++ b/go-cloud/internal/otel/trace.go @@ -0,0 +1,124 @@ +// Copyright 2019-2025 The Go Cloud Development Kit 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 +// +// https://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 otel + +import ( + "context" + "fmt" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/trace" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "reflect" + "time" +) + +// Common attribute keys used across the Go CDK. +var ( + methodKey = attribute.Key("gocdk_method") + packageKey = attribute.Key("gocdk_package") + providerKey = attribute.Key("gocdk_provider") + statusKey = attribute.Key("gocdk_status") + errorKey = attribute.Key("gocdk_error") +) + +const ( + startTimeContextKey = "spanStartTimeCtxKey" + methodNameContextKey = "methodNameCtxKey" +) + +// Tracer provides OpenTelemetry tracing for Go CDK packages. +type Tracer struct { + pkg string + provider string + tracer trace.Tracer + latencyMeasure metric.Float64Histogram +} + +// ProviderName returns the name of the provider associated with the driver value. +// It is intended to be used as the provider argument to NewTracer. +// It actually returns the package path of the driver's type. +func ProviderName(driver any) string { + // Return the last component of the package path. + if driver == nil { + return "" + } + t := reflect.TypeOf(driver) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t.PkgPath() +} + +// NewTracer creates a new Tracer for a package and provider. +func NewTracer(pkg string, provider string) *Tracer { + + attrs := []attribute.KeyValue{ + packageKey.String(pkg), + providerKey.String(provider), + } + + tracer := otel.Tracer(pkg, trace.WithInstrumentationAttributes(attrs...)) + + return &Tracer{ + pkg: pkg, + provider: provider, + tracer: tracer, + latencyMeasure: LatencyMeasure(pkg, provider), + } +} + +// Start creates and starts a new span and returns the updated context and span. +func (t *Tracer) Start(ctx context.Context, methodName string) (context.Context, trace.Span) { + fullName := t.pkg + "." + methodName + + sCtx, span := t.tracer.Start(ctx, fullName, trace.WithAttributes(methodKey.String(methodName))) + sCtx = context.WithValue(sCtx, startTimeContextKey, time.Now()) + return context.WithValue(sCtx, methodNameContextKey, fullName), span +} + +// End completes a span with error information if applicable. +func (t *Tracer) End(ctx context.Context, span trace.Span, err error) { + startTime := ctx.Value(startTimeContextKey).(time.Time) + elapsed := time.Since(startTime) + + code := gcerrors.OK + + if err != nil { + code = gcerrors.Code(err) + span.SetAttributes( + errorKey.String(err.Error()), + statusKey.String(fmt.Sprint(code)), + ) + span.SetStatus(codes.Error, err.Error()) + span.RecordError(err) + } else { + span.SetStatus(codes.Ok, "") + } + + span.End() + + methodName := ctx.Value(methodNameContextKey).(string) + + t.latencyMeasure.Record(ctx, + float64(elapsed.Milliseconds()), + + metric.WithAttributes( + statusKey.String(fmt.Sprint(code)), + methodKey.String(methodName)), + ) +} diff --git a/go-cloud/internal/otel/trace_test.go b/go-cloud/internal/otel/trace_test.go new file mode 100644 index 000000000..d472dc9fd --- /dev/null +++ b/go-cloud/internal/otel/trace_test.go @@ -0,0 +1,42 @@ +// Copyright 2025 The Go Cloud Development Kit 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 +// +// https://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 otel + +import ( + "testing" +) + +type testDriver struct{} + +func TestProviderName(t *testing.T) { + testCases := []struct { + name string + driver any + want string + }{ + {"nil", nil, ""}, + {"struct", testDriver{}, "gocloud.dev/internal/otel"}, + {"pointer", &testDriver{}, "gocloud.dev/internal/otel"}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + got := ProviderName(tc.driver) + if got != tc.want { + t.Errorf("ProviderName(%#v) = %q, want %q", tc.driver, got, tc.want) + } + }) + } +} diff --git a/go-cloud/internal/releasehelper/releasehelper.go b/go-cloud/internal/releasehelper/releasehelper.go new file mode 100644 index 000000000..168955082 --- /dev/null +++ b/go-cloud/internal/releasehelper/releasehelper.go @@ -0,0 +1,262 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// Helper tool for creating new releases of the Go CDK. Run without arguments +// or with 'help' for details. +package main + +import ( + "bufio" + "encoding/json" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "strings" +) + +var helpText string = ` +Helper tool for creating new releases of the Go CDK. + +Automates the modifications required in the project's +go.mod files to create an test new releases. + +The tool processes all modules listed in the 'allmodules' +file. For each module it handles all dependencies on +other gocloud.dev modules. + +Run it from the root directory of the repository, as follows: + +$ %s + +Where command is one of the following: + + addreplace adds 'replace' directives to point to local versions + for testing. + + dropreplace removes these directives. + + setversion + sets 'required' version of modules to a given version formatted + as vX.Y.Z + + tag + runs 'git tag /' for all CDK modules + + help prints this usage message +` + +func printHelp() { + _, binName := filepath.Split(os.Args[0]) + fmt.Fprintf(os.Stderr, helpText, binName) + fmt.Fprintln(os.Stderr) +} + +// cmdCheck invokes the command given in s, echoing the invocation to stdout. +// It checks that the command was successful and returns its standard output. +// If the command returned a non-0 status, log.Fatal is invoked. +func cmdCheck(s string) []byte { + fmt.Printf(" -> %s\n", s) + fields := strings.Fields(s) + if len(fields) < 1 { + log.Fatal(`Expected "command "`) + } + b, err := exec.Command(fields[0], fields[1:]...).Output() + if exiterr, ok := err.(*exec.ExitError); ok { + log.Fatalf("%s; stderr: %s\n", err, string(exiterr.Stderr)) + } else if err != nil { + log.Fatal("exec.Command", err) + } + return b +} + +// GoMod holds "go mod" parameters, taken from "go mod help edit", in order to parse the JSON +// output of `go mod edit -json`. +type GoMod struct { + Module Module + Go string + Require []Require + Exclude []Module + Replace []Replace +} + +// Module represents a Go module. +type Module struct { + Path string + Version string +} + +// Require represents a required module. +type Require struct { + Path string + Version string + Indirect bool +} + +// Replace represents a replace directive. +type Replace struct { + Old Module + New Module +} + +// parseModuleInfo parses module information from a go.mod file at path. +func parseModuleInfo(path string) GoMod { + rawJson := cmdCheck("go mod edit -json " + path) + var modInfo GoMod + err := json.Unmarshal(rawJson, &modInfo) + if err != nil { + log.Fatal(err) + } + return modInfo +} + +// runOnGomod processes a single go.mod file (located in directory 'path'). +// Each require in the go.mod file is processed with reqHandler, a callback +// function. It's called with these arguments: +// +// gomodPath - path to the go.mod file where this 'require' was found +// mod - name of the module being 'require'd +// modPath - mod's location in the filesystem relative to +// the go.mod 'require'ing it +func runOnGomod(path string, reqHandler func(gomodPath, mod, modPath string)) { + gomodPath := filepath.Join(path, "go.mod") + fmt.Println("Processing", gomodPath) + modInfo := parseModuleInfo(gomodPath) + + base := "gocloud.dev" + + for _, r := range modInfo.Require { + // Find requirements on modules within the gocloud.dev tree. + if strings.HasPrefix(r.Path, base) { + // Find the relative path from 'path' and the module required here. + var reqPath string + if r.Path == base { + reqPath = "." + } else { + reqPath = strings.TrimPrefix(r.Path, base+"/") + } + rel, err := filepath.Rel(path, reqPath) + if err != nil { + log.Fatal(err) + } + // When path is '.', filepath.Rel will append a /. to the result and we + // may get paths like ../../. + if strings.HasSuffix(rel, "/.") { + rel, _ = filepath.Split(rel) + } + + reqHandler(gomodPath, r.Path, rel) + } + } +} + +func gomodAddReplace(path string) { + runOnGomod(path, func(gomodPath, mod, modPath string) { + cmdCheck(fmt.Sprintf("go mod edit -replace=%s=%s %s", mod, modPath, gomodPath)) + }) +} + +func gomodDropReplace(path string) { + runOnGomod(path, func(gomodPath, mod, modPath string) { + cmdCheck(fmt.Sprintf("go mod edit -dropreplace=%s %s", mod, gomodPath)) + }) +} + +func gomodSetVersion(path, v string) { + runOnGomod(path, func(gomodPath, mod, modPath string) { + cmdCheck(fmt.Sprintf("go mod edit -require=%s@%s %s", mod, v, gomodPath)) + }) +} + +func gomodTag(path, v string) { + var tagName string + if path == "." { + tagName = v + } else { + tagName = filepath.Join(path, v) + } + cmdCheck(fmt.Sprintf("git tag %s", tagName)) +} + +func validSemanticVersion(v string) bool { + match, err := regexp.MatchString(`v\d+\.\d+\.\d+`, v) + if err != nil { + return false + } + return match +} + +func main() { + if len(os.Args) < 2 { + printHelp() + os.Exit(0) + } + + var gomodHandler func(path string) + switch os.Args[1] { + case "help": + printHelp() + os.Exit(0) + case "addreplace": + gomodHandler = gomodAddReplace + case "dropreplace": + gomodHandler = gomodDropReplace + case "setversion": + if len(os.Args) < 3 || !validSemanticVersion(os.Args[2]) { + printHelp() + os.Exit(1) + } + gomodHandler = func(path string) { + gomodSetVersion(path, os.Args[2]) + } + case "tag": + if len(os.Args) < 3 || !validSemanticVersion(os.Args[2]) { + printHelp() + os.Exit(1) + } + gomodHandler = func(path string) { + gomodTag(path, os.Args[2]) + } + default: + printHelp() + os.Exit(1) + } + + f, err := os.Open("allmodules") + if err != nil { + log.Fatal(err) + } + + input := bufio.NewScanner(f) + input.Split(bufio.ScanLines) + for input.Scan() { + if len(input.Text()) > 0 && !strings.HasPrefix(input.Text(), "#") { + fields := strings.Fields(input.Text()) + if len(fields) != 2 { + log.Fatalf("want 2 fields, got %q\n", input.Text()) + } + // "tag" only runs if the released field is "yes". Other commands run + // for every line. + if os.Args[1] != "tag" || fields[1] == "yes" { + gomodHandler(fields[0]) + } + } + } + + if input.Err() != nil { + log.Fatal(input.Err()) + } +} diff --git a/go-cloud/internal/releasehelper/releasehelper_test.go b/go-cloud/internal/releasehelper/releasehelper_test.go new file mode 100644 index 000000000..db8f79ef3 --- /dev/null +++ b/go-cloud/internal/releasehelper/releasehelper_test.go @@ -0,0 +1,124 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "testing" +) + +// The following directory/file structure is created. ROOT is the root temp +// directory created by the test. +// +// ROOT/go.mod <-- main go.mod for gocloud.dev +// ROOT/submod/go.mod <-- go.mod for a submodule of gocloud.dev +// ROOT/samples/go.mod <-- go.mod for "samples" that include both of the +// +// other modules +var mainGomod = []byte("module gocloud.dev\n") + +var submodGomod = []byte(`module gocloud.dev/submod + +require ( + gocloud.dev v0.15.0 +) +`) + +var samplesGomod = []byte(`module gocloud.dev/samples + +require ( + gocloud.dev v0.15.0 + gocloud.dev/submod v0.15.0 +) +`) + +func createFilesForTest(root string) error { + if err := os.WriteFile(filepath.Join(root, "go.mod"), mainGomod, 0o666); err != nil { + return err + } + if err := os.MkdirAll(filepath.Join(root, "submod"), 0o766); err != nil { + return err + } + if err := os.WriteFile(filepath.Join(root, "submod", "go.mod"), submodGomod, 0o666); err != nil { + return err + } + if err := os.MkdirAll(filepath.Join(root, "samples"), 0o766); err != nil { + return err + } + if err := os.WriteFile(filepath.Join(root, "samples", "go.mod"), samplesGomod, 0o666); err != nil { + return err + } + return nil +} + +func Test(t *testing.T) { + tempDir := t.TempDir() + + fmt.Println("temp dir:", tempDir) + if err := createFilesForTest(tempDir); err != nil { + t.Fatal(err) + } + + if err := os.Chdir(tempDir); err != nil { + t.Fatal(err) + } + + // Add replace lines and expect to find them. + gomodAddReplace("samples") + + samplesGomod := filepath.Join("samples", "go.mod") + c, err := os.ReadFile(samplesGomod) + if err != nil { + t.Fatal(err) + } + + replaceLines := []string{ + "replace gocloud.dev => " + filepath.Clean("../"), + "replace gocloud.dev/submod => " + filepath.Clean("../submod"), + } + + for _, line := range replaceLines { + if !strings.Contains(string(c), line) { + t.Errorf("Expected to find %q in samples/go.mod", line) + } + } + + // Drop replace lines and expect not to find them. + gomodDropReplace("samples") + c, err = os.ReadFile(samplesGomod) + if err != nil { + t.Fatal(err) + } + + for _, line := range replaceLines { + if strings.Contains(string(c), line) { + t.Errorf("Expected to not find %q in samples/go.mod", line) + } + } + + // Set new version and check it was set as expected. + gomodSetVersion("samples", "v1.8.99") + c, err = os.ReadFile(samplesGomod) + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(string(c), "gocloud.dev v1.8.99") || !strings.Contains(string(c), "gocloud.dev/submod v1.8.99") { + t.Error("New versions for require not found in samples/go.mod") + } +} diff --git a/go-cloud/internal/retry/retry.go b/go-cloud/internal/retry/retry.go new file mode 100644 index 000000000..d06f0dace --- /dev/null +++ b/go-cloud/internal/retry/retry.go @@ -0,0 +1,80 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package retry provides retry logic. +package retry // import "gocloud.dev/internal/retry" + +import ( + "context" + "fmt" + "time" + + "github.com/googleapis/gax-go/v2" +) + +// Call calls the supplied function f repeatedly, using the isRetryable function and +// the provided backoff parameters to control the repetition. +// +// When f returns nil, Call immediately returns nil. +// +// When f returns an error for which isRetryable returns false, Call immediately +// returns that error. +// +// When f returns an error for which isRetryable returns true, Call sleeps for the +// provided backoff value and invokes f again. +// +// When the provided context is done, Retry returns a ContextError that includes both +// ctx.Error() and the last error returned by f, or nil if there isn't one. +func Call(ctx context.Context, bo gax.Backoff, isRetryable func(error) bool, f func() error) error { + return call(ctx, bo, isRetryable, f, gax.Sleep) +} + +// Split out for testing. +func call(ctx context.Context, bo gax.Backoff, isRetryable func(error) bool, f func() error, + sleep func(context.Context, time.Duration) error, +) error { + // Do nothing if context is done on entry. + if err := ctx.Err(); err != nil { + return &ContextError{CtxErr: err} + } + for { + err := f() + if err == nil { + return nil + } + if !isRetryable(err) { + return err + } + if cerr := sleep(ctx, bo.Pause()); cerr != nil { + return &ContextError{CtxErr: cerr, FuncErr: err} + } + } +} + +// A ContextError contains both a context error (either context.Canceled or +// context.DeadlineExceeded), and the last error from the function being retried, +// or nil if the function was never called. +type ContextError struct { + CtxErr error // The error obtained from ctx.Err() + FuncErr error // The error obtained from the function being retried, or nil +} + +func (e *ContextError) Error() string { + return fmt.Sprintf("%v; last error: %v", e.CtxErr, e.FuncErr) +} + +// Is returns true iff one of the two errors held in e is equal to target. +func (e *ContextError) Is(target error) bool { + return e.CtxErr == target || e.FuncErr == target +} diff --git a/go-cloud/internal/retry/retry_test.go b/go-cloud/internal/retry/retry_test.go new file mode 100644 index 000000000..c4def1b99 --- /dev/null +++ b/go-cloud/internal/retry/retry_test.go @@ -0,0 +1,144 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package retry + +import ( + "context" + "errors" + "os" + "testing" + "time" + + "github.com/googleapis/gax-go/v2" +) + +// Errors to distinguish retryable and non-retryable cases. +var ( + errRetry = errors.New("retry") + errNoRetry = errors.New("no retry") +) + +func retryable(err error) bool { + return err == errRetry +} + +func TestCall(t *testing.T) { + for _, test := range []struct { + desc string + isRetryable func(error) bool + f func(int) error // passed the number of calls so far + wantErr error // the return value of call + wantCount int // number of times f is called + }{ + { + desc: "f returns nil", + isRetryable: retryable, + f: func(int) error { return nil }, + wantCount: 1, + wantErr: nil, + }, + { + desc: "f returns non-retryable error", + isRetryable: retryable, + f: func(int) error { return errNoRetry }, + wantCount: 1, + wantErr: errNoRetry, + }, + { + desc: "f returns retryable error", + isRetryable: retryable, + f: func(n int) error { + if n < 2 { + return errRetry + } + return errNoRetry + }, + wantCount: 3, + wantErr: errNoRetry, + }, + { + desc: "f returns context error", // same as non-retryable + isRetryable: retryable, + f: func(int) error { return context.Canceled }, + wantCount: 1, + wantErr: context.Canceled, + }, + } { + t.Run(test.desc, func(t *testing.T) { + sleep := func(context.Context, time.Duration) error { return nil } + gotCount := 0 + f := func() error { gotCount++; return test.f(gotCount - 1) } + gotErr := call(context.Background(), gax.Backoff{}, test.isRetryable, f, sleep) + if gotErr != test.wantErr { + t.Errorf("error: got %v, want %v", gotErr, test.wantErr) + } + if gotCount != test.wantCount { + t.Errorf("retry count: got %d, want %d", gotCount, test.wantCount) + } + }) + } +} + +func TestCallCancel(t *testing.T) { + t.Run("done on entry", func(t *testing.T) { + // If the context is done on entry, f is never called. + ctx, cancel := context.WithCancel(context.Background()) + cancel() + gotCount := 0 + f := func() error { gotCount++; return nil } + gotErr := call(ctx, gax.Backoff{}, retryable, f, nil) + if gotCount != 0 { + t.Errorf("retry count: got %d, want 0", gotCount) + } + wantErr := &ContextError{CtxErr: context.Canceled} + if !equalContextError(gotErr, wantErr) { + t.Errorf("error: got %v, want %v", gotErr, wantErr) + } + }) + t.Run("done in sleep", func(t *testing.T) { + // If the context is done during sleep, we get a ContextError. + gotCount := 0 + f := func() error { gotCount++; return errRetry } + sleep := func(context.Context, time.Duration) error { return context.Canceled } + gotErr := call(context.Background(), gax.Backoff{}, retryable, f, sleep) + if gotCount != 1 { + t.Errorf("retry count: got %d, want 1", gotCount) + } + wantErr := &ContextError{CtxErr: context.Canceled, FuncErr: errRetry} + if !equalContextError(gotErr, wantErr) { + t.Errorf("error: got %v, want %v", gotErr, wantErr) + } + }) +} + +func equalContextError(got error, want *ContextError) bool { + cerr, ok := got.(*ContextError) + if !ok { + return false + } + return cerr.CtxErr == want.CtxErr && cerr.FuncErr == want.FuncErr +} + +func TestErrorsIs(t *testing.T) { + err := &ContextError{ + CtxErr: context.Canceled, + FuncErr: os.ErrExist, + } + for _, target := range []error{err, context.Canceled, os.ErrExist} { + if !errors.Is(err, target) { + t.Errorf("xerrors.Is(%v) == false, want true", target) + } + } +} diff --git a/go-cloud/internal/testing/alldeps b/go-cloud/internal/testing/alldeps new file mode 100644 index 000000000..e284c2fdf --- /dev/null +++ b/go-cloud/internal/testing/alldeps @@ -0,0 +1,204 @@ +cel.dev/expr +cloud.google.com/go +cloud.google.com/go/auth +cloud.google.com/go/auth/oauth2adapt +cloud.google.com/go/compute/metadata +cloud.google.com/go/firestore +cloud.google.com/go/iam +cloud.google.com/go/kms +cloud.google.com/go/longrunning +cloud.google.com/go/monitoring +cloud.google.com/go/pubsub +cloud.google.com/go/secretmanager +cloud.google.com/go/storage +cloud.google.com/go/trace +filippo.io/edwards25519 +github.com/Azure/azure-amqp-common-go/v3 +github.com/Azure/azure-sdk-for-go/sdk/azcore +github.com/Azure/azure-sdk-for-go/sdk/azidentity +github.com/Azure/azure-sdk-for-go/sdk/internal +github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys +github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal +github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob +github.com/Azure/go-amqp +github.com/Azure/go-autorest/autorest/to +github.com/AzureAD/microsoft-authentication-library-for-go +github.com/GoogleCloudPlatform/cloudsql-proxy +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping +github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator +github.com/IBM/sarama +github.com/XSAM/otelsql +github.com/aws/aws-sdk-go +github.com/aws/aws-sdk-go-v2 +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream +github.com/aws/aws-sdk-go-v2/config +github.com/aws/aws-sdk-go-v2/credentials +github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue +github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression +github.com/aws/aws-sdk-go-v2/feature/ec2/imds +github.com/aws/aws-sdk-go-v2/feature/s3/manager +github.com/aws/aws-sdk-go-v2/internal/configsources +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 +github.com/aws/aws-sdk-go-v2/internal/ini +github.com/aws/aws-sdk-go-v2/internal/v4a +github.com/aws/aws-sdk-go-v2/service/dynamodb +github.com/aws/aws-sdk-go-v2/service/dynamodbstreams +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding +github.com/aws/aws-sdk-go-v2/service/internal/checksum +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url +github.com/aws/aws-sdk-go-v2/service/internal/s3shared +github.com/aws/aws-sdk-go-v2/service/kms +github.com/aws/aws-sdk-go-v2/service/s3 +github.com/aws/aws-sdk-go-v2/service/secretsmanager +github.com/aws/aws-sdk-go-v2/service/sns +github.com/aws/aws-sdk-go-v2/service/sqs +github.com/aws/aws-sdk-go-v2/service/ssm +github.com/aws/aws-sdk-go-v2/service/sso +github.com/aws/aws-sdk-go-v2/service/ssooidc +github.com/aws/aws-sdk-go-v2/service/sts +github.com/aws/smithy-go +github.com/beorn7/perks +github.com/cenkalti/backoff/v4 +github.com/cenkalti/backoff/v5 +github.com/cespare/xxhash/v2 +github.com/cncf/xds/go +github.com/coreos/go-semver +github.com/coreos/go-systemd/v22 +github.com/davecgh/go-spew +github.com/eapache/go-resiliency +github.com/eapache/go-xerial-snappy +github.com/eapache/queue +github.com/envoyproxy/go-control-plane/envoy +github.com/envoyproxy/protoc-gen-validate +github.com/felixge/httpsnoop +github.com/fsnotify/fsnotify +github.com/go-jose/go-jose/v4 +github.com/go-logr/logr +github.com/go-logr/stdr +github.com/go-sql-driver/mysql +github.com/gogo/protobuf +github.com/golang-jwt/jwt/v5 +github.com/golang/protobuf +github.com/golang/snappy +github.com/google/go-cmp +github.com/google/go-replayers/grpcreplay +github.com/google/go-replayers/httpreplay +github.com/google/martian/v3 +github.com/google/s2a-go +github.com/google/subcommands +github.com/google/uuid +github.com/google/wire +github.com/googleapis/enterprise-certificate-proxy +github.com/googleapis/gax-go/v2 +github.com/gorilla/mux +github.com/grpc-ecosystem/grpc-gateway/v2 +github.com/hashicorp/errwrap +github.com/hashicorp/go-cleanhttp +github.com/hashicorp/go-multierror +github.com/hashicorp/go-retryablehttp +github.com/hashicorp/go-rootcerts +github.com/hashicorp/go-secure-stdlib/parseutil +github.com/hashicorp/go-secure-stdlib/strutil +github.com/hashicorp/go-sockaddr +github.com/hashicorp/go-uuid +github.com/hashicorp/hcl +github.com/hashicorp/vault/api +github.com/jcmturner/aescts/v2 +github.com/jcmturner/dnsutils/v2 +github.com/jcmturner/gofork +github.com/jcmturner/gokrb5/v8 +github.com/jcmturner/rpc/v2 +github.com/jmespath/go-jmespath +github.com/klauspost/compress +github.com/kylelemons/godebug +github.com/lib/pq +github.com/mitchellh/mapstructure +github.com/montanaflynn/stats +github.com/munnerz/goautoneg +github.com/nats-io/nats.go +github.com/nats-io/nkeys +github.com/nats-io/nuid +github.com/pierrec/lz4/v4 +github.com/pkg/browser +github.com/prometheus/client_golang +github.com/prometheus/client_model +github.com/prometheus/common +github.com/prometheus/procfs +github.com/rabbitmq/amqp091-go +github.com/rcrowley/go-metrics +github.com/ryanuber/go-glob +github.com/spiffe/go-spiffe/v2 +github.com/xdg-go/pbkdf2 +github.com/xdg-go/scram +github.com/xdg-go/stringprep +github.com/youmark/pkcs8 +github.com/zeebo/errs +go.etcd.io/etcd +go.etcd.io/etcd/api/v3 +go.etcd.io/etcd/client/pkg/v3 +go.etcd.io/etcd/client/v3 +go.mongodb.org/mongo-driver +go.opentelemetry.io/auto/sdk +go.opentelemetry.io/contrib/bridges/prometheus +go.opentelemetry.io/contrib/detectors/aws/ec2 +go.opentelemetry.io/contrib/detectors/gcp +go.opentelemetry.io/contrib/exporters/autoexport +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp +go.opentelemetry.io/contrib/propagators/autoprop +go.opentelemetry.io/contrib/propagators/aws +go.opentelemetry.io/contrib/propagators/b3 +go.opentelemetry.io/contrib/propagators/jaeger +go.opentelemetry.io/contrib/propagators/ot +go.opentelemetry.io/otel +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp +go.opentelemetry.io/otel/exporters/otlp/otlptrace +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp +go.opentelemetry.io/otel/exporters/prometheus +go.opentelemetry.io/otel/exporters/stdout/stdoutlog +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric +go.opentelemetry.io/otel/exporters/stdout/stdouttrace +go.opentelemetry.io/otel/log +go.opentelemetry.io/otel/metric +go.opentelemetry.io/otel/sdk +go.opentelemetry.io/otel/sdk/log +go.opentelemetry.io/otel/sdk/metric +go.opentelemetry.io/otel/trace +go.opentelemetry.io/proto/otlp +go.uber.org/multierr +go.uber.org/zap +gocloud.dev +gocloud.dev/docstore/mongodocstore +gocloud.dev/internal/website +gocloud.dev/pubsub/kafkapubsub +gocloud.dev/pubsub/natspubsub +gocloud.dev/pubsub/rabbitpubsub +gocloud.dev/runtimevar/etcdvar +gocloud.dev/samples +gocloud.dev/secrets/hashivault +golang.org/x/crypto +golang.org/x/mod +golang.org/x/net +golang.org/x/oauth2 +golang.org/x/sync +golang.org/x/sys +golang.org/x/text +golang.org/x/time +golang.org/x/tools +golang.org/x/xerrors +google.golang.org/api +google.golang.org/genproto +google.golang.org/genproto/googleapis/api +google.golang.org/genproto/googleapis/rpc +google.golang.org/grpc +google.golang.org/protobuf +gopkg.in/pipe.v2 diff --git a/go-cloud/internal/testing/check_mod_tidy.sh b/go-cloud/internal/testing/check_mod_tidy.sh new file mode 100755 index 000000000..94e05d89a --- /dev/null +++ b/go-cloud/internal/testing/check_mod_tidy.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# This script checks to see if `go mod tidy` has been run on the module +# in the current directory. +# +# It exits with status 1 if "go mod tidy && go list -deps ./..." would +# make changes. +# +# TODO(rvangent): Replace this with `go mod tidy --check` when it exists: +# https://github.com/golang/go/issues/27005. +# +# TODO(rvangent): Drop the "go list" part here and in gomodcleanup.sh once +# https://github.com/golang/go/issues/31248 is fixed. + +set -euo pipefail + +TMP_GOMOD=$(mktemp) +TMP_GOSUM=$(mktemp) + +function cleanup() { + # Restore the original files in case "go mod tidy" made changes. + if [[ -f "$TMP_GOMOD" ]]; then + mv "$TMP_GOMOD" ./go.mod + fi + if [[ -f "$TMP_GOSUM" ]]; then + mv "$TMP_GOSUM" ./go.sum + fi +} +trap cleanup EXIT + +# Make copies of the current files. +cp ./go.mod "$TMP_GOMOD" +cp ./go.sum "$TMP_GOSUM" + +# Modifies the files in-place. +go mod tidy +go list -deps ./... &> /dev/null + +# Check for diffs. +diff -u "$TMP_GOMOD" ./go.mod +diff -u "$TMP_GOSUM" ./go.sum diff --git a/go-cloud/internal/testing/deploywebsite.sh b/go-cloud/internal/testing/deploywebsite.sh new file mode 100644 index 000000000..3e508eebc --- /dev/null +++ b/go-cloud/internal/testing/deploywebsite.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# To update the website: +# +# Install Hugo locally, by downloading a version (at least 0.92) and unpacking: +# +# In $HUGODIR: +# +# wget https://github.com/gohugoio/hugo/releases/download/v0.91.2/hugo_0.91.2_Linux-64bit.tar.gz +# tar xvf hugo_0.91.2_Linux-64bit.tar.gz +# +# This creates a binary $HUGODIR/hugo +# +# In a go-cloud clone, run: +# +# $HUGODIR/hugo -s internal/website +# +# This updates the internal/website/public directory with the new contents of +# the website. Now we'll need a separate clone of go-cloud, with the gh-pages +# branch checked out: +# +# git clone git@github.com:google/go-cloud.git GH-PAGES-CLONE +# cd GH-PAGES-CLONE +# git co gh-pages +# +# This should have the contents of the website (configured in +# https://github.com/google/go-cloud/settings/pages). +# +# Once that's ready, copy the contents of internal/website/public into the root +# directory of the clone that's on the gh-pages branch, e.g. with rsync: +# +# rsync -avc internal/website/public/ GH-PAGES-CLONE +# +# Commit into the gh-pages branch and push it to origin (git push origin +# gh-pages). This deploys the new site contents. + +# (Old) +# Here's what we had in Travis: +# install: "curl -fsSL https://github.com/gohugoio/hugo/releases/download/v0.54.0/hugo_0.54.0_Linux-64bit.tar.gz | tar zxf - -C \"$HOME\" hugo" +# script: "HUGO_GOOGLEANALYTICS=UA-135118641-1 \"$HOME/hugo\" -s internal/website" +# deploy: +# provider: pages +# edge: true +# fqdn: gocloud.dev +# skip-cleanup: true +# local-dir: internal/website/public diff --git a/go-cloud/internal/testing/git_tag_modules.sh b/go-cloud/internal/testing/git_tag_modules.sh new file mode 100755 index 000000000..b895dd6bc --- /dev/null +++ b/go-cloud/internal/testing/git_tag_modules.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# Copyright 2021 The Go Cloud Development Kit 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 +# +# https://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. + +# This script should be run from the root directory. +# It creates git tags for all marked modules listed in the allmodules file. +set -euo pipefail + +function usage() { + echo + echo "Usage: git_tag_modules.sh vX.X.X" 1>&2 + echo " vX.X.X: the git tag version" + exit 64 +} + +if [[ $# -ne 1 ]] ; then + echo "Need at least one argument" + usage +fi +version="$1" + +sed -e '/^#/d' -e '/^$/d' allmodules | awk '{ print $1, $2}' | while read -r path update || [[ -n "$path" ]] ; do + if [[ "$update" != "yes" ]]; then + echo "$path is not marked to be released" + continue + fi + + tag="$version" + if [[ "$path" != "." ]]; then + tag="$path/$version" + fi + echo "Creating tag: ${tag}" + git tag "$tag" +done diff --git a/go-cloud/internal/testing/gomodcleanup.sh b/go-cloud/internal/testing/gomodcleanup.sh new file mode 100755 index 000000000..192ff9208 --- /dev/null +++ b/go-cloud/internal/testing/gomodcleanup.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# This script should be run from the root directory. +# It runs "go mod tidy && go list -deps ./..." on all modules in +# the repo, to ensure that go.mod and go.sum are in the canonical +# form that tests will verify (see check_mod_tidy.sh). +set -euo pipefail + +sed -e '/^#/d' -e '/^$/d' allmodules | awk '{print $1}' | while read -r path || [[ -n "$path" ]]; do + echo "cleaning up $path" + ( cd "$path" && go mod tidy && go list -deps ./... &> /dev/null || echo " FAILED!") +done diff --git a/go-cloud/internal/testing/listdeps.sh b/go-cloud/internal/testing/listdeps.sh new file mode 100755 index 000000000..b75c4d0a3 --- /dev/null +++ b/go-cloud/internal/testing/listdeps.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +set -euo pipefail + +# To run this script manually to update alldeps: +# +# $ internal/testing/listdeps.sh > internal/testing/alldeps +# +# Make sure to use the same version of Go as used by tests +# (see .github/actions/tests.yml) when updating the alldeps file. +tmpfile=$(mktemp) +function cleanup() { + rm -rf "$tmpfile" +} +trap cleanup EXIT + + +sed -e '/^#/d' -e '/^$/d' allmodules | awk '{print $1}' | while read -r path || [[ -n "$path" ]]; do + ( cd "$path" && go list -mod=readonly -deps -f '{{with .Module}}{{.Path}}{{end}}' ./... >> "$tmpfile") +done + +# Sort using the native byte values to keep results from different environment consistent. +LC_ALL=C sort "$tmpfile" | uniq diff --git a/go-cloud/internal/testing/oteltest/diff.go b/go-cloud/internal/testing/oteltest/diff.go new file mode 100644 index 000000000..444b461d2 --- /dev/null +++ b/go-cloud/internal/testing/oteltest/diff.go @@ -0,0 +1,215 @@ +// Copyright 2019-2025 The Go Cloud Development Kit 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 +// +// https://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 oteltest + +import ( + "fmt" + "go.opentelemetry.io/otel/codes" + "sort" + "strings" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +var ( + methodKey = attribute.Key("gocdk_method") + providerKey = attribute.Key("gocdk_provider") + statusKey = attribute.Key("gocdk_status") +) + +// Call represents a method call/span with its result code. +type Call struct { + Method string + Code gcerrors.ErrorCode + Attrs []attribute.KeyValue +} + +func formatSpanData(s sdktrace.ReadOnlySpan) string { + if s == nil { + return "missing" + } + // OTel uses codes.Code for status. + return fmt.Sprintf("", s.Name(), s.Status().Code.String()) +} + +func formatCall(c *Call) string { + if c == nil { + return "nothing" + } + // gcerrors.ErrorCode is an int, just print it. + return fmt.Sprintf("", c.Method, c.Code) +} + +// Diff compares the list of spans and metric data obtained from OpenTelemetry +// instrumentation (using a test exporter like `sdktrace/tracetest.NewExporter` +// and `sdkmetric/metrictest.NewExporter`) with an expected list of calls. +// The span/metric name and status code/status attribute are compared. +// Order matters for traces (though not for metrics). +// +// gotSpans should be the result from a test trace exporter (e.g., exporter.GetSpans()). +// gotMetrics should be the result from a test metric exporter (e.g., exporter.GetMetrics()). +// namePrefix is the prefix prepended to method names in spans/metrics mostly its the package name. +// provider is the name of the provider used (e.g., "aws"). +// want is the list of expected calls. +func Diff(gotSpans []sdktrace.ReadOnlySpan, gotMetrics []metricdata.ScopeMetrics, namePrefix, provider string, want []Call) string { + ds := diffSpans(gotSpans, namePrefix, want) + dc := DiffMetrics(gotMetrics, namePrefix, provider, want) + if len(ds) > 0 { + ds = "trace: " + ds + "\n" + } + if len(dc) > 0 { + dc = "metrics: " + dc + } + return ds + dc +} + +func mapStatusCode(code gcerrors.ErrorCode) codes.Code { + // For gcerrors used by gocloud, OK -> Ok, everything else -> Error is common. + if code == gcerrors.OK { + return codes.Ok + } + return codes.Error +} + +func diffSpans(got []sdktrace.ReadOnlySpan, prefix string, want []Call) string { + var diffs []string + add := func(i int, g sdktrace.ReadOnlySpan, w *Call) { + diffs = append(diffs, fmt.Sprintf("#%d: got %s, want %s", i, formatSpanData(g), formatCall(w))) + } + + for i := 0; i < len(got) || i < len(want); i++ { + var gotSpan sdktrace.ReadOnlySpan + if i < len(got) { + gotSpan = got[i] + } + + switch { + case i >= len(got): + add(i, nil, &want[i]) + case i >= len(want): + add(i, gotSpan, nil) + default: + expectedName := prefix + "." + want[i].Method + expectedCode := mapStatusCode(want[i].Code) // Map wanted gcerrors code to OTel code. + + if gotSpan == nil || gotSpan.Name() != expectedName || gotSpan.Status().Code != expectedCode { + w := want[i] + w.Method = prefix + "." + w.Method + add(i, gotSpan, &w) + } + } + } + return strings.Join(diffs, "\n") +} + +func DiffMetrics(got []metricdata.ScopeMetrics, prefix, provider string, wantCalls []Call) string { + // OTel metric data is structured. We need to iterate through it to find the + // relevant metric data points and their attributes. + var diffs []string + gotTags := map[string]bool{} // map of canonicalized data point attributes + + // Helper to convert attribute.Set to a canonical string key + attrSetToCanonicalString := func(set attribute.Set) string { + // Get key-value pairs, sort them, and format into a stable string. + attrs := make([]attribute.KeyValue, 0, set.Len()) + iter := set.Iter() + for iter.Next() { + attrs = append(attrs, iter.Attribute()) + } + sort.Slice(attrs, func(i, j int) bool { + return string(attrs[i].Key) < string(attrs[j].Key) + }) + parts := make([]string, len(attrs)) + for i, attr := range attrs { + // Format value based on type - attribute.Value doesn't have a simple String() + // that's guaranteed to be consistent for comparison. Using fmt.Sprint is safer. + parts[i] = fmt.Sprintf("%s:%s", attr.Key, fmt.Sprint(attr.Value.AsInterface())) + } + return strings.Join(parts, ",") + } + + // Helper function to collect relevant attributes for tag comparison. + processAtrributes := func(attrSets ...attribute.Set) { + + var requiredAttributes []attribute.KeyValue + for _, attrSet := range attrSets { + for _, a := range attrSet.ToSlice() { + if a.Key == providerKey { + requiredAttributes = append(requiredAttributes, a) + } + + if a.Key == methodKey { + requiredAttributes = append(requiredAttributes, a) + } + + if a.Key == statusKey { + requiredAttributes = append(requiredAttributes, a) + } + } + } + + if len(requiredAttributes) > 0 { + gotTags[attrSetToCanonicalString(attribute.NewSet(requiredAttributes...))] = true + } + + } + + // Iterate through all collected metrics to find relevant data points. + for _, sm := range got { + + for _, m := range sm.Metrics { + + // Using a switch will allow us accommodate other types of metrics. + switch v := m.Data.(type) { + case metricdata.Sum[int64]: + // Handle int64 Sum metrics. + for _, dp := range v.DataPoints { + processAtrributes(sm.Scope.Attributes, dp.Attributes) + } + case metricdata.Sum[float64]: + // gocloud usually records counts. Check for Sum metrics. + for _, dp := range v.DataPoints { + processAtrributes(sm.Scope.Attributes, dp.Attributes) + } + default: + // Handle any other types of metrics. + processAtrributes(sm.Scope.Attributes) + } + } + } + + // Check that each wanted call has a corresponding metric data point with the correct attributes. + for _, wc := range wantCalls { + // Construct the expected set of attributes for the wanted call. + expectedAttributes := []attribute.KeyValue{providerKey.String(provider)} + + if wc.Method != "" { + expectedAttributes = append(expectedAttributes, + methodKey.String(prefix+"."+wc.Method), + statusKey.String(fmt.Sprint(wc.Code))) + } + + // Canonicalize the expected attributes to check against the collected ones. + expectedKey := attrSetToCanonicalString(attribute.NewSet(expectedAttributes...)) + + if !gotTags[expectedKey] { + diffs = append(diffs, fmt.Sprintf("missing metric data point with attributes %q", expectedKey)) + } + } + return strings.Join(diffs, "\n") +} diff --git a/go-cloud/internal/testing/oteltest/exporter.go b/go-cloud/internal/testing/oteltest/exporter.go new file mode 100644 index 000000000..e6a17853f --- /dev/null +++ b/go-cloud/internal/testing/oteltest/exporter.go @@ -0,0 +1,183 @@ +// Copyright 2019-2025 The Go Cloud Development Kit 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 +// +// https://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 oteltest supports testing of OpenTelemetry integrations. +package oteltest + +import ( + "context" + "sync" + "testing" + + "go.opentelemetry.io/otel" + noopmetric "go.opentelemetry.io/otel/metric/noop" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/sdk/trace/tracetest" + nooptrace "go.opentelemetry.io/otel/trace/noop" +) + +// TestExporter is an exporter of OpenTelemetry traces and metrics, for testing. +// It should be created with NewTestExporter. +type TestExporter struct { + mu sync.Mutex + spanExporter *tracetest.InMemoryExporter + metricExporter *metricExporter + shutdown func(context.Context) error +} + +// metricExporter is a simple metrics exporter for testing. +// It implements the sdkmetric.Exporter interface. +type metricExporter struct { + mu sync.Mutex + reader sdkmetric.Reader + temporalitySelector sdkmetric.TemporalitySelector + aggregationSelector sdkmetric.AggregationSelector + rm *metricdata.ResourceMetrics +} + +var _ sdkmetric.Exporter = (*metricExporter)(nil) + +// newMetricExporter creates a new metric exporter for testing. +func newMetricExporter() *metricExporter { + + reader := sdkmetric.NewManualReader() + + return &metricExporter{ + reader: reader, + temporalitySelector: sdkmetric.DefaultTemporalitySelector, + aggregationSelector: sdkmetric.DefaultAggregationSelector, + rm: &metricdata.ResourceMetrics{}, + } +} + +// Temporality returns the aggregation temporality for the given instrument kind. +func (e *metricExporter) Temporality(kind sdkmetric.InstrumentKind) metricdata.Temporality { + return e.temporalitySelector(kind) +} + +// Aggregation returns the aggregation for the given instrument kind. +func (e *metricExporter) Aggregation(kind sdkmetric.InstrumentKind) sdkmetric.Aggregation { + return e.aggregationSelector(kind) +} + +// Export exports metric data. +func (e *metricExporter) Export(ctx context.Context, data *metricdata.ResourceMetrics) error { + + return nil +} + +// GetMetrics returns all collected metrics. +func (e *metricExporter) GetMetrics() []metricdata.ScopeMetrics { + e.mu.Lock() + defer e.mu.Unlock() + return e.rm.ScopeMetrics +} + +// ForceFlush forces a flush of metrics. +func (e *metricExporter) ForceFlush(ctx context.Context) error { + + err := e.reader.Collect(ctx, e.rm) + if err == nil { + return err + } + return e.Export(ctx, e.rm) +} + +// Reset the current in-memory storage. +func (e *metricExporter) Reset() { + e.mu.Lock() + defer e.mu.Unlock() + e.rm = &metricdata.ResourceMetrics{} +} + +// Shutdown shuts down the exporter. +func (e *metricExporter) Shutdown(ctx context.Context) error { + e.mu.Lock() + defer e.mu.Unlock() + e.Reset() + + return nil +} + +// NewTestExporter creates a TestExporter and registers it with OpenTelemetry. +func NewTestExporter(t *testing.T, views []sdkmetric.View) *TestExporter { + // Create span exporter + se := tracetest.NewInMemoryExporter() + + res := resource.NewSchemaless() + + traceShutdown, err := configureTraceProvider("test", se, sdktrace.AlwaysSample(), res, true) + if err != nil { + t.Fatalf("Failed to configure trace provider: %v", err) + } + // Create metric exporter + me := newMetricExporter() + + // Create and register meter provider. + metricsShutdown, err := configureMeterProvider("test", me.reader, res, views) + if err != nil { + t.Fatalf("Failed to configure meter provider: %v", err) + } + + shutdown := func(ctx context.Context) error { + err1 := traceShutdown(ctx) + err2 := metricsShutdown(ctx) + if err1 != nil { + return err1 + } + return err2 + } + + return &TestExporter{ + spanExporter: se, + metricExporter: me, + shutdown: shutdown, + } +} + +// GetSpans returns the collected span stubs. +func (te *TestExporter) GetSpans() tracetest.SpanStubs { + return te.spanExporter.GetSpans() +} + +// GetMetrics returns the collected metrics. +func (te *TestExporter) GetMetrics(ctx context.Context) []metricdata.ScopeMetrics { + + _ = te.metricExporter.ForceFlush(ctx) + + return te.metricExporter.GetMetrics() +} + +// ForceFlush forces the export of all metrics. +func (te *TestExporter) ForceFlush(ctx context.Context) error { + return te.metricExporter.ForceFlush(ctx) +} + +// Shutdown unregisters and shuts down the exporter. +func (te *TestExporter) Shutdown(ctx context.Context) error { + + if te.shutdown != nil { + err := te.shutdown(ctx) + if err != nil { + return err + } + } + // Reset global providers + otel.SetTracerProvider(nooptrace.NewTracerProvider()) + otel.SetMeterProvider(noopmetric.NewMeterProvider()) + return nil +} diff --git a/go-cloud/internal/testing/oteltest/init.go b/go-cloud/internal/testing/oteltest/init.go new file mode 100644 index 000000000..9ddda77bb --- /dev/null +++ b/go-cloud/internal/testing/oteltest/init.go @@ -0,0 +1,104 @@ +// Copyright 2025 The Go Cloud Development Kit 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 +// +// https://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 oteltest + +import ( + "context" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/propagation" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" +) + +// configureTraceProvider sets up the global trace provider with the given exporter. +// It returns a function to shut down the exporter. +func configureTraceProvider(serviceName string, exporter sdktrace.SpanExporter, sampler sdktrace.Sampler, res *resource.Resource, asyncExport bool) (func(context.Context) error, error) { + var err error + if res == nil { + res = resource.Default() + } + + res, err = resource.Merge( + res, + resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceName(serviceName), + ), + ) + if err != nil { + return nil, err + } + + if sampler == nil { + sampler = sdktrace.AlwaysSample() + } + + var exporterOpt sdktrace.TracerProviderOption + if asyncExport { + exporterOpt = sdktrace.WithSyncer(exporter) + } else { + exporterOpt = sdktrace.WithBatcher(exporter) + + } + + tp := sdktrace.NewTracerProvider( + exporterOpt, + sdktrace.WithResource(res), + sdktrace.WithSampler(sampler), + ) + + // Set the global trace provider. + otel.SetTracerProvider(tp) + + // Set the global propagator to tracecontext (the default is no-op). + otel.SetTextMapPropagator(propagation.TraceContext{}) + + return tp.Shutdown, nil +} + +// configureMeterProvider sets up the given meter provider with the given exporter. +// It returns a function to collect and export metrics on demand, and a shutdown function. +func configureMeterProvider(serviceName string, reader sdkmetric.Reader, res *resource.Resource, views []sdkmetric.View) (func(context.Context) error, error) { + var err error + if res == nil { + res = resource.Default() + } + + res, err = resource.Merge( + res, + resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceName(serviceName), + ), + ) + if err != nil { + return nil, err + } + + mp := sdkmetric.NewMeterProvider( + sdkmetric.WithReader(reader), + sdkmetric.WithResource(res), + sdkmetric.WithView(views...), + ) + + // Set the global meter provider. + otel.SetMeterProvider(mp) + + return func(ctx context.Context) error { + return mp.Shutdown(ctx) + }, nil +} diff --git a/go-cloud/internal/testing/runchecks.sh b/go-cloud/internal/testing/runchecks.sh new file mode 100755 index 000000000..965188873 --- /dev/null +++ b/go-cloud/internal/testing/runchecks.sh @@ -0,0 +1,197 @@ +#!/usr/bin/env bash +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +# This script runs all checks for Go CDK, including go test suites, +# compatibility checks, consistency checks, Wire, etc. + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +# Change to -euxo if debugging. +set -euo pipefail + +if [[ $# -gt 0 ]]; then + echo "usage: runchecks.sh" 1>&2 + exit 64 +fi + +# start_local_deps.sh requires that Docker is installed, +# which is only supported on Linux. +# Tests that depend on them should check the RUNNER_OS environment before running. +# Don't do this when running locally, as it's slow; user should do it. +if [[ "${RUNNER_OS:-}" == "Linux" ]]; then + echo + echo "Starting local dependencies..." + ./internal/testing/start_local_deps.sh +else + echo "Not starting local dependencies for ${RUNNER_OS:-}." +fi + +result=0 +rootdir="$(pwd)" + +# Update the regexp below when upgrading to a +# new Go version. Some checks below we only run +# for the latest Go version. +latest_go_version=0 +if [[ $(go version) == *go1\.24* ]]; then + latest_go_version=1 +fi + +# Build the test-summary app, which is used inside the loop to summarize results +# from Go tests. +(cd internal/testing/test-summary && go build) +while read -r path || [[ -n "$path" ]]; do + echo + echo "******************************" + echo "* Running Go tests for module: $path" + echo "******************************" + echo + + # TODO(rvangent): Special case modules to skip for Windows. Perhaps + # this should be data-driven by allmodules? + # (https://github.com/google/go-cloud/issues/2111). + if [[ "${RUNNER_OS:-}" == "Windows" ]] && [[ "$path" == "internal/website" ]]; then + echo " Skipping on Windows" + continue + fi + + gotestflags=("-json" "-race") + testsummaryflags=("-progress") + + if [[ $latest_go_version -eq 1 ]]; then + # Only do coverage for the latest Linux build because it is slow, and + # codecov will only save the last one anyway. + if [[ "${RUNNER_OS:-}" == "Linux" ]]; then + gotestflags+=("-coverpkg=./..." "-coverprofile=$rootdir/modcoverage.out") + fi + # Previous versions of the "go" command may have + # different opinions about what go.mod should look + # like. + gotestflags+=("-mod=readonly") + fi + + # Run the tests. + (cd "$path" && go test "${gotestflags[@]}" ./...) | ./internal/testing/test-summary/test-summary "${testsummaryflags[@]}" || result=1 + if [ -f modcoverage.out ] && [ $result -eq 0 ]; then + cat modcoverage.out >> coverage.out + rm modcoverage.out + fi +done < <( sed -e '/^#/d' -e '/^$/d' allmodules | awk '{print $1}' ) +# The above filters out comments and empty lines from allmodules and only takes +# the first (whitespace-separated) field from each line. + +# Upload cumulative coverage data if we generated it. +if [ -f coverage.out ] && [ $result -eq 0 ]; then + # Filter out test packages. + grep -v test coverage.out > coverage2.out + mv coverage2.out coverage.out + bash <(curl -s https://codecov.io/bash) + rm coverage.out +fi + +# The rest of these checks are not OS-specific, so we only run them for the +# Linux build, or when running locally. +if [[ "${RUNNER_OS:-linux}" != "Linux" ]]; then + exit $result +fi + +if [[ ${latest_go_version} -eq 1 ]]; then + echo + echo "************************" + echo "* Checking go mod tidy" + echo "************************" + echo + while read -r path || [[ -n "$path" ]]; do + echo "Module: $path" + ( cd "$path" && "$rootdir"/internal/testing/check_mod_tidy.sh && echo " OK" ) || { echo "FAIL: please run ./internal/testing/gomodcleanup.sh" && result=1; } + done < <( sed -e '/^#/d' -e '/^$/d' allmodules | awk '{print $1}' ) + # The above filters out comments and empty lines from allmodules and only takes + # the first (whitespace-separated) field from each line. +fi + + +if [[ ${latest_go_version} -eq 1 ]]; then + echo + echo "**********************" + echo "* Checking wire diff" + echo "**********************" + echo + echo "Installing Wire..." + go install github.com/google/wire/cmd/wire@latest + echo + while read -r path || [[ -n "$path" ]]; do + echo "Module: $path" + ( cd "$path" && wire diff ./... && echo " OK" ) || { echo "FAIL: wire diff found diffs!" && result=1; } + done < <( sed -e '/^#/d' -e '/^$/d' allmodules | awk '{print $1}' ) + # The above filters out comments and empty lines from allmodules and only takes + # the first (whitespace-separated) field from each line. +fi; + +if [[ ${latest_go_version} -eq 1 ]]; then + echo + echo "******************************" + echo "* Doing non-module checks" + echo "******************************" + echo + echo "Ensuring .go files are formatted with gofmt -s..." + DIFF="$(gofmt -s -d .)" + if [ -n "$DIFF" ]; then + echo "FAIL: please run 'gofmt -s -w .' and commit the result" + echo "$DIFF"; + exit 1; + else + echo " OK" + fi; +fi; + +if [[ ${latest_go_version} -eq 1 ]]; then + echo + echo "Ensuring that there are no dependencies not listed in ./internal/testing/alldeps..." + ( ./internal/testing/listdeps.sh | diff -u ./internal/testing/alldeps - && echo " OK" ) || { + echo "FAIL: dependencies changed; run: internal/testing/listdeps.sh > internal/testing/alldeps" && result=1 + # Module behavior may differ across versions. + echo "using the most recent go version." + } +fi + + +if [[ ${latest_go_version} -eq 1 ]]; then + echo + echo "Ensuring that any new packages have the corresponding entries in Hugo..." + missing_packages="$(internal/website/listnewpkgs.sh)" + if ! [[ -z "$missing_packages" ]]; then + echo "FAIL: missing package meta tags for:" 1>&2 + echo "$missing_packages" 1>&2 + result=1 + else + echo " OK" + fi + + echo + echo "Ensuring that all examples used in Hugo match what's in source..." + (internal/website/gatherexamples/run.sh | diff -u internal/website/data/examples.json - > /dev/null && echo " OK") || { + echo "FAIL: examples changed; run: internal/website/gatherexamples/run.sh > internal/website/data/examples.json" + result=1 + } +fi; + + +echo +if [[ ${result} -eq 0 ]]; then + echo "SUCCESS!" +else + echo "FAILED; see above for more info." +fi + +exit $result diff --git a/go-cloud/internal/testing/setup/setup.go b/go-cloud/internal/testing/setup/setup.go new file mode 100644 index 000000000..a1d9e4abc --- /dev/null +++ b/go-cloud/internal/testing/setup/setup.go @@ -0,0 +1,354 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 setup // import "gocloud.dev/internal/testing/setup" + +import ( + "context" + "flag" + "net/http" + "os" + "path/filepath" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + awscreds "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" + + awsv2 "github.com/aws/aws-sdk-go-v2/aws" + awsv2config "github.com/aws/aws-sdk-go-v2/config" + awsv2creds "github.com/aws/aws-sdk-go-v2/credentials" + + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/internal/useragent" + + "github.com/google/go-replayers/grpcreplay" + "github.com/google/go-replayers/httpreplay" + hrgoog "github.com/google/go-replayers/httpreplay/google" + "golang.org/x/oauth2/google" + "google.golang.org/api/option" + "google.golang.org/grpc" + grpccreds "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/oauth" +) + +// Record is true iff the tests are being run in "record" mode. +var Record = flag.Bool("record", false, "whether to run tests against cloud resources and record the interactions") + +// FakeGCPCredentials gets fake GCP credentials. +func FakeGCPCredentials(ctx context.Context) (*google.Credentials, error) { + return google.CredentialsFromJSON(ctx, []byte(`{"type": "service_account", "project_id": "my-project-id"}`)) +} + +func awsSession(region string, client *http.Client) (*session.Session, error) { + // Provide fake creds if running in replay mode. + var creds *awscreds.Credentials + if !*Record { + creds = awscreds.NewStaticCredentials("FAKE_ID", "FAKE_SECRET", "FAKE_TOKEN") + } + return session.NewSession(&aws.Config{ + HTTPClient: client, + Region: aws.String(region), + Credentials: creds, + MaxRetries: aws.Int(0), + }) +} + +func awsV2Config(ctx context.Context, region string, client *http.Client) (awsv2.Config, error) { + // Provide fake creds if running in replay mode. + var creds awsv2.CredentialsProvider + if !*Record { + creds = awsv2creds.NewStaticCredentialsProvider("FAKE_KEY", "FAKE_SECRET", "FAKE_SESSION") + } + return awsv2config.LoadDefaultConfig( + ctx, + awsv2config.WithHTTPClient(client), + awsv2config.WithRegion(region), + awsv2config.WithCredentialsProvider(creds), + awsv2config.WithRetryer(func() awsv2.Retryer { return awsv2.NopRetryer{} }), + ) +} + +// NewRecordReplayClient creates a new http.Client for tests. This client's +// activity is being either recorded to files (when *Record is set) or replayed +// from files. rf is a modifier function that will be invoked with the address +// of the httpreplay.Recorder object used to obtain the client; this function +// can mutate the recorder to add service-specific header filters, for example. +// An initState is returned for tests that need a state to have deterministic +// results, for example, a seed to generate random sequences. +func NewRecordReplayClient(ctx context.Context, t *testing.T, rf func(r *httpreplay.Recorder)) (c *http.Client, cleanup func(), initState int64) { + t.Helper() + + httpreplay.DebugHeaders() + path := filepath.Join("testdata", t.Name()+".replay") + if *Record { + t.Logf("Recording into golden file %s", path) + if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { + t.Fatal(err) + } + state := time.Now() + b, _ := state.MarshalBinary() + rec, err := httpreplay.NewRecorder(path, b) + if err != nil { + t.Fatal(err) + } + rf(rec) + cleanup = func() { + if err := rec.Close(); err != nil { + t.Fatal(err) + } + } + + return rec.Client(), cleanup, state.UnixNano() + } + t.Logf("Replaying from golden file %s", path) + rep, err := httpreplay.NewReplayer(path) + if err != nil { + t.Fatal(err) + } + recState := new(time.Time) + if err := recState.UnmarshalBinary(rep.Initial()); err != nil { + t.Fatal(err) + } + return rep.Client(), func() { rep.Close() }, recState.UnixNano() +} + +// NewAWSSession creates a new session for testing against AWS. +// If the test is in --record mode, the test will call out to AWS, and the +// results are recorded in a replay file. +// Otherwise, the session reads a replay file and runs the test as a replay, +// which never makes an outgoing HTTP call and uses fake credentials. +// An initState is returned for tests that need a state to have deterministic +// results, for example, a seed to generate random sequences. +func NewAWSSession(ctx context.Context, t *testing.T, region string) (sess *session.Session, + rt http.RoundTripper, cleanup func(), initState int64, +) { + t.Helper() + + client, cleanup, state := NewRecordReplayClient(ctx, t, func(r *httpreplay.Recorder) { + r.RemoveQueryParams("X-Amz-Credential", "X-Amz-Signature", "X-Amz-Security-Token") + r.RemoveRequestHeaders("Authorization", "Duration", "X-Amz-Security-Token") + r.ClearHeaders("X-Amz-Date") + r.ClearQueryParams("X-Amz-Date") + r.ClearHeaders("User-Agent") // AWS includes the Go version + }) + sess, err := awsSession(region, client) + if err != nil { + t.Fatal(err) + } + return sess, client.Transport, cleanup, state +} + +// NewAWSv2Config creates a new aws.Config for testing against AWS. +// If the test is in --record mode, the test will call out to AWS, and the +// results are recorded in a replay file. +// Otherwise, the session reads a replay file and runs the test as a replay, +// which never makes an outgoing HTTP call and uses fake credentials. +// An initState is returned for tests that need a state to have deterministic +// results, for example, a seed to generate random sequences. +// +// If scrubBody is true, the entire HTTP POST body is cleared for matching, +// so the tests will rely entirely on ordering and headers. +func NewAWSv2Config(ctx context.Context, t *testing.T, region string, scrubBody bool) (cfg awsv2.Config, rt http.RoundTripper, cleanup func(), initState int64) { + t.Helper() + + client, cleanup, state := NewRecordReplayClient(ctx, t, func(r *httpreplay.Recorder) { + r.RemoveQueryParams("X-Amz-Credential", "X-Amz-Signature", "X-Amz-Security-Token") + r.RemoveRequestHeaders("Authorization", "Duration", "X-Amz-Security-Token") + r.ClearHeaders("Amz-Sdk-Invocation-Id") + r.ClearHeaders("X-Amz-Date") + r.ClearQueryParams("X-Amz-Date") + r.ClearHeaders("User-Agent") // AWS includes the Go version + // The MessageAttributes parameter is a map, and so the values are + // in randomized order, so we can't match against them. Just scrub + // them and rely on the ordering. + r.ScrubBody("MessageAttributes.*") + if scrubBody { + r.ScrubBody(".*") + } + }) + cfg, err := awsV2Config(ctx, region, client) + if err != nil { + t.Fatal(err) + } + return cfg, client.Transport, cleanup, state +} + +// NewGCPClient creates a new HTTPClient for testing against GCP. +// NewGCPClient creates a new HTTPClient for testing against GCP. +// If the test is in --record mode, the client will call out to GCP, and the +// results are recorded in a replay file. +// Otherwise, the session reads a replay file and runs the test as a replay, +// which never makes an outgoing HTTP call and uses fake credentials. +func NewGCPClient(ctx context.Context, t *testing.T) (client *gcp.HTTPClient, rt http.RoundTripper, done func()) { + t.Helper() + + c, cleanup, _ := NewRecordReplayClient(ctx, t, func(r *httpreplay.Recorder) { + r.ClearQueryParams("Expires") + r.ClearQueryParams("Signature") + r.ClearHeaders("Expires") + r.ClearHeaders("Signature") + r.ClearHeaders("X-Goog-Gcs-Idempotency-Token") + r.ClearHeaders("User-Agent") + }) + transport := c.Transport + if *Record { + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + t.Fatalf("failed to get default credentials: %v", err) + } + c, err = hrgoog.RecordClient(ctx, c, option.WithTokenSource(gcp.CredentialsTokenSource(creds))) + if err != nil { + t.Fatal(err) + } + } + return &gcp.HTTPClient{Client: *c}, transport, cleanup +} + +// NewGCPgRPCConn creates a new connection for testing against GCP via gRPC. +// If the test is in --record mode, the client will call out to GCP, and the +// results are recorded in a replay file. +// Otherwise, the session reads a replay file and runs the test as a replay, +// which never makes an outgoing RPC and uses fake credentials. +func NewGCPgRPCConn(ctx context.Context, t *testing.T, endPoint, api string) (*grpc.ClientConn, func()) { + t.Helper() + + filename := t.Name() + ".replay" + if *Record { + opts, done := newGCPRecordDialOptions(t, filename) + opts = append(opts, useragent.GRPCDialOption(api)) + // Add credentials for real RPCs. + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + t.Fatal(err) + } + opts = append(opts, grpc.WithTransportCredentials(grpccreds.NewClientTLSFromCert(nil, ""))) + opts = append(opts, grpc.WithPerRPCCredentials(oauth.TokenSource{TokenSource: gcp.CredentialsTokenSource(creds)})) + conn, err := grpc.DialContext(ctx, endPoint, opts...) + if err != nil { + t.Fatal(err) + } + return conn, done + } + rep, done := newGCPReplayer(t, filename) + conn, err := rep.Connection() + if err != nil { + t.Fatal(err) + } + return conn, done +} + +// NewAzureTestBlobClient creates a new connection for testing against Azure Blob. +func NewAzureTestBlobClient(ctx context.Context, t *testing.T) (*http.Client, func()) { + t.Helper() + + client, cleanup, _ := NewRecordReplayClient(ctx, t, func(r *httpreplay.Recorder) { + r.RemoveQueryParams("se", "sig", "st") + r.RemoveQueryParams("X-Ms-Date") + r.ClearQueryParams("blockid") + r.ClearHeaders("X-Ms-Date") + r.ClearHeaders("X-Ms-Version") + r.ClearHeaders("User-Agent") // includes the full Go version + // Yes, it's true, Azure does not appear to be internally + // consistent about casing for BLock(l|L)ist. + r.ScrubBody(".*") + }) + return client, cleanup +} + +// NewAzureKeyVaultTestClient creates a *http.Client for Azure KeyVault test +// recordings. +func NewAzureKeyVaultTestClient(ctx context.Context, t *testing.T) (*http.Client, func()) { + t.Helper() + + client, cleanup, _ := NewRecordReplayClient(ctx, t, func(r *httpreplay.Recorder) { + r.RemoveQueryParams("se", "sig") + r.RemoveQueryParams("X-Ms-Date") + r.ClearHeaders("X-Ms-Date") + r.ClearHeaders("User-Agent") // includes the full Go version + }) + return client, cleanup +} + +// FakeGCPDefaultCredentials sets up the environment with fake GCP credentials. +// It returns a cleanup function. +func FakeGCPDefaultCredentials(t *testing.T) func() { + t.Helper() + + const envVar = "GOOGLE_APPLICATION_CREDENTIALS" + jsonCred := []byte(`{"client_id": "foo.apps.googleusercontent.com", "client_secret": "bar", "refresh_token": "baz", "type": "authorized_user"}`) + + f, err := os.CreateTemp(t.TempDir(), "fake-gcp-creds") + if err != nil { + t.Fatal(err) + } + if err := os.WriteFile(f.Name(), jsonCred, 0o666); err != nil { + t.Fatal(err) + } + + t.Setenv(envVar, f.Name()) + return func() { + t.Log("fake gcp default credentials done") + } +} + +// newGCPRecordDialOptions return grpc.DialOptions that are to be appended to a +// GRPC dial request. These options allow a recorder to intercept RPCs and save +// RPCs to the file at filename, or read the RPCs from the file and return them. +func newGCPRecordDialOptions(t *testing.T, filename string) (opts []grpc.DialOption, done func()) { + t.Helper() + + path := filepath.Join("testdata", filename) + os.MkdirAll(filepath.Dir(path), os.ModePerm) + t.Logf("Recording into golden file %s", path) + r, err := grpcreplay.NewRecorder(path, nil) + if err != nil { + t.Fatal(err) + } + opts = r.DialOptions() + done = func() { + if err := r.Close(); err != nil { + t.Errorf("unable to close recorder: %v", err) + } + } + return opts, done +} + +// newGCPReplayer returns a Replayer for GCP gRPC connections, as well as a function +// to call when done with the Replayer. +func newGCPReplayer(t *testing.T, filename string) (*grpcreplay.Replayer, func()) { + t.Helper() + + path := filepath.Join("testdata", filename) + t.Logf("Replaying from golden file %s", path) + r, err := grpcreplay.NewReplayer(path, nil) + if err != nil { + t.Fatal(err) + } + done := func() { + if err := r.Close(); err != nil { + t.Errorf("unable to close recorder: %v", err) + } + } + return r, done +} + +// HasDockerTestEnvironment returns true when either: +// 1) Not on Github Actions. +// 2) On Github's Linux environment, where Docker is available. +func HasDockerTestEnvironment() bool { + s := os.Getenv("RUNNER_OS") + return s == "" || s == "Linux" +} diff --git a/go-cloud/internal/testing/start_local_deps.sh b/go-cloud/internal/testing/start_local_deps.sh new file mode 100755 index 000000000..b9fe00325 --- /dev/null +++ b/go-cloud/internal/testing/start_local_deps.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Starts all local instances needed for Go CDK tests. +# You must have Docker installed. +# Run this script from the top level of the tree, e.g.: +# ./internal/testing/start_local_deps.sh + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +set -euo pipefail + +./pubsub/kafkapubsub/localkafka.sh +./pubsub/rabbitpubsub/localrabbit.sh +./runtimevar/etcdvar/localetcd.sh +./docstore/mongodocstore/localmongo.sh +./secrets/hashivault/localvault.sh + +sleep 10 diff --git a/go-cloud/internal/testing/terraform/terraform.go b/go-cloud/internal/testing/terraform/terraform.go new file mode 100644 index 000000000..7510e43c6 --- /dev/null +++ b/go-cloud/internal/testing/terraform/terraform.go @@ -0,0 +1,45 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 terraform provides a function to read Terraform output. +package terraform // import "gocloud.dev/internal/testing/terraform" + +import ( + "encoding/json" + "fmt" + "os/exec" +) + +// ReadOutput runs `terraform output` on the given directory and returns +// the parsed result. +func ReadOutput(dir string) (map[string]Output, error) { + c := exec.Command("terraform", "output", "-json") + c.Dir = dir + data, err := c.Output() + if err != nil { + return nil, fmt.Errorf("read terraform output: %v", err) + } + var parsed map[string]Output + if err := json.Unmarshal(data, &parsed); err != nil { + return nil, fmt.Errorf("read terraform output: %v", err) + } + return parsed, nil +} + +// Output describes a single output value. +type Output struct { + Type string `json:"type"` // one of "string", "list", or "map" + Sensitive bool `json:"sensitive"` + Value any `json:"value"` +} diff --git a/go-cloud/internal/testing/test-summary/test-summary.go b/go-cloud/internal/testing/test-summary/test-summary.go new file mode 100644 index 000000000..3faff6044 --- /dev/null +++ b/go-cloud/internal/testing/test-summary/test-summary.go @@ -0,0 +1,144 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// Summarizes the output of go test. +// Run like so: +// +// go test -json ./... | test-summary +package main + +import ( + "bufio" + "encoding/json" + "flag" + "fmt" + "io" + "log" + "os" + "path/filepath" + "strings" + "time" +) + +var ( + progress = flag.Bool("progress", false, "display test progress") + verbose = flag.Bool("verbose", false, "display all test output") +) + +// TestEvent is copied from "go doc test2json". +type TestEvent struct { + Time time.Time // encodes as an RFC3339-format string + Action string + Package string + Test string + Elapsed float64 // seconds + Output string +} + +func main() { + flag.Parse() + s, fails, err := run(os.Stdin) + if err != nil { + log.Fatal(err) + } + fmt.Println(s) + if fails { + os.Exit(1) + } +} + +func run(r io.Reader) (msg string, failures bool, err error) { + counts := map[string]int{} + scanner := bufio.NewScanner(bufio.NewReader(r)) + + // Collects tests that failed. + var failedTests []string + + // Stores output produced by each test. + testOutputs := map[string][]string{} + + start := time.Now() + for scanner.Scan() { + // When the build fails, go test -json doesn't emit a valid JSON value, only + // a line of output starting with FAIL. Report a more reasonable error in + // this case. + if strings.HasPrefix(scanner.Text(), "FAIL") { + return "", true, fmt.Errorf("No test output: %q", scanner.Text()) + } + + var event TestEvent + if err := json.Unmarshal(scanner.Bytes(), &event); err != nil { + return "", false, fmt.Errorf("%q: %v", scanner.Text(), err) + } + testpath := filepath.Join(event.Package, event.Test) + + // The Test field, if non-empty, specifies the test, example, or benchmark + // function that caused the event. Events for the overall package test do + // not set Test. + if event.Action == "fail" && event.Test != "" { + failedTests = append(failedTests, testpath) + } + + if event.Action == "output" { + if *verbose { + fmt.Print(event.Output) + } + testOutputs[testpath] = append(testOutputs[testpath], event.Output) + } + + // We don't want to count package passes/fails because these don't + // represent specific tests being run. However, skips of an entire package + // are not duplicated with individual test skips. + if event.Test != "" || event.Action == "skip" { + counts[event.Action]++ + } + + // For failed tests, print all the output we collected for them before + // the "fail" event. + if event.Action == "fail" { + fmt.Println(strings.Join(testOutputs[testpath], "")) + } + + if *progress { + // Only print progress for fail events for packages and tests, or + // pass events for packages only (not individual tests, since this is + // too noisy). + if event.Action == "fail" || (event.Test == "" && event.Action == "pass") { + fmt.Printf("%s %s (%.2fs)\n", event.Action, testpath, event.Elapsed) + } + } + } + if err := scanner.Err(); err != nil { + return "", false, err + } + p := counts["pass"] + f := counts["fail"] + s := counts["skip"] + + summary := fmt.Sprintf("ran %d; passed %d; failed %d; skipped %d (in %.1f sec)", p+f+s, p, f, s, time.Since(start).Seconds()) + if len(failedTests) > 0 { + var sb strings.Builder + sb.WriteString("Failures (reporting up to 10):\n") + for i := 0; i < len(failedTests) && i < 10; i++ { + fmt.Fprintf(&sb, " %s\n", failedTests[i]) + } + if len(failedTests) > 10 { + sb.WriteString(" ...\n") + } + sb.WriteString(summary) + summary = sb.String() + } + + return summary, f > 0, nil +} diff --git a/go-cloud/internal/testing/test-summary/test-summary_test.go b/go-cloud/internal/testing/test-summary/test-summary_test.go new file mode 100644 index 000000000..12555d0cf --- /dev/null +++ b/go-cloud/internal/testing/test-summary/test-summary_test.go @@ -0,0 +1,56 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "fmt" + "path/filepath" + "strings" + "testing" +) + +func Test(t *testing.T) { + got, fails, err := run(strings.NewReader(testOutput)) + if err != nil { + t.Fatal(err) + } + path := filepath.Join("gocloud.dev", "internal", "docstore", "internal", "fields", "TestUnexportedAnonymousNonStruct") + want := fmt.Sprintf(`Failures (reporting up to 10): + %s +ran 6; passed 3; failed 1; skipped 2 (in `, path) + if !strings.HasPrefix(got, want) { + t.Errorf("\ngot %s\nwant %s", got, want) + } + if !fails { + t.Error("wanted fails true, got false") + } +} + +const testOutput = `{"Time":"2019-05-09T16:39:56.83133991-04:00","Action":"run","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestFieldsNoTags"} +{"Time":"2019-05-09T16:39:56.831489481-04:00","Action":"output","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestFieldsNoTags","Output":"=== RUN TestFieldsNoTags\n"} +{"Time":"2019-05-09T16:39:56.831517464-04:00","Action":"output","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestFieldsNoTags","Output":"--- PASS: TestFieldsNoTags (0.00s)\n"} +{"Time":"2019-05-09T16:39:56.831535431-04:00","Action":"pass","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestFieldsNoTags","Elapsed":0} +{"Time":"2019-05-09T16:39:56.831551807-04:00","Action":"run","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestAgainstJSONEncodingNoTags"} +{"Time":"2019-05-09T16:39:56.831561396-04:00","Action":"output","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestAgainstJSONEncodingNoTags","Output":"=== RUN TestAgainstJSONEncodingNoTags\n"} +{"Time":"2019-05-09T16:39:56.831573783-04:00","Action":"output","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestAgainstJSONEncodingNoTags","Output":"--- PASS: TestAgainstJSONEncodingNoTags (0.00s)\n"} +{"Time":"2019-05-09T16:39:56.831584528-04:00","Action":"pass","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestAgainstJSONEncodingNoTags","Elapsed":0} +{"Time":"2019-05-09T16:39:56.844376487-04:00","Action":"output","Package":"gocloud.dev/internal/docstore/drivertest","Output":"? \tgocloud.dev/internal/docstore/drivertest\t[no test files]\n"} +{"Time":"2019-05-09T16:39:56.844397339-04:00","Action":"skip","Package":"gocloud.dev/internal/docstore/drivertest","Elapsed":0} +{"Time":"2019-05-09T16:39:56.831666898-04:00","Action":"output","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestFieldsWithTags","Output":"--- PASS: TestFieldsWithTags (0.00s)\n"} +{"Time":"2019-05-09T16:39:56.831677054-04:00","Action":"pass","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestFieldsWithTags","Elapsed":0} +{"Time":"2019-05-09T16:39:56.831729957-04:00","Action":"output","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestUnexportedAnonymousNonStruct","Output":"=== RUN TestUnexportedAnonymousNonStruct\n"} +{"Time":"2019-05-09T16:39:56.831759258-04:00","Action":"fail","Package":"gocloud.dev/internal/docstore/internal/fields","Test":"TestUnexportedAnonymousNonStruct","Elapsed":0} +{"Time":"2019-05-09T16:39:56.873905964-04:00","Action":"skip","Package":"gocloud.dev/internal/docstore/memdocstore","Test":"TestConformance/TypeDrivenCodec","Elapsed":0} +` diff --git a/go-cloud/internal/testing/update_deps.sh b/go-cloud/internal/testing/update_deps.sh new file mode 100755 index 000000000..4de372da0 --- /dev/null +++ b/go-cloud/internal/testing/update_deps.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# This script should be run from the root directory. +# It runs "go get -u && go mod tidy" on all modules in +# the repo, to update dependencies. Run runchecks.sh afterwards. +set -euo pipefail + +sed -e '/^#/d' -e '/^$/d' allmodules | awk '{print $1}' | while read -r path || [[ -n "$path" ]]; do + echo "updating $path" + ( cd "$path" && go get -u ./... &> /dev/null && go mod tidy &> /dev/null || echo " FAILED! (some modules without code, like samples, are expected to fail)") +done diff --git a/go-cloud/internal/useragent/useragent.go b/go-cloud/internal/useragent/useragent.go new file mode 100644 index 000000000..80f5e7ead --- /dev/null +++ b/go-cloud/internal/useragent/useragent.go @@ -0,0 +1,76 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 useragent includes constants and utilitiesfor setting the User-Agent +// for Go CDK connections to GCP. +package useragent // import "gocloud.dev/internal/useragent" + +import ( + "fmt" + "net/http" + + "google.golang.org/api/option" + "google.golang.org/grpc" +) + +const ( + prefix = "go-cloud" + version = "0.43.0" +) + +// ClientOption returns an option.ClientOption that sets a Go CDK User-Agent. +func ClientOption(api string) option.ClientOption { + return option.WithUserAgent(userAgentString(api)) +} + +// GRPCDialOption returns a grpc.DialOption that sets a Go CDK User-Agent. +func GRPCDialOption(api string) grpc.DialOption { + return grpc.WithUserAgent(userAgentString(api)) +} + +// AzureUserAgentPrefix returns a prefix that is used to set Azure SDK User-Agent to help with diagnostics. +func AzureUserAgentPrefix(api string) string { + return userAgentString(api) +} + +func userAgentString(api string) string { + return fmt.Sprintf("%s/%s/%s", prefix, api, version) +} + +// userAgentTransport wraps an http.RoundTripper, adding a User-Agent header +// to each request. +type userAgentTransport struct { + base http.RoundTripper + api string +} + +func (t *userAgentTransport) RoundTrip(req *http.Request) (*http.Response, error) { + // Clone the request to avoid mutating it. + newReq := *req + newReq.Header = make(http.Header) + for k, vv := range req.Header { + newReq.Header[k] = vv + } + // Append to the User-Agent string to preserve other information. + newReq.Header.Set("User-Agent", req.UserAgent()+" "+userAgentString(t.api)) + return t.base.RoundTrip(&newReq) +} + +// HTTPClient wraps client and appends a Go CDK string to the User-Agent +// header for all requests. +func HTTPClient(client *http.Client, api string) *http.Client { + c := *client + c.Transport = &userAgentTransport{base: c.Transport, api: api} + return &c +} diff --git a/go-cloud/internal/website/.vscode/tasks.json b/go-cloud/internal/website/.vscode/tasks.json new file mode 100644 index 000000000..61b8dfc72 --- /dev/null +++ b/go-cloud/internal/website/.vscode/tasks.json @@ -0,0 +1,67 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build", + "type": "shell", + "command": "hugo", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": { + "pattern": { + "regexp": "(ERROR|Error:) .*\"([^\"]+):(\\d+):(\\d+)\": (.*)$", + "file": 2, + "line": 3, + "column": 4, + "message": 5 + }, + "fileLocation": "absolute" + } + }, + { + "label": "Serve", + "type": "shell", + "command": "hugo serve --disableFastRender --port=8080", + "isBackground": true, + "problemMatcher": { + "pattern": { + "regexp": "(ERROR|Error:) .*\"([^\"]+):(\\d+):(\\d+)\": (.*)$", + "file": 2, + "line": 3, + "column": 4, + "message": 5 + }, + "fileLocation": "absolute", + "background": { + "activeOnStart": true, + "beginsPattern": "^Change detected, rebuilding site$", + "endsPattern": "^Total in [0-9]+ ms$" + } + } + }, + { + "label": "Serve with Drafts", + "type": "shell", + "command": "hugo serve --disableFastRender -D --port=8080", + "isBackground": true, + "problemMatcher": { + "pattern": { + "regexp": "(ERROR|Error:) .*\"([^\"]+):(\\d+):(\\d+)\": (.*)$", + "file": 2, + "line": 3, + "column": 4, + "message": 5 + }, + "background": { + "activeOnStart": true, + "beginsPattern": "^Change detected, rebuilding site$", + "endsPattern": "^Total in [0-9]+ ms$" + } + } + }, + ] +} diff --git a/go-cloud/internal/website/README.md b/go-cloud/internal/website/README.md new file mode 100644 index 000000000..f16ed38e7 --- /dev/null +++ b/go-cloud/internal/website/README.md @@ -0,0 +1,38 @@ +# gocloud.dev source + +Source for the [gocloud.dev website][]. Powered by [Hugo][]. + +[gocloud.dev website]: https://gocloud.dev/ +[Hugo]: https://gohugo.io/ + +## Local Development + +Use local hugo server for preview. `cd` into this directory and run: + +``` +$ hugo server -D +``` + +This will run the Hugo server that auto-updates its output based on the source +contents. It will print out the `localhost:` URL to point the browser to. + +This was tested with Hugo 0.53 but should work with subsequent versions as well. + +## Editing + +Use `hugo new foo/page.md` to create `content/foo/page.md`. This will +automatically add the appropriate [Front Matter][] to the site. After modifying +an existing page, add the `lastmod` attribute with the current ISO date, which +you can obtain with `date -I`. For example: + +```yaml +--- +title: Foo +date: "2019-03-17T09:00:00-07:00" +lastmod: "2019-03-18T13:30:12-07:00" +--- + +... +``` + +[Front Matter]: https://gohugo.io/content-management/front-matter/ diff --git a/go-cloud/internal/website/archetypes/default.md b/go-cloud/internal/website/archetypes/default.md new file mode 100644 index 000000000..8e295c78a --- /dev/null +++ b/go-cloud/internal/website/archetypes/default.md @@ -0,0 +1,9 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +draft: true +showInSidenav: false # only for sections (any level) +pagesInSidenav: false # only for top-level sections +weight: 0 +--- + diff --git a/go-cloud/internal/website/archetypes/howto.md b/go-cloud/internal/website/archetypes/howto.md new file mode 100644 index 000000000..fc048e48d --- /dev/null +++ b/go-cloud/internal/website/archetypes/howto.md @@ -0,0 +1,8 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +draft: true +showInSidenav: false # only for sections (any level) +weight: 0 +--- + diff --git a/go-cloud/internal/website/config.toml b/go-cloud/internal/website/config.toml new file mode 100644 index 000000000..9a098eca4 --- /dev/null +++ b/go-cloud/internal/website/config.toml @@ -0,0 +1,24 @@ +baseURL = "https://gocloud.dev/" +languageCode = "en-us" +title = "Go CDK" +copyright = "Copyright © 2018–2019 The Go Cloud Development Kit Authors" +pygmentsUseClasses = true +pygmentsCodefences = true + +[outputs] +home = ["HTML", "RSS"] +section = ["HTML"] +taxonomy = ["HTML"] +taxonomyTerm = ["HTML", "RSS"] + +[[menu.footer]] +identifier = "github" +name = "GitHub" +url = "https://github.com/google/go-cloud/" +weight = 1 + +[[menu.footer]] +identifier = "private-contact" +name = "Contact Team" +url = "https://github.com/google/go-cloud/issues" +weight = 3 diff --git a/go-cloud/internal/website/content/_index.md b/go-cloud/internal/website/content/_index.md new file mode 100644 index 000000000..52818f7fc --- /dev/null +++ b/go-cloud/internal/website/content/_index.md @@ -0,0 +1,64 @@ +--- +title: "Go CDK" +pkgmeta: true +--- + +# The Go Cloud Development Kit + +The Go Cloud Development Kit (Go CDK) is an open source project building +libraries and tools to improve the experience of developing for the cloud with +Go. + +Go CDK provides commonly used, vendor-neutral generic APIs that you can deploy +across cloud providers. The idea is to support hybrid cloud deployments while +combining on-prem (local) and cloud tools. + +This project also lays the foundation for other open source projects to write +cloud libraries that work across providers. It does this by providing stable, +idiomatic interfaces for use cases like storage, events and databases. + +For more background about the project, check out the +[announcement blog post](https://blog.golang.org/go-cloud) and +[our talk from Cloud Next 2018](https://www.youtube.com/watch?v=_2ZwhvIkgek). + +If you're interested in contributing to the Go CDK or are interested in checking +out the code, head to [our GitHub project +page](https://github.com/google/go-cloud). + +## Installing and getting started + +To start using the Go CDK, install it using `go get`: + +```shell +go get gocloud.dev +``` + +Then follow the [Go CDK tutorial][]. Links to additional documentation and +samples are available below and in the site navigation bar. + +[Go CDK tutorial]: {{< ref "/tutorials/cli-uploader.md" >}} + +## Portable Cloud APIs in Go + +At this time, the Go CDK focuses on a set of portable APIs for cloud +programming. We strive to implement these APIs for the leading Cloud providers: +AWS, GCP and Azure, as well as provide a local (on-prem) implementation. + +Using the Go CDK you can write your application code once using these idiomatic +APIs, test locally using the local versions, and then deploy to a cloud provider +with only minimal setup-time changes. + +## Project status + +We're looking for early adopters to help us validate the APIs before releasing +a beta version. Please try it and provide feedback by filing a +[GitHub issue](https://github.com/google/go-cloud/issues). + +## Legal disclaimer + +The Go CDK is open-source and released under an [Apache 2.0 +License](https://github.com/google/go-cloud/blob/master/LICENSE). Copyright © +2018–2019 The Go Cloud Development Kit Authors. + +If you are looking for the website of GoCloud Systems, which is unrelated to the +Go CDK, visit https://gocloud.systems. diff --git a/go-cloud/internal/website/content/aws/_index.md b/go-cloud/internal/website/content/aws/_index.md new file mode 100644 index 000000000..91916179a --- /dev/null +++ b/go-cloud/internal/website/content/aws/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/aws +type: pkg +--- diff --git a/go-cloud/internal/website/content/aws/awscloud/_index.md b/go-cloud/internal/website/content/aws/awscloud/_index.md new file mode 100644 index 000000000..dd5f3f542 --- /dev/null +++ b/go-cloud/internal/website/content/aws/awscloud/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/aws/awscloud +type: pkg +--- diff --git a/go-cloud/internal/website/content/aws/rds/_index.md b/go-cloud/internal/website/content/aws/rds/_index.md new file mode 100644 index 000000000..1e4298a38 --- /dev/null +++ b/go-cloud/internal/website/content/aws/rds/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/aws/rds +type: pkg +--- diff --git a/go-cloud/internal/website/content/azure/azurecloud/_index.md b/go-cloud/internal/website/content/azure/azurecloud/_index.md new file mode 100644 index 000000000..ca9adc2b6 --- /dev/null +++ b/go-cloud/internal/website/content/azure/azurecloud/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/azure/azurecloud +type: pkg +--- diff --git a/go-cloud/internal/website/content/azure/azuredb/_index.md b/go-cloud/internal/website/content/azure/azuredb/_index.md new file mode 100644 index 000000000..10dd65bf5 --- /dev/null +++ b/go-cloud/internal/website/content/azure/azuredb/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/azure/azuredb +type: pkg +--- diff --git a/go-cloud/internal/website/content/blob/_index.md b/go-cloud/internal/website/content/blob/_index.md new file mode 100644 index 000000000..0fa4bcfc6 --- /dev/null +++ b/go-cloud/internal/website/content/blob/_index.md @@ -0,0 +1,5 @@ +--- +title: gocloud.dev/blob +type: pkg +--- + diff --git a/go-cloud/internal/website/content/blob/azureblob/_index.md b/go-cloud/internal/website/content/blob/azureblob/_index.md new file mode 100644 index 000000000..587ca4e26 --- /dev/null +++ b/go-cloud/internal/website/content/blob/azureblob/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/blob/azureblob +type: pkg +--- diff --git a/go-cloud/internal/website/content/blob/driver/_index.md b/go-cloud/internal/website/content/blob/driver/_index.md new file mode 100644 index 000000000..07459208f --- /dev/null +++ b/go-cloud/internal/website/content/blob/driver/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/blob/driver +type: pkg +--- diff --git a/go-cloud/internal/website/content/blob/drivertest/_index.md b/go-cloud/internal/website/content/blob/drivertest/_index.md new file mode 100644 index 000000000..d2a4dcb3b --- /dev/null +++ b/go-cloud/internal/website/content/blob/drivertest/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/blob/drivertest +type: pkg +--- diff --git a/go-cloud/internal/website/content/blob/fileblob/_index.md b/go-cloud/internal/website/content/blob/fileblob/_index.md new file mode 100644 index 000000000..906ed4031 --- /dev/null +++ b/go-cloud/internal/website/content/blob/fileblob/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/blob/fileblob +type: pkg +--- diff --git a/go-cloud/internal/website/content/blob/gcsblob/_index.md b/go-cloud/internal/website/content/blob/gcsblob/_index.md new file mode 100644 index 000000000..6e00cfaa6 --- /dev/null +++ b/go-cloud/internal/website/content/blob/gcsblob/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/blob/gcsblob +type: pkg +--- diff --git a/go-cloud/internal/website/content/blob/memblob/_index.md b/go-cloud/internal/website/content/blob/memblob/_index.md new file mode 100644 index 000000000..7528be6d9 --- /dev/null +++ b/go-cloud/internal/website/content/blob/memblob/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/blob/memblob +type: pkg +--- diff --git a/go-cloud/internal/website/content/blob/s3blob/_index.md b/go-cloud/internal/website/content/blob/s3blob/_index.md new file mode 100644 index 000000000..c6d03542a --- /dev/null +++ b/go-cloud/internal/website/content/blob/s3blob/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/blob/s3blob +type: pkg +--- diff --git a/go-cloud/internal/website/content/concepts/_index.md b/go-cloud/internal/website/content/concepts/_index.md new file mode 100644 index 000000000..9cff372ae --- /dev/null +++ b/go-cloud/internal/website/content/concepts/_index.md @@ -0,0 +1,9 @@ +--- +title: "Concepts" +date: 2019-05-06T09:52:00-07:00 +showInSidenav: true +pagesInSidenav: true +weight: 4 +--- + +The documents in this section describe higher level concepts in the Go CDK. diff --git a/go-cloud/internal/website/content/concepts/as.md b/go-cloud/internal/website/content/concepts/as.md new file mode 100644 index 000000000..29128b47d --- /dev/null +++ b/go-cloud/internal/website/content/concepts/as.md @@ -0,0 +1,40 @@ +--- +title: Using provider-specific APIs +date: 2019-05-10T11:17:09-07:00 +weight: 3 +--- + +It is not feasible or desirable for APIs like `blob.Bucket` to encompass the +full functionality of every provider. Rather, we intend to provide a subset +of the most commonly used functionality. There will be cases where a +developer wants to access provider-specific functionality, such as unexposed +APIs or data fields, errors, or options. This can be accomplished using `As` +functions. + + + +## `As` {#as} + +`As` functions in the APIs provide the user a way to escape the Go CDK +abstraction to access provider-specific types. They might be used as an +interim solution until a feature request to the Go CDK is implemented. Or, +the Go CDK may choose not to support specific features, and the use of `As` +will be permanent. + +Using `As` implies that the resulting code is no longer portable; the +provider-specific code will need to be ported in order to switch providers. +Therefore, it should be avoided if possible. + +Each API includes examples demonstrating how to use its various `As` +functions, and each provider implementation documents what types it supports +for each. + +Usage: + +1. Declare a variable of the provider-specific type you want to access. +2. Pass a pointer to it to `As`. +3. If the type is supported, `As` will return `true` and copy the + provider-specific type into your variable. Otherwise, it will return `false`. + +Provider-specific types that are intended to be mutable will be exposed +as a pointer to the underlying type. diff --git a/go-cloud/internal/website/content/concepts/structure/index.md b/go-cloud/internal/website/content/concepts/structure/index.md new file mode 100644 index 000000000..efbfb1e4e --- /dev/null +++ b/go-cloud/internal/website/content/concepts/structure/index.md @@ -0,0 +1,95 @@ +--- +title: "Structuring Portable Code" +date: 2019-06-03T07:34:22-07:00 +weight: 1 +--- + +The Go CDK's APIs are intentionally structured to make it easier to separate +your application's core logic from the details of the services it is using. + + + +## Motivation + +Consider the [uploader tutorial][]. Without the Go CDK, we would have had to +write a code path for Amazon's Simple Storage Service (S3) and another code +path for Google Cloud Storage (GCS). That would work, but it would be +tedious. We would have to learn the semantics of uploading files to both blob +storage services. Even worse, we would have two code paths that effectively +do the same thing, but would have to be maintained separately. It would be +much nicer if we could write the upload logic once and reuse it across +providers. That's exactly the kind of [separation of concerns][] that the Go +CDK makes possible. + +(More details available in the [Go CDK design doc][Developers and Operators].) + +[Developers and Operators]: https://github.com/google/go-cloud/blob/master/internal/docs/design.md#developers-and-operators +[separation of concerns]: https://en.wikipedia.org/wiki/Separation_of_concerns +[uploader tutorial]: {{< ref "/tutorials/cli-uploader.md" >}} + +## Portable Types and Drivers + +The portable APIs that the Go CDK exports (like [`blob.Bucket`][] or +[`runtimevar.Variable`][]) are concrete types, not interfaces. To understand +why, imagine if we used a plain interface: + +{{< figure class="FullWidthFigure" src="portable-type-no-driver.png" link="portable-type-no-driver.png" alt="Diagram showing user code depending on blob.Bucket, which is implemented by awsblob.Bucket." >}} + +Consider the [`Bucket.NewWriter` method][], which infers the content type of the +blob based on the first bytes written to it. If `blob.Bucket` was an interface, +each implementation of `blob.Bucket` would have to replicate this behavior +precisely. This does not scale: conformance tests would be needed to ensure that +each interface method actually behaves in the way that the docs describe. This +makes the interfaces hard to implement, which runs counter to the goals of the +project. + +Instead, we follow the example of [`database/sql`][] and separate out the +implementation-agnostic logic from the interface. The implementation-agnostic +logic-containing concrete type is the **portable type**. We call the interface +the **driver**. Visually, it looks like this: + +{{< figure class="FullWidthFigure" src="portable-type.png" link="portable-type.png" alt="Diagram showing user code depending on blob.Bucket, which holds a driver.Bucket implemented by awsblob.Bucket." >}} + +This has a number of benefits: + +- The portable type can perform higher level logic without making the + interface complex to implement. In the blob example, the portable type's + `NewWriter` method can do the content type detection and then pass the final + result to the driver type. +- Methods can be added to the portable type without breaking compatibility. + Contrast with adding methods to an interface, which is a breaking change. +- When new operations on the driver are added as new optional interfaces, the + portable type can hide the need for type-assertions from the user. + +(More details available in the [Go CDK design doc][Portable Types and Drivers].) + +[Portable Types and Drivers]: https://github.com/google/go-cloud/blob/master/internal/docs/design.md#portable-types-and-drivers +[`blob.Bucket`]: https://godoc.org/github.com/google/go-cloud/blob#Bucket +[`runtimevar.Variable`]: +https://godoc.org/github.com/google/go-cloud/runtimevar#Variable +[`Bucket.NewWriter` method]: +https://godoc.org/github.com/google/go-cloud/blob#Bucket.NewWriter +[`database/sql`]: https://godoc.org/database/sql + +## Best Practices + +- **Create portable types as close to program startup as possible.** Since + creation of a portable type requires using driver-specific setup, this + separates your driver-specific details from the rest of your application. +- **Pass portable types around as arguments or struct fields instead of as + package variables.** This allows you to easily swap out the portable type + for a local implementation in unit tests. It also enables you to use + dependency injection tools like [Wire][] to set up your application. +- **Avoid using [`As`][] functions when possible.** Using driver-specific + options makes it harder to test your code with confidence or migrate to + another driver later. If your application needs to use driver-specific + options, try to make it so that other drivers fall back gracefully. For + example, you may need to use a particular ACL setting for a write to a Google + Cloud Storage bucket. When testing for the driver-specific write options, + don't return an error if the `As` function doesn't have the right type. That + way, when running against an in-memory bucket for tests, the write will still + occur and can be observed. Leave provider-specific checks to integration + tests. + +[`As`]: {{< ref "/concepts/as.md#as" >}} +[Wire]: https://github.com/google/wire diff --git a/go-cloud/internal/website/content/concepts/structure/portable-type-no-driver.png b/go-cloud/internal/website/content/concepts/structure/portable-type-no-driver.png new file mode 100644 index 000000000..61a6f23e3 Binary files /dev/null and b/go-cloud/internal/website/content/concepts/structure/portable-type-no-driver.png differ diff --git a/go-cloud/internal/website/content/concepts/structure/portable-type.png b/go-cloud/internal/website/content/concepts/structure/portable-type.png new file mode 100644 index 000000000..a802caee8 Binary files /dev/null and b/go-cloud/internal/website/content/concepts/structure/portable-type.png differ diff --git a/go-cloud/internal/website/content/concepts/urls.md b/go-cloud/internal/website/content/concepts/urls.md new file mode 100644 index 000000000..ead907870 --- /dev/null +++ b/go-cloud/internal/website/content/concepts/urls.md @@ -0,0 +1,61 @@ +--- +title: "URLs" +date: 2019-05-06T09:55:09-07:00 +weight: 2 +--- + +In addition to creating portable types via provider-specific constructors +(e.g., creating a `*blob.Bucket` using [`s3blob.OpenBucket`][]), many portable types +can also be created using a URL. The scheme of the URL specifies the provider, +and each provider implementation has code to convert the URL into the data +needed to call its constructor. For example, calling +`blob.OpenBucket("s3blob://my-bucket")` will return a `*blob.Bucket` created +using [`s3blob.OpenBucket`][]. + +[`s3blob.OpenBucket`]: https://godoc.org/gocloud.dev/blob/s3blob#OpenBucket + + + +Each portable API package will document the types that it supports opening +by URL. For example, the `blob` package supports `Bucket`s, while the `pubsub` +package supports `Topic`s and `Subscription`s. Each provider implementation will +document what scheme(s) it registers for, and what format of URL it expects. + +Each portable type URL opener will accept URL schemes with an `+` prefix +(e.g. `blob+file:///dir` instead of `file:///dir`, as well as schemes with an +`++` prefix (e.g. `blob+bucket+file:///dir`). + +Each portable API package should include an example using a URL, and +many providers will include provider-specific examples as well. + +## Muxes + +Each portable type that is openable via URL will have a top-level function +you can call, like [`blob.OpenBucket`][]. This top-level function uses a default +instance of a `URLMux` multiplexer to map schemes to a provider-specific +opener for the type. For example, `blob` has a [`BucketURLOpener`][] interface +that providers implement and then register using [`RegisterBucket`][] on the +result of [`DefaultURLMux`][]. + +Many applications will work just fine using the default mux through the +top-level `Open` functions. However, if you want more control, you can create +your own `URLMux` and register the provider `URLOpener`s you need. Most +providers will export URLOpeners that give you more fine grained control over +the arguments needed by the constructor. In particular, portable types opened +via URL will often use default credentials from the environment. For example, +the AWS URL openers use the credentials saved by "aws login" (we don't want +to include credentials in the URL itself, since they are likely to be +sensitive). + +1. Instantiate the provider's `URLOpener` with the specific fields you need. + For example, `s3blob.URLOpener{ConfigProvider: myAWSProvider}` using a + `ConfigProvider` that holds explicit AWS credentials. +2. Create your own instance of the `URLMux`. For example: `mymux := new(blob.URLMux)` +3. Register your custom URLOpener on your mux. For example: + `mymux.RegisterBucket(s3blob.Scheme, myS3URLOpener)` +4. Now use your mux to open URLs: `mymux.OpenBucket("s3://my-bucket")` + +[`blob.OpenBucket`]: https://godoc.org/gocloud.dev/blob#OpenBucket +[`BucketURLOpener`]: https://godoc.org/gocloud.dev/blob#BucketURLOpener +[`DefaultURLMux`]: https://godoc.org/gocloud.dev/blob#DefaultURLMux +[`RegisterBucket`]: https://godoc.org/gocloud.dev/blob#URLMux.RegisterBucket diff --git a/go-cloud/internal/website/content/docstore/_index.md b/go-cloud/internal/website/content/docstore/_index.md new file mode 100644 index 000000000..bd8f19c94 --- /dev/null +++ b/go-cloud/internal/website/content/docstore/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/docstore +type: pkg +--- diff --git a/go-cloud/internal/website/content/docstore/awsdynamodb/_index.md b/go-cloud/internal/website/content/docstore/awsdynamodb/_index.md new file mode 100644 index 000000000..9ebdcf37b --- /dev/null +++ b/go-cloud/internal/website/content/docstore/awsdynamodb/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/docstore/awsdynamodb +type: pkg +--- diff --git a/go-cloud/internal/website/content/docstore/awsdynamodb/v2/_index.md b/go-cloud/internal/website/content/docstore/awsdynamodb/v2/_index.md new file mode 100644 index 000000000..fcaf58f19 --- /dev/null +++ b/go-cloud/internal/website/content/docstore/awsdynamodb/v2/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/docstore/awsdynamodb/v2 +type: pkg +--- diff --git a/go-cloud/internal/website/content/docstore/driver/_index.md b/go-cloud/internal/website/content/docstore/driver/_index.md new file mode 100644 index 000000000..9f7166c43 --- /dev/null +++ b/go-cloud/internal/website/content/docstore/driver/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/docstore/driver +type: pkg +--- diff --git a/go-cloud/internal/website/content/docstore/drivertest/_index.md b/go-cloud/internal/website/content/docstore/drivertest/_index.md new file mode 100644 index 000000000..1375bd3d7 --- /dev/null +++ b/go-cloud/internal/website/content/docstore/drivertest/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/docstore/drivertest +type: pkg +--- diff --git a/go-cloud/internal/website/content/docstore/dynamodocstore/_index.md b/go-cloud/internal/website/content/docstore/dynamodocstore/_index.md new file mode 100644 index 000000000..11e1607a2 --- /dev/null +++ b/go-cloud/internal/website/content/docstore/dynamodocstore/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/docstore/dynamodocstore +type: pkg +--- diff --git a/go-cloud/internal/website/content/docstore/firedocstore/_index.md b/go-cloud/internal/website/content/docstore/firedocstore/_index.md new file mode 100644 index 000000000..a35c61b91 --- /dev/null +++ b/go-cloud/internal/website/content/docstore/firedocstore/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/docstore/firedocstore +type: pkg +--- diff --git a/go-cloud/internal/website/content/docstore/gcpfirestore/_index.md b/go-cloud/internal/website/content/docstore/gcpfirestore/_index.md new file mode 100644 index 000000000..0b4098572 --- /dev/null +++ b/go-cloud/internal/website/content/docstore/gcpfirestore/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/docstore/gcpfirestore +type: pkg +--- diff --git a/go-cloud/internal/website/content/docstore/internal/fields/_index.md b/go-cloud/internal/website/content/docstore/internal/fields/_index.md new file mode 100644 index 000000000..fdc153320 --- /dev/null +++ b/go-cloud/internal/website/content/docstore/internal/fields/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/docstore/internal/fields +type: pkg +--- diff --git a/go-cloud/internal/website/content/docstore/memdocstore/_index.md b/go-cloud/internal/website/content/docstore/memdocstore/_index.md new file mode 100644 index 000000000..34def261e --- /dev/null +++ b/go-cloud/internal/website/content/docstore/memdocstore/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/docstore/memdocstore +type: pkg +--- diff --git a/go-cloud/internal/website/content/docstore/mongodocstore/_index.md b/go-cloud/internal/website/content/docstore/mongodocstore/_index.md new file mode 100644 index 000000000..4601123bd --- /dev/null +++ b/go-cloud/internal/website/content/docstore/mongodocstore/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/docstore/mongodocstore +type: pkg +--- diff --git a/go-cloud/internal/website/content/gcerrors/_index.md b/go-cloud/internal/website/content/gcerrors/_index.md new file mode 100644 index 000000000..39029091e --- /dev/null +++ b/go-cloud/internal/website/content/gcerrors/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/gcerrors +type: pkg +--- diff --git a/go-cloud/internal/website/content/gcp/_index.md b/go-cloud/internal/website/content/gcp/_index.md new file mode 100644 index 000000000..88470a291 --- /dev/null +++ b/go-cloud/internal/website/content/gcp/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/gcp +type: pkg +--- diff --git a/go-cloud/internal/website/content/gcp/cloudsql/_index.md b/go-cloud/internal/website/content/gcp/cloudsql/_index.md new file mode 100644 index 000000000..1b9da13ea --- /dev/null +++ b/go-cloud/internal/website/content/gcp/cloudsql/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/gcp/cloudsql +type: pkg +--- diff --git a/go-cloud/internal/website/content/gcp/gcpcloud/_index.md b/go-cloud/internal/website/content/gcp/gcpcloud/_index.md new file mode 100644 index 000000000..e9ef0a942 --- /dev/null +++ b/go-cloud/internal/website/content/gcp/gcpcloud/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/gcp/gcpcloud +type: pkg +--- diff --git a/go-cloud/internal/website/content/health/_index.md b/go-cloud/internal/website/content/health/_index.md new file mode 100644 index 000000000..a4e942117 --- /dev/null +++ b/go-cloud/internal/website/content/health/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/health +type: pkg +--- diff --git a/go-cloud/internal/website/content/health/sqlhealth/_index.md b/go-cloud/internal/website/content/health/sqlhealth/_index.md new file mode 100644 index 000000000..72a8f6782 --- /dev/null +++ b/go-cloud/internal/website/content/health/sqlhealth/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/health/sqlhealth +type: pkg +--- diff --git a/go-cloud/internal/website/content/howto/_index.md b/go-cloud/internal/website/content/howto/_index.md new file mode 100644 index 000000000..43998860f --- /dev/null +++ b/go-cloud/internal/website/content/howto/_index.md @@ -0,0 +1,10 @@ +--- +title: "How-To Guides" +date: 2019-03-20T14:50:56-07:00 +showInSidenav: true +pagesInSidenav: true +weight: 2 +--- + +The guides in this section are aimed to help you solve common tasks with +the Go CDK. They are grouped by API. diff --git a/go-cloud/internal/website/content/howto/blob/_index.md b/go-cloud/internal/website/content/howto/blob/_index.md new file mode 100644 index 000000000..c8f94b666 --- /dev/null +++ b/go-cloud/internal/website/content/howto/blob/_index.md @@ -0,0 +1,330 @@ +--- +title: "Blob" +date: 2019-07-09T16:46:29-07:00 +lastmod: 2019-07-29T12:00:00-07:00 +showInSidenav: true +toc: true +--- + +Blobs are a common abstraction for storing unstructured data on Cloud storage +services and accessing them via HTTP. This guide shows how to work with +blobs in the Go CDK. + + + +The [`blob` package][] supports operations like reading and writing blobs (using standard +[`io` package][] interfaces), deleting blobs, and listing blobs in a bucket. + +Subpackages contain driver implementations of blob for various services, +including Cloud and on-prem solutions. You can develop your application +locally using [`fileblob`][], then deploy it to multiple Cloud providers with +minimal initialization reconfiguration. + +[`blob` package]: https://godoc.org/gocloud.dev/blob +[`io` package]: https://golang.org/pkg/io/ +[`fileblob`]: https://godoc.org/gocloud.dev/blob/fileblob + +## Opening a Bucket {#opening} + +The first step in interacting with unstructured storage is +to instantiate a portable [`*blob.Bucket`][] for your storage service. + +The easiest way to do so is to use [`blob.OpenBucket`][] and a service-specific URL +pointing to the bucket, making sure you ["blank import"][] the driver package to +link it in. + +```go +import ( + "gocloud.dev/blob" + _ "gocloud.dev/blob/" +) +... +bucket, err := blob.OpenBucket(context.Background(), "") +if err != nil { + return fmt.Errorf("could not open bucket: %v", err) +} +defer bucket.Close() +// bucket is a *blob.Bucket; see usage below +... +``` + +See [Concepts: URLs][] for general background and the [guide below][] for URL usage +for each supported service. + +Alternatively, if you need +fine-grained control over the connection settings, you can call the constructor +function in the driver package directly. + +```go +import "gocloud.dev/blob/" +... +bucket, err := .OpenBucket(...) +... +``` + +You may find the [`wire` package][] useful for managing your initialization code +when switching between different backing services. + +See the [guide below][] for constructor usage for each supported service. + +[`wire` package]: http://github.com/google/wire +[`*blob.Bucket`]: https://godoc.org/gocloud.dev/blob#Bucket +[`blob.OpenBucket`]: https://godoc.org/gocloud.dev/blob#OpenBucket +["blank import"]: https://golang.org/doc/effective_go.html#blank_import +[Concepts: URLs]: {{< ref "/concepts/urls.md" >}} +[guide below]: {{< ref "#services" >}} + +### Prefixed Buckets {#prefix} + +You can wrap a `*blob.Bucket` to always operate on a subfolder of the bucket +using `blob.PrefixedBucket`: + +{{< goexample "gocloud.dev/blob.ExamplePrefixedBucket" >}} + +Alternatively, you can configure the prefix directly in the `blob.OpenBucket` +URL: + +{{< goexample "gocloud.dev/blob.Example_openFromURLWithPrefix" >}} + +### Single Key Buckets {#singlekey} + +You can wrap a `*blob.Bucket` to always operate on a single key +using `blob.SingleKeyBucket`: + +{{< goexample "gocloud.dev/blob.ExampleSingleKeyBucket" >}} + +Alternatively, you can configure the single key directly in the `blob.OpenBucket` +URL: + +{{< goexample "gocloud.dev/blob.Example_openFromURLWithSingleKey" >}} + +The resulting bucket will ignore the `key` parameter to its functions, +and always refer to the single key. This can be useful to allow configuration +of a specific "file" via a single URL. + +`List` functions will not work on single key buckets. + +## Using a Bucket {#using} + +Once you have opened a bucket for the storage provider you want, you can +store and access data from it using the standard Go I/O patterns described +below. Other operations like listing and reading metadata are documented in the +[`blob` package documentation][]. + +[`blob` package documentation]: https://godoc.org/gocloud.dev/blob + +### Writing Data to a Bucket {#writing} + +To write data to a bucket, you create a writer, write data to it, and then +close the writer. Closing the writer commits the write to the provider, +flushing any buffers, and releases any resources used while writing, so you +must always check the error of `Close`. + +The writer implements [`io.Writer`][], so you can use any functions that take +an `io.Writer` like `io.Copy` or `fmt.Fprintln`. + +{{< goexample src="gocloud.dev/blob.ExampleBucket_NewWriter" imports="0" >}} + +In some cases, you may want to cancel an in-progress write to avoid the blob +being created or overwritten. A typical reason for wanting to cancel a write +is encountering an error in the stream your program is copying from. To abort +a write, you cancel the `Context` you pass to the writer. Again, you must +always `Close` the writer to release the resources, but in this case you can +ignore the error because the write's failure is expected. + +{{< goexample src="gocloud.dev/blob.ExampleBucket_NewWriter_cancel" imports="0" >}} + +[`io.Writer`]: https://golang.org/pkg/io/#Writer + +### Reading Data from a Bucket {#reading} + +Once you have written data to a bucket, you can read it back by creating a +reader. The reader implements [`io.Reader`][], so you can use any functions +that take an `io.Reader` like `io.Copy` or `io/io.ReadAll`. You must +always close a reader after using it to avoid leaking resources. + +{{< goexample src="gocloud.dev/blob.ExampleBucket_NewReader" imports="0" >}} + +Many storage providers provide efficient random-access to data in buckets. To +start reading from an arbitrary offset in the blob, use `NewRangeReader`. + +{{< goexample src="gocloud.dev/blob.ExampleBucket_NewRangeReader" imports="0" >}} + +[`io.Reader`]: https://golang.org/pkg/io/#Reader + +### Deleting a Bucket {#deleting} + +You can delete blobs using the `Bucket.Delete` method. + +{{< goexample src="gocloud.dev/blob.ExampleBucket_Delete" imports="0" >}} + +## Other Usage Samples + +* [CLI Tutorial]({{< ref "/tutorials/cli-uploader.md" >}}) +* [CLI Sample](https://github.com/google/go-cloud/tree/master/samples/gocdk-blob) +* [Guestbook sample](https://gocloud.dev/tutorials/guestbook/) +* [blob package examples](https://godoc.org/gocloud.dev/blob#pkg-examples) + +## Supported Storage Services {#services} + +### Google Cloud Storage {#gcs} + +[Google Cloud Storage][] (GCS) URLs in the Go CDK closely resemble the URLs +you would see in the [`gsutil`][] CLI. + +[Google Cloud Storage]: https://cloud.google.com/storage/ +[`gsutil`]: https://cloud.google.com/storage/docs/gsutil + +`blob.OpenBucket` will use Application Default Credentials; if you have +authenticated via [`gcloud auth application-default login`][], it will use those credentials. See +[Application Default Credentials][GCP creds] to learn about authentication +alternatives, including using environment variables. + +[GCP creds]: https://cloud.google.com/docs/authentication/production +[`gcloud auth application-default login`]: https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login + +{{< goexample "gocloud.dev/blob/gcsblob.Example_openBucketFromURL" >}} + +Full details about acceptable URLs can be found under the API reference for +[`gcsblob.URLOpener`][]. + +[`gcsblob.URLOpener`]: https://godoc.org/gocloud.dev/blob/gcsblob#URLOpener + +#### GCS Constructor {#gcs-ctor} + +The [`gcsblob.OpenBucket`][] constructor opens a GCS bucket. You must first +create a `*net/http.Client` that sends requests authorized by [Google Cloud +Platform credentials][GCP creds]. (You can reuse the same client for any +other API that takes in a `*gcp.HTTPClient`.) You can find functions in the +[`gocloud.dev/gcp`][] package to set this up for you. + +{{< goexample "gocloud.dev/blob/gcsblob.ExampleOpenBucket" >}} + +[`gcsblob.OpenBucket`]: https://godoc.org/gocloud.dev/blob/gcsblob#OpenBucket +[`gocloud.dev/gcp`]: https://godoc.org/gocloud.dev/gcp + +### S3 {#s3} + +S3 URLs in the Go CDK closely resemble the URLs you would see in the [AWS CLI][]. +You should specify the `region` query parameter to ensure your application +connects to the correct region. + +It will create an AWS Config based on the AWS SDK V2; see [AWS V2 Config][] to learn more. + +Full details about acceptable URLs can be found under the API reference for +[`s3blob.URLOpener`][]. + +{{< goexample "gocloud.dev/blob/s3blob.Example_openBucketFromURL" >}} + +[AWS CLI]: https://aws.amazon.com/cli/ +[AWS V2 Config]: https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ +[`s3blob.URLOpener`]: https://godoc.org/gocloud.dev/blob/s3blob#URLOpener + +#### S3 Constructor {#s3-ctor} + +The [`s3blob.OpenBucket`][] constructor opens an [S3][] bucket. You must first +create an AWS Config with the same region as your bucket: + +{{< goexample "gocloud.dev/blob/s3blob.ExampleOpenBucket" >}} + +[`s3blob.OpenBucket`]: https://godoc.org/gocloud.dev/blob/s3blob#OpenBucket +[S3]: https://aws.amazon.com/s3/ + +#### S3-Compatible Servers {#s3-compatible} + +The Go CDK can also interact with [S3-compatible storage servers][] that +recognize the same REST HTTP endpoints as S3, like [Minio][], [Ceph][], or +[SeaweedFS][]. You can change the endpoint by changing the [`Endpoint` field][] +on the `*aws.Config` you pass to `s3blob.OpenBucket`. If you are using +`blob.OpenBucket`, you can switch endpoints by using the S3 URL using query +parameters like so: + +```go +bucket, err := blob.OpenBucket("s3://mybucket?" + + "endpoint=my.minio.local:8080&" + + "disableSSL=true&" + + "s3ForcePathStyle=true") +``` + +See [`aws.V2ConfigFromURLParams`][] for more details on supported URL options for S3. + +[`aws.V2ConfigFromURLParams`]: https://godoc.org/gocloud.dev/aws#V2ConfigFromURLParams +[`Endpoint` field]: https://godoc.org/github.com/aws/aws-sdk-go/aws#Config.Endpoint +[Ceph]: https://ceph.com/ +[Minio]: https://www.minio.io/ +[SeaweedFS]: https://github.com/chrislusf/seaweedfs +[S3-compatible storage servers]: https://en.wikipedia.org/wiki/Amazon_S3#S3_API_and_competing_services + +### Azure Blob Storage {#azure} + +Azure Blob Storage URLs in the Go CDK allow you to identify [Azure Blob Storage][] containers +when opening a bucket with `blob.OpenBucket`. Go CDK uses the environment +variables `AZURE_STORAGE_ACCOUNT`, `AZURE_STORAGE_KEY`, and +`AZURE_STORAGE_SAS_TOKEN`, among others, to configure the credentials. + +{{< goexample "gocloud.dev/blob/azureblob.Example_openBucketFromURL" >}} + +Full details about acceptable URLs can be found under the API reference for +[`azureblob.URLOpener`][]. + +[Azure Blob Storage]: https://azure.microsoft.com/en-us/services/storage/blobs/ +[`azureblob.URLOpener`]: https://godoc.org/gocloud.dev/blob/azureblob#URLOpener + +#### Azure Blob Constructor {#azure-ctor} + +The [`azureblob.OpenBucket`][] constructor opens an Azure Blob Storage container. +`azureblob` operates on [Azure Storage Block Blobs][]. You must first create +an Azure Service Client before you can open a container. + +{{< goexample "gocloud.dev/blob/azureblob.ExampleOpenBucket" >}} + +[Azure Storage Block Blobs]: https://docs.microsoft.com/en-us/rest/api/storageservices/understanding-block-blobs--append-blobs--and-page-blobs#about-block-blobs +[`azureblob.OpenBucket`]: https://godoc.org/gocloud.dev/blob/azureblob#OpenBucket + +### Local Storage {#local} + +The Go CDK provides blob drivers for storing data in memory and on the local +filesystem. These are primarily intended for testing and local development, +but may be useful in production scenarios where an NFS mount is used. + +Local storage URLs take the form of either `mem://` or `file:///` URLs. +Memory URLs are always `mem://` with no other information and always create a +new bucket. File URLs convert slashes to the operating system's native file +separator, so on Windows, `C:\foo\bar` would be written as +`file:///C:/foo/bar`. + +```go +import ( + "gocloud.dev/blob" + _ "gocloud.dev/blob/fileblob" + _ "gocloud.dev/blob/memblob" +) + +// ... + +bucket1, err := blob.OpenBucket(ctx, "mem://") +if err != nil { + return err +} +defer bucket1.Close() + +bucket2, err := blob.OpenBucket(ctx, "file:///path/to/dir") +if err != nil { + return err +} +defer bucket2.Close() +``` + +#### Local Storage Constructors {#local-ctor} + +You can create an in-memory bucket with [`memblob.OpenBucket`][]: + +{{< goexample "gocloud.dev/blob/memblob.ExampleOpenBucket" >}} + +You can use a local filesystem directory with [`fileblob.OpenBucket`][]: + +{{< goexample "gocloud.dev/blob/fileblob.ExampleOpenBucket" >}} + +[`fileblob.OpenBucket`]: https://godoc.org/gocloud.dev/blob/fileblob#OpenBucket +[`memblob.OpenBucket`]: https://godoc.org/gocloud.dev/blob/memblob#OpenBucket + diff --git a/go-cloud/internal/website/content/howto/docstore/_index.md b/go-cloud/internal/website/content/howto/docstore/_index.md new file mode 100644 index 000000000..bf62d8fbe --- /dev/null +++ b/go-cloud/internal/website/content/howto/docstore/_index.md @@ -0,0 +1,438 @@ +--- +title: "Docstore" +date: 2019-06-08T15:11:57-04:00 +lastmod: 2019-07-29T12:00:00-07:00 +showInSidenav: true +toc: true +--- + +The [`docstore` package][] provides an abstraction layer over common +[document stores](https://en.wikipedia.org/wiki/Document-oriented_database) like +Google Cloud Firestore, Amazon DynamoDB and MongoDB. This guide shows how to +work with document stores in the Go CDK. + + + +A document store is a service that stores data in semi-structured JSON-like +documents grouped into collections. Like other NoSQL databases, document stores +are schemaless. + +The [`docstore` package][] supports operations to add, retrieve, modify and +delete documents. + +Subpackages contain driver implementations of docstore for various services, +including Cloud and on-prem solutions. You can develop your application +locally using [`memdocstore`][], then deploy it to multiple Cloud providers with +minimal initialization reconfiguration. + +[`docstore` package]: https://godoc.org/gocloud.dev/docstore +[`memdocstore`]: https://godoc.org/gocloud.dev/docstore/memdocstore + +## Opening a Collection {#opening} + +The first step in interacting with a document store is to instantiate +a portable [`*docstore.Collection`][] for your service. + +While every docstore service has the concept of a primary key that uniquely +distinguishes a document in a collection, each one specifies that key in its own +way. To be portable, Docstore requires that the key be part of the document's +contents. When you open a collection using one of the functions described here, +you specify how to find the provider's primary key in the document. + +The easiest way to open a collection is using [`docstore.OpenCollection`][] and +a service-specific URL pointing to it, making sure you ["blank import"][] +the driver package to link it in. + +```go +import ( + "gocloud.dev/docstore" + _ "gocloud.dev/docstore/" +) +... +coll, err := docstore.OpenCollection(context.Background(), "") +if err != nil { + return fmt.Errorf("could not open collection: %v", err) +} +defer coll.Close() +// coll is a *docstore.Collection; see usage below +... +``` + +See [Concepts: URLs][] for general background and the [guide below][] for +URL usage for each supported service. + +Alternatively, if you need +fine-grained control over the connection settings, you can call the constructor +function in the driver package directly (like `mongodocstore.OpenCollection`). + +```go +import "gocloud.dev/docstore/" +... +coll, err := .OpenCollection(...) +... +``` + +You may find the [`wire` package][] useful for managing your initialization code +when switching between different backing services. + +See the [guide below][] for constructor usage for each supported service + +[`*docstore.Collection`]: https://godoc.org/gocloud.dev/docstore#Collection +[`docstore.OpenCollection`]: +https://godoc.org/gocloud.dev/docstore#OpenCollection +["blank import"]: https://golang.org/doc/effective_go.html#blank_import +[Concepts: URLs]: {{< ref "/concepts/urls.md" >}} +[guide below]: {{< ref "#services" >}} +[`wire` package]: http://github.com/google/wire + +## Using a Collection {#using} + +### Representing Documents {#rep-doc} + +We'll use a collection with documents represented by this Go struct: + +```go +type Player struct { + Name string + Score int + DocstoreRevision interface{} +} +``` + +We recommend using structs for documents because they impose some structure on +your data, but Docstore also accepts `map[string]interface{}` values. See +[the `docstore` package documentation](https://godoc.org/gocloud.dev/docstore#hdr-Documents) +for more information. + +The `DocstoreRevision` field holds information about the latest revision of the +document. We discuss it [below]({{< ref "#rev" >}}). + +### Actions {#actions} + +Once you have [opened a collection]( {{< ref "#opening" >}}), you can call +action methods on it to read, modify and write documents. You can execute a +single action, or run multiple actions together in an [_action list_]({{ ref +"act-list" }}). + +Docstore supports six kinds of actions on documents: + +- `Get` retrieves a document. +- `Create` creates a new document. +- `Replace` replaces an existing document. +- `Put` puts a document whether or not it already exists. +- `Update` applies a set of modifications to a document. +- `Delete` deletes a document. + +You can create a single document with the `Collection.Create` method, we will +use `coll` as the variable holding the collection throughout the guide: + +```go +err := coll.Create(ctx, &Player{Name: "Pat", Score: 10}) +if err != nil { + return err +} +``` + +#### Action Lists {#act-list} + +When you use an action list to perform multiple actions at once, drivers can +optimize action lists by using bulk RPCs, running the actions concurrently, +or employing a provider's special features to improve efficiency and reduce +cost. Here we create several documents using an action list. + +{{< goexample "gocloud.dev/docstore.ExampleCollection_Actions_bulkWrite" >}} + +`ActionList` has a fluent API, so you can build and execute a sequence of +actions in one line of code. Here we `Put` a document and immediately `Get` its +new contents. + +{{< goexample "gocloud.dev/docstore.ExampleCollection_Actions_getAfterWrite" >}} + +If the underlying provider is eventually consistent, the result of the `Get` +might not reflect the `Put`. Docstore only guarantees that it will perform the +`Get` after the `Put` completes. + +See the documentation for [`docstore.ActionList`][] for the semantics of action +list execution. + +[`docstore.ActionList`]: https://godoc.org/gocloud.dev/docstore#ActionList + +#### Updates {#act-update} + +Use `Update` to modify individual fields of a document. The `Update` action +takes a set of modifications to document fields, and applies them all +atomically. You can change the value of a field, increment it, or delete it. + +{{< goexample "gocloud.dev/docstore.ExampleCollection_Update" >}} + +### Queries {#queries} + +Docstore's `Get` action lets you retrieve a single document by its primary key. +Queries let you retrieve all documents that match some conditions. You can also +use queries to delete or update all documents that match the conditions. + +#### Getting Documents {#qr-get} + +Like [actions]({{< ref "#actions" >}}), queries are built up in a fluent +style. Just as a `Get` action returns one document, the `Query.Get` method +returns several documents, in the form of an iterator. + +```go +iter := coll.Query().Where("Score", ">", 20).Get(ctx) +defer iter.Stop() // Always call Stop on an iterator. +``` + +Repeatedly calling `Next` on the iterator will return all the matching +documents. Like the `Get` action, `Next` will populate an empty document that +you pass to it: + +```go +doc := &Player{} +err := iter.Next(ctx, doc) +``` + +The iteration is over when `Next` returns `io.EOF`. + +{{< goexample "gocloud.dev/docstore.ExampleQuery_Get" >}} + +You can pass a list of fields to `Get` to reduce the amount of data transmitted. + +Queries support the following methods: + +- `Where` describes a condition on a document. You can ask whether a field is + equal to, greater than, or less than a value. The "not equals" comparison + isn't supported, because it isn't portable across providers. +- `OrderBy` specifies the order of the resulting documents, by field and + direction. For portability, you can specify at most one `OrderBy`, and its + field must also be mentioned in a `Where` clause. +- `Limit` limits the number of documents in the result. + +If a query returns an error, the message may help you fix the problem. Some +features, like full table scans, have to be enabled via constructor options, +because they can be expensive. Other queries may require that you manually +create an index on the collection. + +### Revisions {#rev} + +Docstore maintains a revision for every document. Whenever the document is +changed, the revision is too. By default, Docstore stores the revision in a +field named `DocstoreRevision`, but you can change the field name via an option +to a `Collection` constructor. + +You can use revisions to perform _optimistic locking_, a technique for updating +a document atomically: + +1. `Get` a document. This reads the current revision. +2. Modify the document contents on the client (but do not change the revision). +3. `Replace` the document. If the document was changed since it was retrieved + in step 1, the revision will be different, and Docstore will return an error + instead of overwriting the document. +4. If the `Replace` failed, start again from step 1. + +{{< goexample "gocloud.dev/docstore.Example_optimisticLocking" >}} + +See +[the Revisions section of the package documentation](https://godoc.org/gocloud.dev/docstore#hdr-Revisions) +for more on revisions. + +## Other Usage Samples + +* [CLI Sample](https://github.com/google/go-cloud/tree/master/samples/gocdk-docstore) +* [Order Processor sample](https://gocloud.dev/tutorials/order/) +* [docstore package examples](https://godoc.org/gocloud.dev/docstore#pkg-examples) + +## Supported Docstore Services {#services} + +### Google Cloud Firestore {#firestore} + +The [`gcpfirestore`](https://godoc.org/gocloud.dev/docstore/gcpfirestore) +package supports +[Google Cloud Firestore](https://cloud.google.com/firestore). Firestore +documents are uniquely named by paths that are not part of the document content. +In Docstore, these unique names are represented as part of the document. You +must supply a way to extract a document's name from its contents. This can be +done by specifying a document field that holds the name, or by providing a +function to extract the name from a document. + +Firestore URLs provide the project and collection, as well as the field that +holds the document name. + +`docstore.OpenCollection` will use Application Default Credentials; if you have +authenticated via [`gcloud auth application-default login`][], it will use those credentials. See +[Application Default Credentials][GCP creds] to learn about authentication +alternatives, including using environment variables. + +[GCP creds]: https://cloud.google.com/docs/authentication/production +[`gcloud auth application-default login`]: https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login + +{{< goexample +"gocloud.dev/docstore/gcpfirestore.Example_openCollectionFromURL" >}} + +Full details about acceptable URLs can be found under the API reference for +[`gcpfirestore.URLOpener`][]. + +[`gcpfirestore.URLOpener`]: https://godoc.org/gocloud.dev/docstore/gcpfirestore#URLOpener + +#### Firestore Constructors {#firestore-ctor} + +The [`gcpfirestore.OpenCollection`][] constructor opens a Cloud Firestore +collection as a Docstore collection. You must first connect a Firestore client +using [`gcpfirestore.Dial`][] or the +[`cloud.google.com/go/firestore/apiv1`](https://godoc.org/cloud.google.com/go/firestore/apiv1) +package. In addition to a client, `OpenCollection` requires a Google Cloud +project ID, the path to the Firestore collection, and the name of the field that +holds the document name. + +{{< goexample "gocloud.dev/docstore/gcpfirestore.ExampleOpenCollection" >}} + +Instead of mapping the document name to a field, you can supply a function to +construct the name from the document contents with +[`gcpfirestore.OpenCollectionWithNameFunc`][]. This can be useful for documents +whose name is the combination of two or more fields. + +{{< goexample +"gocloud.dev/docstore/gcpfirestore.ExampleOpenCollectionWithNameFunc" >}} + +[`gcpfirestore.Dial`]: https://godoc.org/gocloud.dev/docstore/gcpfirestore#Dial +[`gcpfirestore.OpenCollection`]: https://godoc.org/gocloud.dev/docstore/gcpfirestore#OpenCollection +[`gcpfirestore.OpenCollectionWithNameFunc`]: https://godoc.org/gocloud.dev/docstore/gcpfirestore#OpenCollectionWithNameFunc + +### Amazon DynamoDB {#dynamodb} + +The [`awsdynamodb`](https://godoc.org/gocloud.dev/docstore/awsdynamodb) package +supports [Amazon DynamoDB](https://aws.amazon.com/dynamodb). A Docstore +collection corresponds to a DynamoDB table. + +DynamoDB URLs provide the table, partition key field and optionally the sort key +field for the collection. + +`docstore.OpenCollection` will create a default AWS Session with the +`SharedConfigEnable` option enabled; if you have authenticated with the AWS CLI, +it will use those credentials. See [AWS Session][] to learn about authentication +alternatives, including using environment variables. + +[AWS Session]: https://docs.aws.amazon.com/sdk-for-go/api/aws/session/ + +{{< goexample +"gocloud.dev/docstore/awsdynamodb.Example_openCollectionFromURL" >}} + +Full details about acceptable URLs can be found under the API reference for +[`awsdynamodb.URLOpener`][]. + +#### DynamoDB Constructor {#dynamodb-ctor} + +The [`awsdynamodb.OpenCollection`][] constructor opens a DynamoDB table as a +Docstore collection. You must first create an [AWS session][] with the same +region as your collection: + +{{< goexample "gocloud.dev/docstore/awsdynamodb.ExampleOpenCollection" >}} + +[AWS session]: https://docs.aws.amazon.com/sdk-for-go/api/aws/session/ +[`awsdynamodb.OpenCollection`]: https://godoc.org/gocloud.dev/docstore/awsdynamodb#OpenCollection +[`awsdynamodb.URLOpener`]: https://godoc.org/gocloud.dev/docstore/awsdynamodb#URLOpener + +### Azure Cosmos DB {#cosmosdb} + +[Azure Cosmos DB][] is compatible with the MongoDB API. You can use the +[`mongodocstore`][] package to connect to Cosmos DB. You must +[create an Azure Cosmos account][] and get the MongoDB [connection string][]. + +When you use MongoDB URLs to connect to Cosmos DB, specify the Mongo server +URL by setting the `MONGO_SERVER_URL` environment variable to the connection +string. See the [MongoDB section][] for more details and examples on how to +use the package. + +[Azure Cosmos DB]: https://docs.microsoft.com/en-us/azure/cosmos-db/ +[create an Azure Cosmos account]: https://docs.microsoft.com/en-us/azure/cosmos-db/create-mongodb-dotnet +[connection string]: https://docs.microsoft.com/en-us/azure/cosmos-db/connect-mongodb-account#QuickstartConnection +[MongoDB section]: {{< ref "#mongo" >}} + +#### Cosmos DB Constructors {#cosmosdb-ctor} + +The [`mongodocstore.OpenCollection`][] constructor can open a Cosmos DB +collection. You must first obtain a standard MongoDB Go client with your +Cosmos connections string. See the [MongoDB constructor section][] for more +details and examples. + +[MongoDB constructor section]: {{< ref "#mongo-ctor" >}} + +### MongoDB {#mongo} + +The [`mongodocstore`][] package supports the popular +[MongoDB](https://mongodb.org) document store. MongoDB documents are uniquely +identified by a field called `_id`. In Docstore, you can choose a different +name for this field, or provide a function to extract the document ID from a +document. + +MongoDB URLs provide the database and collection, and optionally the field that +holds the document ID. Specify the Mongo server URL by setting the +`MONGO_SERVER_URL` environment variable. + +{{< goexample +"gocloud.dev/docstore/mongodocstore.Example_openCollectionFromURL" >}} + +Full details about acceptable URLs can be found under the API reference for +[`mongodocstore.URLOpener`][]. + +[`mongodocstore.URLOpener`]: https://godoc.org/gocloud.dev/docstore/mongodocstore#URLOpener + +#### MongoDB Constructors {#mongo-ctor} + +The [`mongodocstore.OpenCollection`][] constructor opens a MongoDB collection. +You must first obtain a standard MongoDB Go client using +[`mongodocstore.Dial`][] or the package +[`go.mongodb.org/mongo-driver/mongo`](https://godoc.org/go.mongodb.org/mongo-driver/mongo). +Obtain a `*mongo.Collection` from the client with +`client.Database(dbName).Collection(collName)`. Then pass the result to +`mongodocstore.OpenCollection` along with the name of the ID field, or `""` to +use `_id`. + +{{< goexample "gocloud.dev/docstore/mongodocstore.ExampleOpenCollection" >}} + +Instead of mapping the document ID to a field, you can supply a function to +construct the ID from the document contents with +[`mongodocstore.OpenCollectionWithIDFunc`][]. This can be useful for documents +whose name is the combination of two or more fields. + +{{< goexample +"gocloud.dev/docstore/mongodocstore.ExampleOpenCollectionWithIDFunc" >}} + +[`mongodocstore`]: https://godoc.org/gocloud.dev/docstore/mongodocstore +[`mongodocstore.Dial`]: https://godoc.org/gocloud.dev/docstore/mongodocstore#Dial +[`mongodocstore.OpenCollection`]: https://godoc.org/gocloud.dev/docstore/mongodocstore#OpenCollection +[`mongodocstore.OpenCollectionWithIDFunc`]: https://godoc.org/gocloud.dev/docstore/mongodocstore#OpenCollectionWithIDFunc + +### In-Memory Document Store {#mem} + +The [`memdocstore`](https://godoc.org/gocloud.dev/docstore/memdocstore) +package implements an in-memory document store suitable for testing and +development. + +URLs for the in-memory store have a `mem:` scheme. The URL host is used as the +the collection name, and the URL path is used as the name of the document field +to use as a primary key. + +{{< goexample +"gocloud.dev/docstore/memdocstore.Example_openCollectionFromURL" >}} + +Full details about acceptable URLs can be found under the API reference for +[`memdocstore.URLOpener`][]. + +[`memdocstore.URLOpener`]: https://godoc.org/gocloud.dev/docstore/memdocstore#URLOpener + +#### Mem Constructors {#mem-ctor} + +The [`memdocstore.OpenCollection`][] constructor creates and opens a collection, +taking the name of the key field. + +{{< goexample "gocloud.dev/docstore/memdocstore.ExampleOpenCollection" >}} + +You can instead supply a function to construct the primary key from the document +contents with [`memdocstore.OpenCollectionWithKeyFunc`][]. This can be useful +for documents whose name is the combination of two or more fields. + +{{< goexample +"gocloud.dev/docstore/memdocstore.ExampleOpenCollectionWithKeyFunc" >}} + +[`memdocstore.OpenCollection`]: https://godoc.org/gocloud.dev/docstore/memdocstore#OpenCollection +[`memdocstore.OpenCollectionWithKeyFunc`]: https://godoc.org/gocloud.dev/docstore/memdocstore#OpenCollectionWithKeyFunc diff --git a/go-cloud/internal/website/content/howto/pubsub/_index.md b/go-cloud/internal/website/content/howto/pubsub/_index.md new file mode 100644 index 000000000..f689aaabc --- /dev/null +++ b/go-cloud/internal/website/content/howto/pubsub/_index.md @@ -0,0 +1,29 @@ +--- +title: "Pub/Sub" +date: 2019-03-26T09:44:06-07:00 +showInSidenav: true +--- + +The [`pubsub` package][] provides an easy and portable way to interact with +publish/subscribe systems. This guide shows how to work with pubsub +in the Go CDK. + + + +The [publish/subscribe model][] allows parts of a system to publish messages +that other parts of a system may subscribe to. This is commonly used to +arrange for work to happen at some point after an interactive frontend +request is finished or in other event-driven computing. + +The [`pubsub` package][] supports operations to publish messages to a topic and +to subscribe to receive messages from a topic. + +Subpackages contain driver implementations of pubsub for various services, +including Cloud and on-prem solutions. You can develop your application +locally using [`mempubsub`][], then deploy it to multiple Cloud providers with +minimal initialization reconfiguration. + +[publish/subscribe model]: https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern +[`pubsub` package]: https://godoc.org/gocloud.dev/pubsub +[`mempubsub`]: https://godoc.org/gocloud.dev/pubsub/mempubsub + diff --git a/go-cloud/internal/website/content/howto/pubsub/publish.md b/go-cloud/internal/website/content/howto/pubsub/publish.md new file mode 100644 index 000000000..8b2f05468 --- /dev/null +++ b/go-cloud/internal/website/content/howto/pubsub/publish.md @@ -0,0 +1,305 @@ +--- +title: "Publish Messages to a Topic" +date: 2019-03-26T09:44:15-07:00 +lastmod: 2019-07-29T12:00:00-07:00 +weight: 1 +toc: true +--- + +Publishing a message to a topic with the Go CDK takes two steps: + +1. [Open a topic][] with the Pub/Sub provider of your choice (once per topic). +2. [Send messages][] on the topic. + +[Open a topic]: {{< ref "#opening" >}} +[Send messages]: {{< ref "#sending" >}} + + + +## Opening a Topic {#opening} + +The first step in publishing messages to a topic is to instantiate a +portable [`*pubsub.Topic`][] for your service. + +The easiest way to do so is to use [`pubsub.OpenTopic`][] and a service-specific URL +pointing to the topic, making sure you ["blank import"][] the driver package to +link it in. + +```go +import ( + "context" + + "gocloud.dev/pubsub" + _ "gocloud.dev/pubsub/" +) +... +ctx := context.Background() +topic, err := pubsub.OpenTopic(ctx, "") +if err != nil { + return fmt.Errorf("could not open topic: %v", err) +} +defer topic.Shutdown(ctx) +// topic is a *pubsub.Topic; see usage below +... +``` + +See [Concepts: URLs][] for general background and the [guide below][] +for URL usage for each supported service. + +Alternatively, if you need fine-grained +control over the connection settings, you can call the constructor function in +the driver package directly (like `gcppubsub.OpenTopic`). + +```go +import "gocloud.dev/pubsub/" +... +topic, err := .OpenTopic(...) +... +``` + +You may find the [`wire` package][] useful for managing your initialization code +when switching between different backing services. + +See the [guide below][] for constructor usage for each supported service. + +[guide below]: {{< ref "#services" >}} +[`*pubsub.Topic`]: https://godoc.org/gocloud.dev/pubsub#Topic +[`pubsub.OpenTopic`]: +https://godoc.org/gocloud.dev/pubsub#OpenTopic +["blank import"]: https://golang.org/doc/effective_go.html#blank_import +[Concepts: URLs]: {{< ref "/concepts/urls.md" >}} +[`wire` package]: http://github.com/google/wire + +## Sending Messages on a Topic {#sending} + +Sending a message on a [Topic](https://godoc.org/gocloud.dev/pubsub#Topic) looks +like this: + +{{< goexample src="gocloud.dev/pubsub.ExampleTopic_Send" imports="0" >}} + +Note that the [semantics of message delivery][] can vary by backing service. + +[semantics of message delivery]: https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery + +## Other Usage Samples + +* [CLI Sample](https://github.com/google/go-cloud/tree/master/samples/gocdk-pubsub) +* [Order Processor sample](https://gocloud.dev/tutorials/order/) +* [pubsub package examples](https://godoc.org/gocloud.dev/pubsub#pkg-examples) + +## Supported Pub/Sub Services {#services} + +### Google Cloud Pub/Sub {#gcp} + +The Go CDK can publish to a Google [Cloud Pub/Sub][] topic. The URLs use the +project ID and the topic ID. + +[Cloud Pub/Sub]: https://cloud.google.com/pubsub/docs/ + +`pubsub.OpenTopic` will use Application Default Credentials; if you have +authenticated via [`gcloud auth application-default login`][], it will use those credentials. See +[Application Default Credentials][GCP creds] to learn about authentication +alternatives, including using environment variables. + +[GCP creds]: https://cloud.google.com/docs/authentication/production +[`gcloud auth application-default login`]: https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login + +{{< goexample "gocloud.dev/pubsub/gcppubsub.Example_openTopicFromURL" >}} + +#### Google Cloud Pub/Sub Constructor {#gcp-ctor} + +The [`gcppubsub.OpenTopic`][] constructor opens a Cloud Pub/Sub topic. You +must first obtain [GCP credentials][GCP creds] and then create a gRPC +connection to Cloud Pub/Sub. (This gRPC connection can be reused among +topics.) + +{{< goexample "gocloud.dev/pubsub/gcppubsub.ExampleOpenTopic" >}} + +[`gcppubsub.OpenTopic`]: https://godoc.org/gocloud.dev/pubsub/gcppubsub#OpenTopic + +### Amazon Simple Notification Service {#sns} + +The Go CDK can publish to an Amazon [Simple Notification Service][SNS] (SNS) +topic. SNS URLs in the Go CDK use the Amazon Resource Name (ARN) to identify +the topic. You should specify the `region` query parameter to ensure your +application connects to the correct region. + +[SNS]: https://aws.amazon.com/sns/ + +It will create an AWS Config based on the AWS SDK V2; see [AWS V2 Config][] to learn more. + +{{< goexample "gocloud.dev/pubsub/awssnssqs.Example_openSNSTopicFromURL" >}} + +SNS messages are restricted to UTF-8 clean payloads. If your application +sends a message that contains non-UTF-8 bytes, then the Go CDK will +automatically [Base64][] encode the message and add a `base64encoded` message +attribute. When subscribing to messages on the topic through the Go CDK, +these will be [automatically Base64 decoded][SQS Subscribe], but if you are +receiving messages from a topic in a program that does not use the Go CDK, +you may need to manually Base64 decode the message payload. + +[Base64]: https://en.wikipedia.org/wiki/Base64 +[SQS Subscribe]: {{< relref "./subscribe.md#sqs" >}} +[AWS V2 Config]: https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ + +#### Amazon SNS Constructor {#sns-ctor} + +The [`awssnssqs.OpenSNSTopic`][] constructor opens an SNS topic. You must first +create an AWS Config with the same region as your topic: + +{{< goexample "gocloud.dev/pubsub/awssnssqs.ExampleOpenSNSTopic" >}} + +[`awssnssqs.OpenSNSTopic`]: https://godoc.org/gocloud.dev/pubsub/awssnssqs#OpenSNSTopic + +### Amazon Simple Queue Service {#sqs} + +The Go CDK can publish to an Amazon [Simple Queue Service][SQS] (SQS) +topic. SQS URLs closely resemble the the queue URL, except the leading +`https://` is replaced with `awssqs://`. You can specify the `region` +query parameter to ensure your application connects to the correct region, but +otherwise `pubsub.OpenTopic` will use the region found in the environment +variables or your AWS CLI configuration. + +{{< goexample "gocloud.dev/pubsub/awssnssqs.Example_openSQSTopicFromURL" >}} + +SQS messages are restricted to UTF-8 clean payloads. If your application +sends a message that contains non-UTF-8 bytes, then the Go CDK will +automatically [Base64][] encode the message and add a `base64encoded` message +attribute. When subscribing to messages on the topic through the Go CDK, +these will be [automatically Base64 decoded][SQS Subscribe], but if you are +receiving messages from a topic in a program that does not use the Go CDK, +you may need to manually Base64 decode the message payload. + +[Base64]: https://en.wikipedia.org/wiki/Base64 +[SQS Subscribe]: {{< relref "./subscribe.md#sqs" >}} +[SQS]: https://aws.amazon.com/sqs/ + +#### Amazon SQS Constructor {#sqs-ctor} + +The [`awssnssqs.OpenSQSTopic`][] constructor opens an SQS topic. You must first +create an AWS Config with the same region as your topic: + +{{< goexample "gocloud.dev/pubsub/awssnssqs.ExampleOpenSQSTopic" >}} + +[`awssnssqs.OpenSQSTopic`]: https://godoc.org/gocloud.dev/pubsub/awssnssqs#OpenSQSTopic + +### Azure Service Bus {#azure} + +The Go CDK can publish to an [Azure Service Bus][] topic. +The URL for publishing is the topic name. `pubsub.OpenTopic` will use the +environment variable `SERVICEBUS_CONNECTION_STRING` to obtain the Service Bus +connection string. The connection string can be obtained +[from the Azure portal][Azure connection string]. + +{{< goexample "gocloud.dev/pubsub/azuresb.Example_openTopicFromURL" >}} + +[Azure connection string]: https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-how-to-use-topics-subscriptions#get-the-connection-string +[Azure Service Bus]: https://azure.microsoft.com/en-us/services/service-bus/ + +#### Azure Service Bus Constructor {#azure-ctor} + +The [`azuresb.OpenTopic`][] constructor opens an Azure Service Bus topic. You +must first connect to the topic using the [Azure Service Bus library][] and +then pass it to `azuresb.OpenTopic`. There are also helper functions in the +`azuresb` package to make this easier. + +{{< goexample "gocloud.dev/pubsub/azuresb.ExampleOpenTopic" >}} + +[`azuresb.OpenTopic`]: https://godoc.org/gocloud.dev/pubsub/azuresb#OpenTopic +[Azure Service Bus library]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus + +### RabbitMQ {#rabbitmq} + +The Go CDK can publish to an [AMQP 0.9.1][] fanout exchange, the dialect of +AMQP spoken by [RabbitMQ][]. A RabbitMQ URL only includes the exchange name. +The RabbitMQ's server is discovered from the `RABBIT_SERVER_URL` environment +variable (which is something like `amqp://guest:guest@localhost:5672/`). + +{{< goexample "gocloud.dev/pubsub/rabbitpubsub.Example_openTopicFromURL" >}} + +[AMQP 0.9.1]: https://www.rabbitmq.com/protocol.html +[RabbitMQ]: https://www.rabbitmq.com + +#### RabbitMQ Constructor {#rabbitmq-ctor} + +The [`rabbitpubsub.OpenTopic`][] constructor opens a RabbitMQ exchange. You +must first create an [`*amqp.Connection`][] to your RabbitMQ instance. + +{{< goexample "gocloud.dev/pubsub/rabbitpubsub.ExampleOpenTopic" >}} + +[`*amqp.Connection`]: https://pkg.go.dev/github.com/rabbitmq/amqp091-go#Connection +[`rabbitpubsub.OpenTopic`]: https://godoc.org/gocloud.dev/pubsub/rabbitpubsub#OpenTopic + +### NATS {#nats} + +The Go CDK can publish to a [NATS][] subject. A NATS URL only includes the +subject name. The NATS server is discovered from the `NATS_SERVER_URL` +environment variable (which is something like `nats://nats.example.com`). + +{{< goexample "gocloud.dev/pubsub/natspubsub.Example_openTopicFromURL" >}} + +Because NATS does not natively support metadata, messages sent to NATS will +be encoded with [gob][]. + +[gob]: https://golang.org/pkg/encoding/gob/ +[NATS]: https://nats.io/ + +#### NATS Constructor {#nats-ctor} + +The [`natspubsub.OpenTopic`][] constructor opens a NATS subject as a topic. You +must first create an [`*nats.Conn`][] to your NATS instance. + +{{< goexample "gocloud.dev/pubsub/natspubsub.ExampleOpenTopic" >}} + +[`*nats.Conn`]: https://godoc.org/github.com/nats-io/go-nats#Conn +[`natspubsub.OpenTopic`]: https://godoc.org/gocloud.dev/pubsub/natspubsub#OpenTopic + +### Kafka {#kafka} + +The Go CDK can publish to a [Kafka][] cluster. A Kafka URL only includes the +topic name. The brokers in the Kafka cluster are discovered from the +`KAFKA_BROKERS` environment variable (which is a comma-delimited list of +hosts, something like `1.2.3.4:9092,5.6.7.8:9092`). + +{{< goexample "gocloud.dev/pubsub/kafkapubsub.Example_openTopicFromURL" >}} + +[Kafka]: https://kafka.apache.org/ + +#### Kafka Constructor {#kafka-ctor} + +The [`kafkapubsub.OpenTopic`][] constructor opens a Kafka topic to publish +messages to. Depending on your Kafka cluster configuration (see +`auto.create.topics.enable`), you may need to provision the topic beforehand. + +In addition to the list of brokers, you'll need a [`*sarama.Config`][], which +exposes many knobs that can affect performance and semantics; review and set +them carefully. [`kafkapubsub.MinimalConfig`][] provides a minimal config to get +you started. + +{{< goexample "gocloud.dev/pubsub/kafkapubsub.ExampleOpenTopic" >}} + +[`*sarama.Config`]: https://godoc.org/github.com/IBM/sarama#Config +[`kafkapubsub.OpenTopic`]: https://godoc.org/gocloud.dev/pubsub/kafkapubsub#OpenTopic +[`kafkapubsub.MinimalConfig`]: https://godoc.org/gocloud.dev/pubsub/kafkapubsub#MinimalConfig + +### In-Memory {#mem} + +The Go CDK includes an in-memory Pub/Sub provider useful for local testing. +The names in `mem://` URLs are a process-wide namespace, so subscriptions to +the same name will receive messages posted to that topic. This is detailed +more in the [subscription guide][subscribe-mem]. + +{{< goexample "gocloud.dev/pubsub/mempubsub.Example_openTopicFromURL" >}} + +[subscribe-mem]: {{< ref "./subscribe.md#mem" >}} + +#### In-Memory Constructor {#mem-ctor} + +To create an in-memory Pub/Sub topic, use the [`mempubsub.NewTopic` +function][]. You can use the returned topic to create in-memory +subscriptions, as detailed in the [subscription guide][subscribe-mem-ctor]. + +{{< goexample "gocloud.dev/pubsub/mempubsub.ExampleNewTopic" >}} + +[`mempubsub.NewTopic` function]: https://godoc.org/gocloud.dev/pubsub/mempubsub#NewTopic +[subscribe-mem-ctor]: {{< ref "./subscribe.md#mem-ctor" >}} diff --git a/go-cloud/internal/website/content/howto/pubsub/subscribe.md b/go-cloud/internal/website/content/howto/pubsub/subscribe.md new file mode 100644 index 000000000..bb3a8b7f5 --- /dev/null +++ b/go-cloud/internal/website/content/howto/pubsub/subscribe.md @@ -0,0 +1,296 @@ +--- +title: "Subscribe to Messages from a Topic" +date: 2019-03-26T09:44:33-07:00 +lastmod: 2019-07-29T12:00:00-07:00 +weight: 2 +toc: true +--- + +Subscribing to receive message from a topic with the Go CDK takes three steps: + +1. [Open a subscription][] to a topic with the Pub/Sub service of your choice (once per + subscription). +2. [Receive and acknowledge messages][] from the topic. After completing any + work related to the message, use the Ack method to prevent it from being + redelivered. + +[Open a subscription]: {{< ref "#opening" >}} +[Receive and acknowledge messages]: {{< ref "#receiving" >}} + + + +## Opening a Subscription {#opening} + +The first step in subscribing to receive messages from a topic is +to instantiate a portable [`*pubsub.Subscription`][] for your service. + +The easiest way to do so is to use [`pubsub.OpenSubscription`][] +and a service-specific URL pointing to the topic, making sure you +["blank import"][] the driver package to link it in. + +```go +import ( + "context" + + "gocloud.dev/pubsub" + _ "gocloud.dev/pubsub/" +) +... +ctx := context.Background() +subs, err := pubsub.OpenSubscription(ctx, "") +if err != nil { + return fmt.Errorf("could not open topic subscription: %v", err) +} +defer subs.Shutdown(ctx) +// subs is a *pubsub.Subscription; see usage below +... +``` + +See [Concepts: URLs][] for general background and the [guide below][] +for URL usage for each supported service. + +Alternatively, if you need fine-grained +control over the connection settings, you can call the constructor function in +the driver package directly (like `gcppubsub.OpenSubscription`). + +```go +import "gocloud.dev/pubsub/" +... +subs, err := .OpenSubscription(...) +... +``` + +You may find the [`wire` package][] useful for managing your initialization code +when switching between different backing services. + +See the [guide below][] for constructor usage for each supported service. + +[guide below]: {{< ref "#services" >}} +[`pubsub.OpenSubscription`]: +https://godoc.org/gocloud.dev/pubsub#OpenTopic +["blank import"]: https://golang.org/doc/effective_go.html#blank_import +[Concepts: URLs]: {{< ref "/concepts/urls.md" >}} +[`wire` package]: http://github.com/google/wire + +## Receiving and Acknowledging Messages {#receiving} + +A simple subscriber that operates on +[messages](https://godoc.org/gocloud.dev/pubsub#Message) serially looks like +this: + +{{< goexample src="gocloud.dev/pubsub.ExampleSubscription_Receive" imports="0" >}} + +If you want your subscriber to operate on incoming messages concurrently, +you can start multiple goroutines: + +{{< goexample src="gocloud.dev/pubsub.ExampleSubscription_Receive_concurrent" imports="0" >}} + +Note that the [semantics of message delivery][] can vary by backing service. + +[`*pubsub.Subscription`]: https://godoc.org/gocloud.dev/pubsub#Subscription +[semantics of message delivery]: https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery + +## Other Usage Samples + +* [CLI Sample](https://github.com/google/go-cloud/tree/master/samples/gocdk-pubsub) +* [Order Processor sample](https://gocloud.dev/tutorials/order/) +* [pubsub package examples](https://godoc.org/gocloud.dev/pubsub#pkg-examples) + +## Supported Pub/Sub Services {#services} + +### Google Cloud Pub/Sub {#gcp} + +The Go CDK can receive messages from a Google [Cloud Pub/Sub][] subscription. +The URLs use the project ID and the subscription ID. + +[Cloud Pub/Sub]: https://cloud.google.com/pubsub/docs/ + +`pubsub.OpenSubscription` will use Application Default Credentials; if you have +authenticated via [`gcloud auth application-default login`][], it will use those credentials. See +[Application Default Credentials][GCP creds] to learn about authentication +alternatives, including using environment variables. + +[GCP creds]: https://cloud.google.com/docs/authentication/production +[`gcloud auth application-default login`]: https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login + +{{< goexample "gocloud.dev/pubsub/gcppubsub.Example_openSubscriptionFromURL" >}} + +#### Google Cloud Pub/Sub Constructor {#gcp-ctor} + +The [`gcppubsub.OpenSubscription`][] constructor opens a Cloud Pub/Sub +subscription. You must first obtain [GCP credentials][GCP creds] and then +create a gRPC connection to Cloud Pub/Sub. (This gRPC connection can be +reused among subscriptions.) + +{{< goexample "gocloud.dev/pubsub/gcppubsub.ExampleOpenSubscription" >}} + +[`gcppubsub.OpenSubscription`]: https://godoc.org/gocloud.dev/pubsub/gcppubsub#OpenSubscription + +### Amazon Simple Queueing Service {#sqs} + +The Go CDK can subscribe to an Amazon [Simple Queueing Service][SQS] (SQS) +topic. SQS URLs closely resemble the the queue URL, except the leading +`https://` is replaced with `awssqs://`. You should specify the `region` +query parameter to ensure your application connects to the correct region. + +[SQS]: https://aws.amazon.com/sqs/ + +`pubsub.OpenSubscription` will open a subscription using a default AWS Config. + +{{< goexample "gocloud.dev/pubsub/awssnssqs.Example_openSubscriptionFromURL" >}} + +If your messages are being sent to SQS directly, or if they are being delivered +via an SNS topic with `RawMessageDelivery` enabled, set a `raw=true` query +parameter in your URL, or set `SubscriberOptions.Raw` to `true` if you're using +the constructors. By default, the subscription will use heuristics to identify +whether the message bodies are raw or [SNS JSON][]. + +Messages with a `base64encoded` message attribute will be automatically +[Base64][] decoded before being returned. See the [SNS publishing guide][] +or the [SQS publishing guide][] for more details. + +[Base64]: https://en.wikipedia.org/wiki/Base64 +[SNS publishing guide]: {{< ref "./publish.md#sns" >}} +[SQS publishing guide]: {{< ref "./publish.md#sqs" >}} +[SNS JSON]: https://aws.amazon.com/sns/faqs/#Raw_message_delivery + +#### Amazon SQS Constructor {#sqs-ctor} + +The [`awssnssqs.OpenSubscription`][] constructor opens an SQS queue. You must +first create an AWS Config with the same region as your topic: + +{{< goexample "gocloud.dev/pubsub/awssnssqs.ExampleOpenSubscription" >}} + +[`awssnssqs.OpenSubscription`]: https://godoc.org/gocloud.dev/pubsub/awssnssqs#OpenSubscription + +### Azure Service Bus {#azure} + +The Go CDK can recieve messages from an [Azure Service Bus][] subscription. +The URL for subscribing is the topic name with the +subscription name in the `subscription` query parameter. +`pubsub.OpenSubscription` will use the environment variable +`SERVICEBUS_CONNECTION_STRING` to obtain the Service Bus Connection String +you need to copy [from the Azure portal][Azure connection string]. + +{{< goexample "gocloud.dev/pubsub/azuresb.Example_openSubscriptionFromURL" >}} + +[AMQP 1.0]: https://www.amqp.org/ +[Azure connection string]: https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-how-to-use-topics-subscriptions#get-the-connection-string +[Azure Service Bus]: https://azure.microsoft.com/en-us/services/service-bus/ + +#### Azure Service Bus Constructor {#azure-ctor} + +The [`azuresb.OpenSubscription`][] constructor opens an Azure Service Bus +subscription. You must first connect to the topic and subscription using the +[Azure Service Bus library][] and then pass the subscription to +`azuresb.OpenSubscription`. There are also helper functions in the `azuresb` +package to make this easier. + +{{< goexample "gocloud.dev/pubsub/azuresb.ExampleOpenSubscription" >}} + +[`azuresb.OpenSubscription`]: https://godoc.org/gocloud.dev/pubsub/azuresb#OpenSubscription +[Azure Service Bus library]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus + +### RabbitMQ {#rabbitmq} + +The Go CDK can receive messages from an [AMQP 0.9.1][] queue, the dialect of +AMQP spoken by [RabbitMQ][]. A RabbitMQ URL only includes the queue name. +The RabbitMQ's server is discovered from the `RABBIT_SERVER_URL` environment +variable (which is something like `amqp://guest:guest@localhost:5672/`). + +{{< goexample "gocloud.dev/pubsub/rabbitpubsub.Example_openSubscriptionFromURL" >}} + +[AMQP 0.9.1]: https://www.rabbitmq.com/protocol.html +[RabbitMQ]: https://www.rabbitmq.com + +#### RabbitMQ Constructor {#rabbitmq-ctor} + +The [`rabbitpubsub.OpenSubscription`][] constructor opens a RabbitMQ queue. +You must first create an [`*amqp.Connection`][] to your RabbitMQ instance. + +{{< goexample "gocloud.dev/pubsub/rabbitpubsub.ExampleOpenSubscription" >}} + +[`*amqp.Connection`]: https://pkg.go.dev/github.com/rabbitmq/amqp091-go#Connection +[`rabbitpubsub.OpenSubscription`]: https://godoc.org/gocloud.dev/pubsub/rabbitpubsub#OpenSubscription + +### NATS {#nats} + +The Go CDK can publish to a [NATS][] subject. A NATS URL only includes the +subject name. The NATS server is discovered from the `NATS_SERVER_URL` +environment variable (which is something like `nats://nats.example.com`). + +{{< goexample "gocloud.dev/pubsub/natspubsub.Example_openSubscriptionFromURL" >}} + +NATS guarantees at-most-once delivery; it will never redeliver a message. +Therefore, `Message.Ack` is a no-op. + +To parse messages [published via the Go CDK][publish#nats], the NATS driver +will first attempt to decode the payload using [gob][]. Failing that, it will +return the message payload as the `Data` with no metadata to accomodate +subscribing to messages coming from a source not using the Go CDK. + +[gob]: https://golang.org/pkg/encoding/gob/ +[NATS]: https://nats.io/ +[publish#nats]: {{< ref "./publish.md#nats" >}} + +#### NATS Constructor {#nats-ctor} + +The [`natspubsub.OpenSubscription`][] constructor opens a NATS subject as a +topic. You must first create an [`*nats.Conn`][] to your NATS instance. + +{{< goexample "gocloud.dev/pubsub/natspubsub.ExampleOpenSubscription" >}} + +[`*nats.Conn`]: https://godoc.org/github.com/nats-io/go-nats#Conn +[`natspubsub.OpenSubscription`]: https://godoc.org/gocloud.dev/pubsub/natspubsub#OpenSubscription + +### Kafka {#kafka} + +The Go CDK can receive messages from a [Kafka][] cluster. +A Kafka URL includes the consumer group name, plus at least one instance +of a query parameter specifying the topic to subscribe to. +The brokers in the Kafka cluster are discovered from the +`KAFKA_BROKERS` environment variable (which is a comma-delimited list of +hosts, something like `1.2.3.4:9092,5.6.7.8:9092`). + +{{< goexample "gocloud.dev/pubsub/kafkapubsub.Example_openSubscriptionFromURL" >}} + +[Kafka]: https://kafka.apache.org/ + +#### Kafka Constructor {#kafka-ctor} + +The [`kafkapubsub.OpenSubscription`][] constructor creates a consumer in a +consumer group, subscribed to one or more topics. + +In addition to the list of brokers, you'll need a [`*sarama.Config`][], which +exposes many knobs that can affect performance and semantics; review and set +them carefully. [`kafkapubsub.MinimalConfig`][] provides a minimal config to +get you started. + +{{< goexample "gocloud.dev/pubsub/kafkapubsub.ExampleOpenSubscription" >}} + +[`*sarama.Config`]: https://godoc.org/github.com/IBM/sarama#Config +[`kafkapubsub.OpenSubscription`]: https://godoc.org/gocloud.dev/pubsub/kafkapubsub#OpenSubscription +[`kafkapubsub.MinimalConfig`]: https://godoc.org/gocloud.dev/pubsub/kafkapubsub#MinimalConfig + +### In-Memory {#mem} + +The Go CDK includes an in-memory Pub/Sub provider useful for local testing. +The names in `mem://` URLs are a process-wide namespace, so subscriptions to +the same name will receive messages posted to that topic. For instance, if +you open a topic `mem://topicA` and open two subscriptions with +`mem://topicA`, you will have two subscriptions to the same topic. + +{{< goexample "gocloud.dev/pubsub/mempubsub.Example_openSubscriptionFromURL" >}} + +#### In-Memory Constructor {#mem-ctor} + +To create a subscription to an in-memory Pub/Sub topic, pass the [topic you +created][publish-mem-ctor] into the [`mempubsub.NewSubscription` function][]. +You will also need to pass an acknowledgement deadline: once a message is +received, if it is not acknowledged after the deadline elapses, then it will be +redelivered. + +{{< goexample "gocloud.dev/pubsub/mempubsub.ExampleNewSubscription" >}} + +[`mempubsub.NewSubscription` function]: https://godoc.org/gocloud.dev/pubsub/mempubsub#NewSubscription +[publish-mem-ctor]: {{< ref "./publish.md#mem-ctor" >}} diff --git a/go-cloud/internal/website/content/howto/runtimevar/_index.md b/go-cloud/internal/website/content/howto/runtimevar/_index.md new file mode 100644 index 000000000..c9567fc6e --- /dev/null +++ b/go-cloud/internal/website/content/howto/runtimevar/_index.md @@ -0,0 +1,277 @@ +--- +title: "Runtime Configuration" +date: 2019-07-11T12:00:00-07:00 +lastmod: 2020-12-23T12:00:00-07:00 +showInSidenav: true +toc: true +--- + +The [`runtimevar` package][] provides an easy and portable way to watch runtime +configuration variables. This guide shows how to work with runtime configuration +variables using the Go CDK. + + + +Subpackages contain driver implementations of runtimevar for various services, +including Cloud and on-prem solutions. You can develop your application locally +using [`filevar`][] or [`constantvar`][], then deploy it to multiple Cloud +providers with minimal initialization reconfiguration. + +[`runtimevar` package]: https://godoc.org/gocloud.dev/runtimevar +[`filevar`]: https://godoc.org/gocloud.dev/runtimevar/filevar +[`constantvar`]: https://godoc.org/gocloud.dev/runtimevar/constantvar + +## Opening a Variable {#opening} + +The first step in watching a variable is to instantiate a portable +[`*runtimevar.Variable`][] for your service. + +The easiest way to do so is to use [`runtimevar.OpenVariable`][] and a service-specific URL pointing +to the variable, making sure you ["blank import"][] the driver package to link +it in. + +```go +import ( + "gocloud.dev/runtimevar" + _ "gocloud.dev/runtimevar/" +) +... +v, err := runtimevar.OpenVariable(context.Background(), "") +if err != nil { + return fmt.Errorf("could not open variable: %v", err) +} +defer v.Close() +// v is a *runtimevar.Variable; see usage below +... +``` + +See [Concepts: URLs][] for general background and the [guide below][] +for URL usage for each supported service. + +Alternatively, if you need fine-grained control +over the connection settings, you can call the constructor function in the +driver package directly (like `etcdvar.OpenVariable`). + +```go +import "gocloud.dev/runtimevar/" +... +v, err := .OpenVariable(...) +... +``` + +You may find the [`wire` package][] useful for managing your initialization code +when switching between different backing services. + +See the [guide below][] for constructor usage for each supported service. + +When opening the variable, you can provide a [decoder][] parameter (either as a +[query parameter][] for URLs, or explicitly to the constructor) to specify +whether the raw value stored in the variable is interpreted as a `string`, a +`[]byte`, or as JSON. Here's an example of using a JSON encoder: + +{{< goexample src="gocloud.dev/runtimevar.Example_jsonDecoder" imports="0" >}} + +[`*runtimevar.Variable`]: https://godoc.org/gocloud.dev/runtimevar#Variable +[`runtimevar.OpenVariable`]: https://godoc.org/gocloud.dev/runtimevar#OpenVariable +["blank import"]: https://golang.org/doc/effective_go.html#blank_import +[Concepts: URLs]: {{< ref "/concepts/urls.md" >}} +[decoder]: https://godoc.org/gocloud.dev/runtimevar#Decoder +[guide below]: {{< ref "#services" >}} +[query parameter]: https://godoc.org/gocloud.dev/runtimevar#DecoderByName +[`wire` package]: http://github.com/google/wire + +## Using a Variable {#using} + +Once you have opened a `runtimevar.Variable` for the provider you want, you can +use it portably. + +### Latest {#latest} + +The easiest way to a `Variable` is to use the [`Variable.Latest`][] method. It +returns the latest good [`Snapshot`][] of the variable value, blocking if no +good value has *ever* been detected. The dynamic type of `Snapshot.Value` +depends on the decoder you provided when creating the `Variable`. + +{{< goexample src="gocloud.dev/runtimevar.ExampleVariable_Latest" imports="0" >}} + +To avoid blocking, you can pass an already-`Done` context. You can also use +[`Variable.CheckHealth`][], which reports as healthy when `Latest` will +return a value without blocking. + +[`Variable.Latest`]: https://godoc.org/gocloud.dev/runtimevar#Variable.Latest +[`Variable.CheckHealth`]: https://godoc.org/gocloud.dev/runtimevar#Variable.CheckHealth +[`Snapshot`]: https://godoc.org/gocloud.dev/runtimevar#Snapshot + +### Watch {#watch} + +`Variable` also has a [`Watch`][] method for obtaining the value of a variable; +it has different semantics than `Latest` and may be useful in some scenarios. We +recommend starting with `Latest` as it's conceptually simpler to work with. + +[`Watch`]: https://godoc.org/gocloud.dev/runtimevar#Variable.Watch + +## Other Usage Samples + +* [CLI Sample](https://github.com/google/go-cloud/tree/master/samples/gocdk-runtimevar) +* [Guestbook sample](https://gocloud.dev/tutorials/guestbook/) +* [runtimevar package examples](https://godoc.org/gocloud.dev/runtimevar#pkg-examples) + +## Supported Services {#services} + +### GCP Runtime Configurator {#gcprc} + +To open a variable stored in [GCP Runtime Configurator][] via a URL, you can use +the `runtimevar.OpenVariable` function as shown in the example below. + +[GCP Runtime Configurator]: https://cloud.google.com/deployment-manager/runtime-configurator/ + +`runtimevar.OpenVariable` will use Application Default Credentials; if you have +authenticated via [`gcloud auth application-default login`][], it will use those credentials. See +[Application Default Credentials][GCP creds] to learn about authentication +alternatives, including using environment variables. + +[GCP creds]: https://cloud.google.com/docs/authentication/production +[`gcloud auth application-default login`]: https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login + +{{< goexample +"gocloud.dev/runtimevar/gcpruntimeconfig.Example_openVariableFromURL" >}} + +#### GCP Constructor {#gcprc-ctor} + +The [`gcpruntimeconfig.OpenVariable`][] constructor opens a Runtime Configurator +variable. + +{{< goexample "gocloud.dev/runtimevar/gcpruntimeconfig.ExampleOpenVariable" >}} + +[`gcpruntimeconfig.OpenVariable`]: https://godoc.org/gocloud.dev/runtimevar/gcpruntimeconfig#OpenVariable + +### GCP Secret Manager {#gcpsm} + +To open a variable stored in [GCP Secret Manager][] via a URL, you can use +the `runtimevar.OpenVariable` function as shown in the example below. + +[GCP Secret Manager]: https://cloud.google.com/secret-manager + +`runtimevar.OpenVariable` will use Application Default Credentials; if you have +authenticated via [`gcloud auth application-default login`][], it will use those credentials. See +[Application Default Credentials][GCP creds] to learn about authentication +alternatives, including using environment variables. + +[GCP creds]: https://cloud.google.com/docs/authentication/production +[`gcloud auth application-default login`]: https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login + +{{< goexample +"gocloud.dev/runtimevar/gcpsecretmanager.Example_openVariableFromURL" >}} + +#### GCP Constructor {#gcpsm-ctor} + +The [`gcpsecretmanager.OpenVariable`][] constructor opens a Secret Manager +variable. + +{{< goexample "gocloud.dev/runtimevar/gcpsecretmanager.ExampleOpenVariable" >}} + +[`gcpsecretmanager.OpenVariable`]: https://godoc.org/gocloud.dev/runtimevar/gcpsecretmanager#OpenVariable + +### AWS Parameter Store {#awsps} + +To open a variable stored in [AWS Parameter Store][] via a URL, you can use the +`runtimevar.OpenVariable` function as shown in the example below. + +[AWS Parameter Store]: +https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html + +It will create an AWS Config based on the AWS SDK V2; see [AWS V2 Config][] to learn more. + +[AWS V2 Config]: https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ + +{{< goexample +"gocloud.dev/runtimevar/awsparamstore.Example_openVariableFromURL" >}} + +#### AWS Constructor {#awsps-ctor} + +The [`awsparamstore.OpenVariable`][] constructor opens a Parameter Store +variable. + +{{< goexample "gocloud.dev/runtimevar/awsparamstore.ExampleOpenVariable" >}} + +[`awsparamstore.OpenVariable`]: +https://godoc.org/gocloud.dev/runtimevar/awsparamstore#OpenVariable + +### AWS Secrets Manager {#awssm} + +To open a variable stored in [AWS Secrets Manager][] via a URL, you can use the +`runtimevar.OpenVariable` function as shown in the example below. + +[AWS Secrets Manager]: +https://aws.amazon.com/secrets-manager + +It will create an AWS Config based on the AWS SDK V2; see [AWS V2 Config][] to learn more. + +[AWS V2 Config]: https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ + +{{< goexample +"gocloud.dev/runtimevar/awssecretsmanager.Example_openVariableFromURL" >}} + +#### AWS Constructor {#awssm-ctor} + +The [`awssecretsmanager.OpenVariable`][] constructor opens a Secrets Manager +variable. + +{{< goexample "gocloud.dev/runtimevar/awssecretsmanager.ExampleOpenVariable" >}} + +[`awssecretsmanager.OpenVariable`]: +https://godoc.org/gocloud.dev/runtimevar/awssecretsmanager#OpenVariable + +Note that both `secretsmanager:GetSecretValue` and `secretsmanager:DescribeSecret` actions must be allowed in +the caller's IAM policy. + +### etcd {#etcd} + +*NOTE*: Support for `etcd` has been temporarily dropped due to dependency +issues. See https://github.com/google/go-cloud/issues/2914. + +You can use `runtimevar.etcd` in Go CDK version `v0.20.0` or earlier. + +### HTTP {#http} + +`httpvar` supports watching a variable via an HTTP request. Use +`runtimevar.OpenVariable` with a regular URL starting with `http` or `https`. +`httpvar` will periodically make an HTTP `GET` request to that URL, with the +`decode` URL parameter removed (if present). + +{{< goexample "gocloud.dev/runtimevar/httpvar.Example_openVariableFromURL" >}} + +#### HTTP Constructor {#http-ctor} + +The [`httpvar.OpenVariable`][] constructor opens a variable with a `http.Client` +and a URL. + +{{< goexample "gocloud.dev/runtimevar/httpvar.ExampleOpenVariable" >}} + +[`httpvar.OpenVariable`]: https://godoc.org/gocloud.dev/runtimevar/httpvar#OpenVariable + +### Blob {#blob} + +`blobvar` supports watching a variable based on the contents of a +[Go CDK blob][]. Set the environment variable `BLOBVAR_BUCKET_URL` to the URL +of the bucket, and then use `runtimevar.OpenVariable` as shown below. +`blobvar` will periodically re-fetch the contents of the blob. + +{{< goexample "gocloud.dev/runtimevar/blobvar.Example_openVariableFromURL" >}} + +[Go CDK blob]: https://gocloud.dev/howto/blob/ + +You can also use [`blobvar.OpenVariable`][]. + +[`blobvar.OpenVariable`]: https://godoc.org/gocloud.dev/runtimevar/blobvar#OpenVariable + +### Local {#local} + +You can create an in-memory variable (useful for testing) using `constantvar`: + +{{< goexample "gocloud.dev/runtimevar/constantvar.Example_openVariableFromURL" >}} + +Alternatively, you can create a variable based on the contents of a file using +`filevar`: + +{{< goexample "gocloud.dev/runtimevar/filevar.Example_openVariableFromURL" >}} diff --git a/go-cloud/internal/website/content/howto/secrets/_index.md b/go-cloud/internal/website/content/howto/secrets/_index.md new file mode 100644 index 000000000..d53703a16 --- /dev/null +++ b/go-cloud/internal/website/content/howto/secrets/_index.md @@ -0,0 +1,276 @@ +--- +title: "Secrets" +date: 2019-03-21T17:42:18-07:00 +lastmod: 2019-07-29T12:00:00-07:00 +showInSidenav: true +toc: true +--- + +The [`secrets` package][] provides access to key management services in a +portable way. This guide shows how to work with secrets in the Go CDK. + + + +Cloud applications frequently need to store sensitive information like web +API credentials or encryption keys in a medium that is not fully secure. For +example, an application that interacts with GitHub needs to store its OAuth2 +client secret and use it when obtaining end-user credentials. If this +information was compromised, it could allow someone else to impersonate the +application. In order to keep such information secret and secure, you can +encrypt the data, but then you need to worry about rotating the encryption +keys and distributing them securely to all of your application servers. +Most Cloud providers include a key management service to perform these tasks, +usually with hardware-level security and audit logging. + +The [`secrets` package][] supports encryption and decryption operations. + +Subpackages contain driver implementations of secrets for various services, +including Cloud and on-prem solutions. You can develop your application +locally using [`localsecrets`][], then deploy it to multiple Cloud providers with +minimal initialization reconfiguration. + +[`secrets` package]: https://godoc.org/gocloud.dev/secrets +[`localsecrets`]: https://godoc.org/gocloud.dev/secrets/localsecrets + +## Opening a SecretsKeeper {#opening} + +The first step in working with your secrets is +to instantiate a portable [`*secrets.Keeper`][] for your service. + +The easiest way to do so is to use [`secrets.OpenKeeper`][] and a service-specific +URL pointing to the keeper, making sure you ["blank import"][] the driver +package to link it in. + +```go +import ( + "gocloud.dev/secrets" + _ "gocloud.dev/secrets/" +) +... +keeper, err := secrets.OpenKeeper(context.Background(), "") +if err != nil { + return fmt.Errorf("could not open keeper: %v", err) +} +defer keeper.Close() +// keeper is a *secrets.Keeper; see usage below +... +``` + +See [Concepts: URLs][] for general background and the [guide below][] +for URL usage for each supported service. + +Alternatively, if you need +fine-grained control over the connection settings, you can call the constructor +function in the driver package directly (like `awskms.OpenKeeper`). + +```go +import "gocloud.dev/secrets/" +... +keeper, err := .OpenKeeper(...) +... +``` + +You may find the [`wire` package][] useful for managing your initialization code +when switching between different backing services. + +See the [guide below][] for constructor usage for each supported service. + +[`*secrets.Keeper`]: https://godoc.org/gocloud.dev/secrets#Keeper +[`secrets.OpenKeeper`]: +https://godoc.org/gocloud.dev/secrets#OpenKeeper +["blank import"]: https://golang.org/doc/effective_go.html#blank_import +[Concepts: URLs]: {{< ref "/concepts/urls.md" >}} +[guide below]: {{< ref "#services" >}} +[`wire` package]: http://github.com/google/wire + +## Using a SecretsKeeper {#using} + +Once you have [opened a secrets keeper][] for the secrets provider you want, +you can encrypt and decrypt small messages using the keeper. + +[opened a secrets keeper]: {{< ref "#opening" >}} + +### Encrypting Data {#encrypt} + +To encrypt data with a keeper, you call `Encrypt` with the byte slice you +want to encrypt. + +{{< goexample src="gocloud.dev/secrets.ExampleKeeper_Encrypt" imports="0" >}} + +### Decrypting Data {#decrypt} + +To decrypt data with a keeper, you call `Decrypt` with the byte slice you +want to decrypt. This should be data that you obtained from a previous call +to `Encrypt` with a keeper that uses the same secret material (e.g. two AWS +KMS keepers created with the same customer master key ID). The `Decrypt` +method will return an error if the input data is corrupted. + +{{< goexample src="gocloud.dev/secrets.ExampleKeeper_Decrypt" imports="0" >}} + +### Large Messages {#large-messages} + +The secrets keeper API is designed to work with small messages (i.e. <10 KiB +in length.) Cloud key management services are high latency; using them for +encrypting or decrypting large amounts of data is prohibitively slow (and in +some providers not permitted). If you need your application to encrypt or +decrypt large amounts of data, you should: + +1. Generate a key for the encryption algorithm (16KiB chunks with + [`secretbox`][] is a reasonable approach). +2. Encrypt the key with secret keeper. +3. Store the encrypted key somewhere accessible to the application. + +When your application needs to encrypt or decrypt a large message: + +1. Decrypt the key from storage using the secret keeper +2. Use the decrypted key to encrypt or decrypt the message inside your + application. + +[`secretbox`]: https://godoc.org/golang.org/x/crypto/nacl/secretbox + +### Keep Secrets in Configuration {#runtimevar} + +Once you have [opened a secrets keeper][] for the secrets provider you want, +you can use a secrets keeper to access sensitive configuration stored in an +encrypted `runtimevar`. + +First, you create a [`*runtimevar.Decoder`][] configured to use your secrets +keeper using [`runtimevar.DecryptDecode`][]. In this example, we assume the +data is a plain string, but the configuration could be a more structured +type. + +{{< goexample src="gocloud.dev/runtimevar.ExampleDecryptDecode" imports="0" >}} + +Then you can pass the decoder to the runtime configuration provider of your +choice. See the [Runtime Configuration How-To Guide][] for more on how to set up +runtime configuration. + +[opened a secrets keeper]: {{< ref "#opening" >}} +[Runtime Configuration How-To Guide]: {{< ref "/howto/runtimevar/_index.md" >}} +[`*runtimevar.Decoder`]: https://godoc.org/gocloud.dev/runtimevar#Decoder +[`runtimevar.DecryptDecode`]: https://godoc.org/gocloud.dev/runtimevar#DecryptDecode + +## Other Usage Samples + +* [CLI Sample](https://github.com/google/go-cloud/tree/master/samples/gocdk-secrets) +* [Secrets package examples](https://godoc.org/gocloud.dev/secrets#example-package) + +## Supported Services {#services} + +### Google Cloud Key Management Service {#gcp} + +The Go CDK can use keys from Google Cloud Platform's [Key Management +Service][GCP KMS] (GCP KMS) to keep information secret. GCP KMS URLs are +similar to [key resource IDs][]. + +[GCP KMS]: https://cloud.google.com/kms/ +[key resource IDs]: https://cloud.google.com/kms/docs/object-hierarchy#key + +`secrets.OpenKeeper` will use Application Default Credentials; if you have +authenticated via [`gcloud auth application-default login`][], it will use those credentials. See +[Application Default Credentials][GCP creds] to learn about authentication +alternatives, including using environment variables. + +[GCP creds]: https://cloud.google.com/docs/authentication/production +[`gcloud auth application-default login`]: https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login + +{{< goexample "gocloud.dev/secrets/gcpkms.Example_openFromURL" >}} + +#### GCP Constructor {#gcp-ctor} + +The [`gcpkms.OpenKeeper`][] constructor opens a GCP KMS key. You must first +obtain [GCP credentials][GCP creds] and then create a gRPC connection to GCP KMS. + +{{< goexample "gocloud.dev/secrets/gcpkms.ExampleOpenKeeper" >}} + +[`gcpkms.OpenKeeper`]: https://godoc.org/gocloud.dev/secrets/gcpkms#OpenKeeper + +### AWS Key Management Service {#aws} + +The Go CDK can use customer master keys from Amazon Web Service's [Key +Management Service][AWS KMS] (AWS KMS) to keep information secret. AWS KMS +URLs can use the key's ID, alias, or Amazon Resource Name (ARN) to identify +the key. You should specify the `region` query parameter to ensure your +application connects to the correct region. + +[AWS KMS]: https://aws.amazon.com/kms/ + +It will create an AWS Config based on the AWS SDK V2; see [AWS V2 Config][] to learn more. + +[AWS V2 Config]: https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ + +{{< goexample "gocloud.dev/secrets/awskms.Example_openFromURL" >}} + +#### AWS Constructor {#aws-ctor} + +The [`awskms.OpenKeeper`][] constructor opens a customer master key. You must +first create an AWS Config with the same region as your key and then +connect to KMS: + +{{< goexample "gocloud.dev/secrets/awskms.ExampleOpenKeeper" >}} + +[`awskms.OpenKeeper`]: https://godoc.org/gocloud.dev/secrets/awskms#OpenKeeper + +### Azure KeyVault {#azure} + +The Go CDK can use keys from [Azure KeyVault][] to keep information secret. +`secrets.OpenKeeper` will use [default credentials from the environment][Azure +Environment Auth], unless you set the environment variable +`AZURE_KEYVAULT_AUTH_VIA_CLI` to `true`, in which case it will use +credentials from the `az` command line. + +Azure KeyVault URLs are based on the [Azure Key object identifer][Azure Key ID]: + +{{< goexample "gocloud.dev/secrets/azurekeyvault.Example_openFromURL" >}} + +[Azure KeyVault]: https://azure.microsoft.com/en-us/services/key-vault/ +[Azure Environment Auth]: https://docs.microsoft.com/en-us/go/azure/azure-sdk-go-authorization#use-environment-based-authentication +[Azure Key ID]: https://docs.microsoft.com/en-us/azure/key-vault/about-keys-secrets-and-certificates + +#### Azure Constructor {#azure-ctor} + +The [`azurekeyvault.OpenKeeper`][] constructor opens an Azure KeyVault key. + +{{< goexample "gocloud.dev/secrets/azurekeyvault.ExampleOpenKeeper" >}} + +[`azurekeyvault.OpenKeeper`]: https://godoc.org/gocloud.dev/secrets/azurekeyvault#OpenKeeper + +### HashiCorp Vault {#vault} + +The Go CDK can use the [transit secrets engine][] in [Vault][] to keep +information secret. Vault URLs only specify the key ID. The Vault server +endpoint and authentication token are specified using the environment +variables `VAULT_SERVER_URL` and `VAULT_SERVER_TOKEN`, respectively. + +{{< goexample "gocloud.dev/secrets/hashivault.Example_openFromURL" >}} + +[Vault]: https://www.vaultproject.io/ +[transit secrets engine]: https://www.vaultproject.io/docs/secrets/transit/index.html + +#### HashiCorp Vault Constructor {#vault-ctor} + +The [`hashivault.OpenKeeper`][] constructor opens a transit secrets engine +key. You must first connect to your Vault instance. + +{{< goexample "gocloud.dev/secrets/hashivault.ExampleOpenKeeper" >}} + +[`hashivault.OpenKeeper`]: https://godoc.org/gocloud.dev/secrets/hashivault#OpenKeeper + +### Local Secrets {#local} + +The Go CDK can use local encryption for keeping secrets. Internally, it uses +the [NaCl secret box][] algorithm to perform encryption and authentication. + +{{< goexample "gocloud.dev/secrets/localsecrets.Example_openFromURL" >}} + +[NaCl secret box]: https://godoc.org/golang.org/x/crypto/nacl/secretbox + +#### Local Secrets Constructor {#local-ctor} + +The [`localsecrets.NewKeeper`][] constructor takes in its secret material as +a `[]byte`. + +{{< goexample "gocloud.dev/secrets/localsecrets.ExampleNewKeeper" >}} + +[`localsecrets.NewKeeper`]: https://godoc.org/gocloud.dev/secrets/localsecrets#NewKeeper + diff --git a/go-cloud/internal/website/content/howto/server/_index.md b/go-cloud/internal/website/content/howto/server/_index.md new file mode 100644 index 000000000..af299c0ff --- /dev/null +++ b/go-cloud/internal/website/content/howto/server/_index.md @@ -0,0 +1,72 @@ +--- +title: "Server" +date: 2019-06-21T10:36:43-07:00 +showInSidenav: true +toc: true +--- + +The Go CDK's `server` package provides a pre-configured HTTP server with +diagnostic hooks for request logging, health checks, and trace exporting via +OpenCensus. This guide will show you how to start up and shut down the server, +as well as how to work with the request logging and health checks. + +## Starting up the server + +The Go CDK Server constructor takes an `http.Handler` and an `Options` struct. +The simplest way to start the server is to use `http.DefaultServeMux` and +pass `nil` for the options. + +{{< goexample src="gocloud.dev/server.ExampleServer" >}} + +### Adding a request logger + +You can use the `server.Options` struct to specify a request logger. + +The example is shown with the Go CDK [`requestlog`](https://godoc.org/gocloud.dev/server/requestlog) package's `NCSALogger`. +To get logs in the Stackdriver JSON format, use `NewStackdriverLogger` in place +of `NewNCSALogger`. + +{{< goexample src="gocloud.dev/server.ExampleServer_withRequestLogger" >}} + +### Adding health checks + +The Go CDK `server` package affords a hook for you to define health checks for +your application and see the results at `/healthz/readiness`. The server also +runs an endpoint at `/healthz/liveness`, which is a conventional name for a +liveness check and is where Kubernetes, if you are using it, will look. + +Health checks are an important part of application monitoring, and readiness +checks are subtly different than liveness checks. The liveness check will return +`200 OK` if the server can serve requests. But because each application may have +a different definition of what it means to be "healthy" (perhaps your +application has a dependency on a back end service), you will need to define a +concrete type to implement the `health.Checker` interface and define a +`CheckHealth` method specific to your application for readiness checks. + +```go +// customHealthCheck is an example health check. It implements the +// health.Checker interface and reports the server is healthy when the healthy +// field is set to true. +type customHealthCheck struct { + mu sync.RWMutex + healthy bool +} + +// customHealthCheck implements the health.Checker interface because it has a +// CheckHealth method. +func (h *customHealthCheck) CheckHealth() error { + h.mu.RLock() + defer h.mu.RUnlock() + if !h.healthy { + return errors.New("not ready yet!") + } + return nil +} +``` + +{{< goexample src="gocloud.dev/server.ExampleServer_withHealthChecks" >}} + +## Other Usage Samples + +* [Minimal server sample](https://github.com/google/go-cloud/tree/master/samples/server) +* [Guestbook sample](https://gocloud.dev/tutorials/guestbook/) diff --git a/go-cloud/internal/website/content/howto/sql/_index.md b/go-cloud/internal/website/content/howto/sql/_index.md new file mode 100644 index 000000000..7c0526b85 --- /dev/null +++ b/go-cloud/internal/website/content/howto/sql/_index.md @@ -0,0 +1,74 @@ +--- +title: "MySQL/PostgreSQL" +date: 2019-06-21T09:26:56-07:00 +showInSidenav: true +toc: true +--- + +Connecting to Cloud providers' hosted database services requires additional +steps to ensure the security of the connection. For example, each of GCP, +AWS and Azure require the use of custom certificate authorities to be +configured in the client. GCP requires a custom proxy with authentication +credentials. The Go CDK makes opening these connections easier while still +using the standard [`*sql.DB`][] type. + +[`*sql.DB`]: https://godoc.org/database/sql#DB + + + +## Local or On-Premise {#local} + +The Go CDK uses the same [URL opener pattern][] as seen in other Go CDK APIs. It +differs from the standard library's `sql.Open` in that it automatically +instruments the connection with [OpenCensus metrics][]. + +The portable function for MySQL is [`mysql.Open`][]: + +{{< goexample "gocloud.dev/mysql.ExampleOpen" >}} + +And the portable function for PostgreSQL is [`postgres.Open`][]: + +{{< goexample "gocloud.dev/postgres.ExampleOpen" >}} + +[`mysql.Open`]: https://godoc.org/gocloud.dev/mysql#Open +[OpenCensus metrics]: https://opencensus.io/integrations/sql/go_sql/ +[`postgres.Open`]: https://godoc.org/gocloud.dev/postgres#Open +[URL opener pattern]: {{< ref "/concepts/urls.md" >}} + +## GCP {#gcp} + +Users of [GCP Cloud SQL for MySQL][] should import the `gocloud.dev/mysql/gcpmysql` package: + +{{< goexample "gocloud.dev/mysql/gcpmysql.Example" >}} + +Users of [GCP Cloud SQL for PostgreSQL][] should import the `gocloud.dev/postgres/gcppostgres` package: + +{{< goexample "gocloud.dev/postgres/gcppostgres.Example" >}} + +[GCP Cloud SQL for MySQL]: https://cloud.google.com/sql/docs/mysql/ +[GCP Cloud SQL for PostgreSQL]: https://cloud.google.com/sql/docs/postgres/ + +## AWS {#aws} + +Users of [AWS RDS for MySQL][] should import the `gocloud.dev/mysql/awsmysql` package: + +{{< goexample "gocloud.dev/mysql/awsmysql.Example" >}} + +Users of [AWS RDS for PostgreSQL][] should import the `gocloud.dev/postgres/awspostgres` package: + +{{< goexample "gocloud.dev/postgres/awspostgres.Example" >}} + +[AWS RDS for MySQL]: https://aws.amazon.com/rds/mysql/ +[AWS RDS for PostgreSQL]: https://aws.amazon.com/rds/postgresql/ + +## Azure {#azure} + +Users of [Azure Database for MySQL][] should import the `gocloud.dev/mysql/azuremysql` package: + +{{< goexample "gocloud.dev/mysql/azuremysql.Example" >}} + +[Azure Database for MySQL]: https://azure.microsoft.com/en-us/services/mysql/ + +## Other Usage Samples + +* [Guestbook sample](https://gocloud.dev/tutorials/guestbook/) diff --git a/go-cloud/internal/website/content/internal/batcher/_index.md b/go-cloud/internal/website/content/internal/batcher/_index.md new file mode 100644 index 000000000..730fab031 --- /dev/null +++ b/go-cloud/internal/website/content/internal/batcher/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/batcher +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/escape/_index.md b/go-cloud/internal/website/content/internal/escape/_index.md new file mode 100644 index 000000000..ff307d2a5 --- /dev/null +++ b/go-cloud/internal/website/content/internal/escape/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/escape +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/gcerr/_index.md b/go-cloud/internal/website/content/internal/gcerr/_index.md new file mode 100644 index 000000000..50cff118b --- /dev/null +++ b/go-cloud/internal/website/content/internal/gcerr/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/gcerr +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/oc/_index.md b/go-cloud/internal/website/content/internal/oc/_index.md new file mode 100644 index 000000000..c33853e97 --- /dev/null +++ b/go-cloud/internal/website/content/internal/oc/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/oc +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/openurl/_index.md b/go-cloud/internal/website/content/internal/openurl/_index.md new file mode 100644 index 000000000..b6334e525 --- /dev/null +++ b/go-cloud/internal/website/content/internal/openurl/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/openurl +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/otel/_index.md b/go-cloud/internal/website/content/internal/otel/_index.md new file mode 100644 index 000000000..68a6e72f7 --- /dev/null +++ b/go-cloud/internal/website/content/internal/otel/_index.md @@ -0,0 +1,6 @@ +--- +title: gocloud.dev/internal/otel +type: pkg +--- + +Package otel provides OpenTelemetry integration for Go Cloud Development Kit, supporting tracing, metrics, and logging. It serves as the primary instrumentation framework, replacing the deprecated OpenCensus implementation. diff --git a/go-cloud/internal/website/content/internal/releasehelper/_index.md b/go-cloud/internal/website/content/internal/releasehelper/_index.md new file mode 100644 index 000000000..f6c63fadd --- /dev/null +++ b/go-cloud/internal/website/content/internal/releasehelper/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/releasehelper +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/retry/_index.md b/go-cloud/internal/website/content/internal/retry/_index.md new file mode 100644 index 000000000..64054cec2 --- /dev/null +++ b/go-cloud/internal/website/content/internal/retry/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/retry +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/testing/_index.md b/go-cloud/internal/website/content/internal/testing/_index.md new file mode 100644 index 000000000..4070b9b40 --- /dev/null +++ b/go-cloud/internal/website/content/internal/testing/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/testing +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/testing/cmdtest/_index.md b/go-cloud/internal/website/content/internal/testing/cmdtest/_index.md new file mode 100644 index 000000000..d7f6f5133 --- /dev/null +++ b/go-cloud/internal/website/content/internal/testing/cmdtest/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/testing/cmdtest +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/testing/octest/_index.md b/go-cloud/internal/website/content/internal/testing/octest/_index.md new file mode 100644 index 000000000..575dc312d --- /dev/null +++ b/go-cloud/internal/website/content/internal/testing/octest/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/testing/octest +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/testing/oteltest/_index.md b/go-cloud/internal/website/content/internal/testing/oteltest/_index.md new file mode 100644 index 000000000..2092677be --- /dev/null +++ b/go-cloud/internal/website/content/internal/testing/oteltest/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/testing/oteltest +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/testing/setup/_index.md b/go-cloud/internal/website/content/internal/testing/setup/_index.md new file mode 100644 index 000000000..21b9fd990 --- /dev/null +++ b/go-cloud/internal/website/content/internal/testing/setup/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/testing/setup +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/testing/terraform/_index.md b/go-cloud/internal/website/content/internal/testing/terraform/_index.md new file mode 100644 index 000000000..b92226e6c --- /dev/null +++ b/go-cloud/internal/website/content/internal/testing/terraform/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/testing/terraform +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/testing/test-summary/_index.md b/go-cloud/internal/website/content/internal/testing/test-summary/_index.md new file mode 100644 index 000000000..7c1984feb --- /dev/null +++ b/go-cloud/internal/website/content/internal/testing/test-summary/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/testing/test-summary +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/trace/_index.md b/go-cloud/internal/website/content/internal/trace/_index.md new file mode 100644 index 000000000..fd0b3f572 --- /dev/null +++ b/go-cloud/internal/website/content/internal/trace/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/trace +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/useragent/_index.md b/go-cloud/internal/website/content/internal/useragent/_index.md new file mode 100644 index 000000000..037d112dc --- /dev/null +++ b/go-cloud/internal/website/content/internal/useragent/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/useragent +type: pkg +--- diff --git a/go-cloud/internal/website/content/internal/website/gatherexamples/_index.md b/go-cloud/internal/website/content/internal/website/gatherexamples/_index.md new file mode 100644 index 000000000..03c85e7fe --- /dev/null +++ b/go-cloud/internal/website/content/internal/website/gatherexamples/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/website/gatherexamples +type: pkg +--- diff --git a/go-cloud/internal/website/content/mysql/_index.md b/go-cloud/internal/website/content/mysql/_index.md new file mode 100644 index 000000000..ffad9c710 --- /dev/null +++ b/go-cloud/internal/website/content/mysql/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/mysql +type: pkg +--- diff --git a/go-cloud/internal/website/content/mysql/awsmysql/_index.md b/go-cloud/internal/website/content/mysql/awsmysql/_index.md new file mode 100644 index 000000000..445ca1209 --- /dev/null +++ b/go-cloud/internal/website/content/mysql/awsmysql/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/mysql/awsmysql +type: pkg +--- diff --git a/go-cloud/internal/website/content/mysql/azuremysql/_index.md b/go-cloud/internal/website/content/mysql/azuremysql/_index.md new file mode 100644 index 000000000..2c88d61da --- /dev/null +++ b/go-cloud/internal/website/content/mysql/azuremysql/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/mysql/azuremysql +type: pkg +--- diff --git a/go-cloud/internal/website/content/mysql/cloudmysql/_index.md b/go-cloud/internal/website/content/mysql/cloudmysql/_index.md new file mode 100644 index 000000000..57da55634 --- /dev/null +++ b/go-cloud/internal/website/content/mysql/cloudmysql/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/mysql/cloudmysql +type: pkg +--- diff --git a/go-cloud/internal/website/content/mysql/gcpmysql/_index.md b/go-cloud/internal/website/content/mysql/gcpmysql/_index.md new file mode 100644 index 000000000..f081324ef --- /dev/null +++ b/go-cloud/internal/website/content/mysql/gcpmysql/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/mysql/gcpmysql +type: pkg +--- diff --git a/go-cloud/internal/website/content/mysql/rdsmysql/_index.md b/go-cloud/internal/website/content/mysql/rdsmysql/_index.md new file mode 100644 index 000000000..ad7def64f --- /dev/null +++ b/go-cloud/internal/website/content/mysql/rdsmysql/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/mysql/rdsmysql +type: pkg +--- diff --git a/go-cloud/internal/website/content/postgres/_index.md b/go-cloud/internal/website/content/postgres/_index.md new file mode 100644 index 000000000..550e158bc --- /dev/null +++ b/go-cloud/internal/website/content/postgres/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/postgres +type: pkg +--- diff --git a/go-cloud/internal/website/content/postgres/awspostgres/_index.md b/go-cloud/internal/website/content/postgres/awspostgres/_index.md new file mode 100644 index 000000000..2beffcb0a --- /dev/null +++ b/go-cloud/internal/website/content/postgres/awspostgres/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/postgres/awspostgres +type: pkg +--- diff --git a/go-cloud/internal/website/content/postgres/cloudpostgres/_index.md b/go-cloud/internal/website/content/postgres/cloudpostgres/_index.md new file mode 100644 index 000000000..f751a0ff9 --- /dev/null +++ b/go-cloud/internal/website/content/postgres/cloudpostgres/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/postgres/cloudpostgres +type: pkg +--- diff --git a/go-cloud/internal/website/content/postgres/gcppostgres/_index.md b/go-cloud/internal/website/content/postgres/gcppostgres/_index.md new file mode 100644 index 000000000..908b11153 --- /dev/null +++ b/go-cloud/internal/website/content/postgres/gcppostgres/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/postgres/gcppostgres +type: pkg +--- diff --git a/go-cloud/internal/website/content/postgres/rdspostgres/_index.md b/go-cloud/internal/website/content/postgres/rdspostgres/_index.md new file mode 100644 index 000000000..aa1442fee --- /dev/null +++ b/go-cloud/internal/website/content/postgres/rdspostgres/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/postgres/rdspostgres +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/_index.md b/go-cloud/internal/website/content/pubsub/_index.md new file mode 100644 index 000000000..033a254c8 --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/pubsub +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/awssnssqs/_index.md b/go-cloud/internal/website/content/pubsub/awssnssqs/_index.md new file mode 100644 index 000000000..ae6fc9690 --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/awssnssqs/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/pubsub/awssnssqs +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/azurepubsub/_index.md b/go-cloud/internal/website/content/pubsub/azurepubsub/_index.md new file mode 100644 index 000000000..3032ec6c5 --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/azurepubsub/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/pubsub/azurepubsub +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/azuresb/_index.md b/go-cloud/internal/website/content/pubsub/azuresb/_index.md new file mode 100644 index 000000000..b6ff99eec --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/azuresb/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/pubsub/azuresb +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/batcher/_index.md b/go-cloud/internal/website/content/pubsub/batcher/_index.md new file mode 100644 index 000000000..730fab031 --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/batcher/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/internal/batcher +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/driver/_index.md b/go-cloud/internal/website/content/pubsub/driver/_index.md new file mode 100644 index 000000000..154a5f48b --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/driver/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/pubsub/driver +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/drivertest/_index.md b/go-cloud/internal/website/content/pubsub/drivertest/_index.md new file mode 100644 index 000000000..cfdd18156 --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/drivertest/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/pubsub/drivertest +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/gcppubsub/_index.md b/go-cloud/internal/website/content/pubsub/gcppubsub/_index.md new file mode 100644 index 000000000..dfb16f695 --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/gcppubsub/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/pubsub/gcppubsub +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/kafkapubsub/_index.md b/go-cloud/internal/website/content/pubsub/kafkapubsub/_index.md new file mode 100644 index 000000000..7267d234f --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/kafkapubsub/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/pubsub/kafkapubsub +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/mempubsub/_index.md b/go-cloud/internal/website/content/pubsub/mempubsub/_index.md new file mode 100644 index 000000000..9f5f7f0ea --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/mempubsub/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/pubsub/mempubsub +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/natspubsub/_index.md b/go-cloud/internal/website/content/pubsub/natspubsub/_index.md new file mode 100644 index 000000000..14a368475 --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/natspubsub/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/pubsub/natspubsub +type: pkg +--- diff --git a/go-cloud/internal/website/content/pubsub/rabbitpubsub/_index.md b/go-cloud/internal/website/content/pubsub/rabbitpubsub/_index.md new file mode 100644 index 000000000..7533e22fc --- /dev/null +++ b/go-cloud/internal/website/content/pubsub/rabbitpubsub/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/pubsub/rabbitpubsub +type: pkg +--- diff --git a/go-cloud/internal/website/content/requestlog/_index.md b/go-cloud/internal/website/content/requestlog/_index.md new file mode 100644 index 000000000..75a10d5db --- /dev/null +++ b/go-cloud/internal/website/content/requestlog/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/requestlog +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/_index.md b/go-cloud/internal/website/content/runtimevar/_index.md new file mode 100644 index 000000000..9cf283508 --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/awsparamstore/_index.md b/go-cloud/internal/website/content/runtimevar/awsparamstore/_index.md new file mode 100644 index 000000000..2481cab5b --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/awsparamstore/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/awsparamstore +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/awssecretsmanager/_index.md b/go-cloud/internal/website/content/runtimevar/awssecretsmanager/_index.md new file mode 100644 index 000000000..91b4d6ca1 --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/awssecretsmanager/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/awssecretsmanager +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/blobvar/_index.md b/go-cloud/internal/website/content/runtimevar/blobvar/_index.md new file mode 100644 index 000000000..bcc1a474e --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/blobvar/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/blobvar +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/constantvar/_index.md b/go-cloud/internal/website/content/runtimevar/constantvar/_index.md new file mode 100644 index 000000000..3e87ce271 --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/constantvar/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/constantvar +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/driver/_index.md b/go-cloud/internal/website/content/runtimevar/driver/_index.md new file mode 100644 index 000000000..40bb5679b --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/driver/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/driver +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/drivertest/_index.md b/go-cloud/internal/website/content/runtimevar/drivertest/_index.md new file mode 100644 index 000000000..ebe1a2389 --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/drivertest/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/drivertest +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/etcdvar/_index.md b/go-cloud/internal/website/content/runtimevar/etcdvar/_index.md new file mode 100644 index 000000000..56df10550 --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/etcdvar/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/etcdvar +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/filevar/_demo/_index.md b/go-cloud/internal/website/content/runtimevar/filevar/_demo/_index.md new file mode 100644 index 000000000..6ad7ad45c --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/filevar/_demo/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/filevar/_demo +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/filevar/_index.md b/go-cloud/internal/website/content/runtimevar/filevar/_index.md new file mode 100644 index 000000000..0514836c0 --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/filevar/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/filevar +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/gcpruntimeconfig/_index.md b/go-cloud/internal/website/content/runtimevar/gcpruntimeconfig/_index.md new file mode 100644 index 000000000..0120ad99c --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/gcpruntimeconfig/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/gcpruntimeconfig +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/gcpsecretmanager/_index.md b/go-cloud/internal/website/content/runtimevar/gcpsecretmanager/_index.md new file mode 100644 index 000000000..881de3a67 --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/gcpsecretmanager/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/gcpsecretmanager +type: pkg +--- diff --git a/go-cloud/internal/website/content/runtimevar/httpvar/_index.md b/go-cloud/internal/website/content/runtimevar/httpvar/_index.md new file mode 100644 index 000000000..5cffb24a3 --- /dev/null +++ b/go-cloud/internal/website/content/runtimevar/httpvar/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/runtimevar/httpvar +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/appengine/_index.md b/go-cloud/internal/website/content/samples/appengine/_index.md new file mode 100644 index 000000000..1560fe919 --- /dev/null +++ b/go-cloud/internal/website/content/samples/appengine/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/appengine +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/gocdk-blob/_index.md b/go-cloud/internal/website/content/samples/gocdk-blob/_index.md new file mode 100644 index 000000000..29a8b4f3b --- /dev/null +++ b/go-cloud/internal/website/content/samples/gocdk-blob/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/gocdk-blob +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/gocdk-docstore/_index.md b/go-cloud/internal/website/content/samples/gocdk-docstore/_index.md new file mode 100644 index 000000000..b0a60721f --- /dev/null +++ b/go-cloud/internal/website/content/samples/gocdk-docstore/_index.md @@ -0,0 +1,8 @@ +--- +title: "Gocdk Docstore" +date: 2019-06-11T14:33:50-07:00 +showInSidenav: false # only for sections (any level) +pagesInSidenav: false # only for top-level sections +weight: 0 +--- + diff --git a/go-cloud/internal/website/content/samples/gocdk-pubsub/_index.md b/go-cloud/internal/website/content/samples/gocdk-pubsub/_index.md new file mode 100644 index 000000000..d6016a29e --- /dev/null +++ b/go-cloud/internal/website/content/samples/gocdk-pubsub/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/gocdk-pubsub +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/gocdk-runtimevar/_index.md b/go-cloud/internal/website/content/samples/gocdk-runtimevar/_index.md new file mode 100644 index 000000000..9668e8053 --- /dev/null +++ b/go-cloud/internal/website/content/samples/gocdk-runtimevar/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/gocdk-runtimevar +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/gocdk-secrets/_index.md b/go-cloud/internal/website/content/samples/gocdk-secrets/_index.md new file mode 100644 index 000000000..72b105bff --- /dev/null +++ b/go-cloud/internal/website/content/samples/gocdk-secrets/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/gocdk-secrets +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/guestbook/_index.md b/go-cloud/internal/website/content/samples/guestbook/_index.md new file mode 100644 index 000000000..41eabaf68 --- /dev/null +++ b/go-cloud/internal/website/content/samples/guestbook/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/guestbook +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/guestbook/aws/provision_db/_index.md b/go-cloud/internal/website/content/samples/guestbook/aws/provision_db/_index.md new file mode 100644 index 000000000..becf8ad93 --- /dev/null +++ b/go-cloud/internal/website/content/samples/guestbook/aws/provision_db/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/guestbook/aws/provision_db +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/guestbook/gcp/deploy/_index.md b/go-cloud/internal/website/content/samples/guestbook/gcp/deploy/_index.md new file mode 100644 index 000000000..8f1aed794 --- /dev/null +++ b/go-cloud/internal/website/content/samples/guestbook/gcp/deploy/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/guestbook/gcp/deploy +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/guestbook/gcp/provision_db/_index.md b/go-cloud/internal/website/content/samples/guestbook/gcp/provision_db/_index.md new file mode 100644 index 000000000..5f8370142 --- /dev/null +++ b/go-cloud/internal/website/content/samples/guestbook/gcp/provision_db/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/guestbook/gcp/provision_db +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/guestbook/localdb/_index.md b/go-cloud/internal/website/content/samples/guestbook/localdb/_index.md new file mode 100644 index 000000000..1585e704e --- /dev/null +++ b/go-cloud/internal/website/content/samples/guestbook/localdb/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/guestbook/localdb +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/order/_index.md b/go-cloud/internal/website/content/samples/order/_index.md new file mode 100644 index 000000000..23ada2a4e --- /dev/null +++ b/go-cloud/internal/website/content/samples/order/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/order +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/server/_index.md b/go-cloud/internal/website/content/samples/server/_index.md new file mode 100644 index 000000000..d9037c350 --- /dev/null +++ b/go-cloud/internal/website/content/samples/server/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/server +type: pkg +--- diff --git a/go-cloud/internal/website/content/samples/tutorial/_index.md b/go-cloud/internal/website/content/samples/tutorial/_index.md new file mode 100644 index 000000000..b92cc5e09 --- /dev/null +++ b/go-cloud/internal/website/content/samples/tutorial/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/samples/tutorial +type: pkg +--- diff --git a/go-cloud/internal/website/content/secrets/_index.md b/go-cloud/internal/website/content/secrets/_index.md new file mode 100644 index 000000000..86612d1ec --- /dev/null +++ b/go-cloud/internal/website/content/secrets/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/secrets +type: pkg +--- diff --git a/go-cloud/internal/website/content/secrets/awskms/_index.md b/go-cloud/internal/website/content/secrets/awskms/_index.md new file mode 100644 index 000000000..7cacc9edd --- /dev/null +++ b/go-cloud/internal/website/content/secrets/awskms/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/secrets/awskms +type: pkg +--- diff --git a/go-cloud/internal/website/content/secrets/azurekeyvault/_index.md b/go-cloud/internal/website/content/secrets/azurekeyvault/_index.md new file mode 100644 index 000000000..72a1905c4 --- /dev/null +++ b/go-cloud/internal/website/content/secrets/azurekeyvault/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/secrets/azurekeyvault +type: pkg +--- diff --git a/go-cloud/internal/website/content/secrets/driver/_index.md b/go-cloud/internal/website/content/secrets/driver/_index.md new file mode 100644 index 000000000..2076b0385 --- /dev/null +++ b/go-cloud/internal/website/content/secrets/driver/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/secrets/driver +type: pkg +--- diff --git a/go-cloud/internal/website/content/secrets/drivertest/_index.md b/go-cloud/internal/website/content/secrets/drivertest/_index.md new file mode 100644 index 000000000..f3b73286c --- /dev/null +++ b/go-cloud/internal/website/content/secrets/drivertest/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/secrets/drivertest +type: pkg +--- diff --git a/go-cloud/internal/website/content/secrets/gcpkms/_index.md b/go-cloud/internal/website/content/secrets/gcpkms/_index.md new file mode 100644 index 000000000..fe3e4e8c6 --- /dev/null +++ b/go-cloud/internal/website/content/secrets/gcpkms/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/secrets/gcpkms +type: pkg +--- diff --git a/go-cloud/internal/website/content/secrets/hashivault/_index.md b/go-cloud/internal/website/content/secrets/hashivault/_index.md new file mode 100644 index 000000000..53178c509 --- /dev/null +++ b/go-cloud/internal/website/content/secrets/hashivault/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/secrets/hashivault +type: pkg +--- diff --git a/go-cloud/internal/website/content/secrets/localsecrets/_index.md b/go-cloud/internal/website/content/secrets/localsecrets/_index.md new file mode 100644 index 000000000..7e9a894ee --- /dev/null +++ b/go-cloud/internal/website/content/secrets/localsecrets/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/secrets/localsecrets +type: pkg +--- diff --git a/go-cloud/internal/website/content/secrets/vault/_index.md b/go-cloud/internal/website/content/secrets/vault/_index.md new file mode 100644 index 000000000..8ad370e99 --- /dev/null +++ b/go-cloud/internal/website/content/secrets/vault/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/secrets/vault +type: pkg +--- diff --git a/go-cloud/internal/website/content/server/_index.md b/go-cloud/internal/website/content/server/_index.md new file mode 100644 index 000000000..144297910 --- /dev/null +++ b/go-cloud/internal/website/content/server/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/server +type: pkg +--- diff --git a/go-cloud/internal/website/content/server/driver/_index.md b/go-cloud/internal/website/content/server/driver/_index.md new file mode 100644 index 000000000..b5db06db1 --- /dev/null +++ b/go-cloud/internal/website/content/server/driver/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/server/driver +type: pkg +--- diff --git a/go-cloud/internal/website/content/server/health/_index.md b/go-cloud/internal/website/content/server/health/_index.md new file mode 100644 index 000000000..3bb8b3891 --- /dev/null +++ b/go-cloud/internal/website/content/server/health/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/server/health +type: pkg +--- diff --git a/go-cloud/internal/website/content/server/health/sqlhealth/_index.md b/go-cloud/internal/website/content/server/health/sqlhealth/_index.md new file mode 100644 index 000000000..2285d8abe --- /dev/null +++ b/go-cloud/internal/website/content/server/health/sqlhealth/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/server/health/sqlhealth +type: pkg +--- diff --git a/go-cloud/internal/website/content/server/requestlog/_index.md b/go-cloud/internal/website/content/server/requestlog/_index.md new file mode 100644 index 000000000..21504a47d --- /dev/null +++ b/go-cloud/internal/website/content/server/requestlog/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/server/requestlog +type: pkg +--- diff --git a/go-cloud/internal/website/content/server/sdserver/_index.md b/go-cloud/internal/website/content/server/sdserver/_index.md new file mode 100644 index 000000000..81e2632b7 --- /dev/null +++ b/go-cloud/internal/website/content/server/sdserver/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/server/sdserver +type: pkg +--- diff --git a/go-cloud/internal/website/content/server/xrayserver/_index.md b/go-cloud/internal/website/content/server/xrayserver/_index.md new file mode 100644 index 000000000..ceb68f6f9 --- /dev/null +++ b/go-cloud/internal/website/content/server/xrayserver/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/server/xrayserver +type: pkg +--- diff --git a/go-cloud/internal/website/content/tests/aws/app/_index.md b/go-cloud/internal/website/content/tests/aws/app/_index.md new file mode 100644 index 000000000..6f308baff --- /dev/null +++ b/go-cloud/internal/website/content/tests/aws/app/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/tests/aws/app +type: pkg +--- diff --git a/go-cloud/internal/website/content/tests/gcp/app/_index.md b/go-cloud/internal/website/content/tests/gcp/app/_index.md new file mode 100644 index 000000000..54d26d036 --- /dev/null +++ b/go-cloud/internal/website/content/tests/gcp/app/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/tests/gcp/app +type: pkg +--- diff --git a/go-cloud/internal/website/content/tests/internal/testutil/_index.md b/go-cloud/internal/website/content/tests/internal/testutil/_index.md new file mode 100644 index 000000000..d3e01212b --- /dev/null +++ b/go-cloud/internal/website/content/tests/internal/testutil/_index.md @@ -0,0 +1,4 @@ +--- +title: gocloud.dev/tests/internal/testutil +type: pkg +--- diff --git a/go-cloud/internal/website/content/tutorials/_index.md b/go-cloud/internal/website/content/tutorials/_index.md new file mode 100644 index 000000000..2a8094d4d --- /dev/null +++ b/go-cloud/internal/website/content/tutorials/_index.md @@ -0,0 +1,8 @@ +--- +title: "Tutorials" +date: 2019-03-19T18:45:15-07:00 +showInSidenav: true +pagesInSidenav: true +weight: 1 +--- + diff --git a/go-cloud/internal/website/content/tutorials/cli-uploader.md b/go-cloud/internal/website/content/tutorials/cli-uploader.md new file mode 100644 index 000000000..84d7e16ba --- /dev/null +++ b/go-cloud/internal/website/content/tutorials/cli-uploader.md @@ -0,0 +1,251 @@ +--- +title: "Tutorial: Command-Line Uploader" +linkTitle: "Command-Line Uploader" +date: 2019-03-19T18:45:53-07:00 +weight: 1 +--- + +This quickstart will build a command line application called `upload` that +uploads files to blob storage on GCP, AWS, and Azure. Blob storage stores binary +data under a string key, and is one of the most frequently used cloud +services. + + + +When we're done, our command line application will work like this: + +```shell +# uploads gopher.png to GCS +$ ./upload gs://go-cloud-bucket gopher.png + +# uploads gopher.png to S3 +$ ./upload s3://go-cloud-bucket gopher.png + +# uploads gopher.png to Azure +$ ./upload azblob://go-cloud-bucket gopher.png +``` + +(You can download the finished tutorial [from GitHub][samples/tutorial]). + +[samples/tutorial]: https://github.com/google/go-cloud/tree/master/samples/tutorial/ + +## Setup + +We start with a skeleton for our program to read from command-line +arguments to configure the bucket URL. + +```go +// Command upload saves files to blob storage on GCP, AWS, and Azure. +package main + +import ( + "log" + "os" +) + +func main() { + // Define our input. + if len(os.Args) != 3 { + log.Fatal("usage: upload BUCKET_URL FILE") + } + bucketURL := os.Args[1] + file := os.Args[2] + _, _ = bucketURL, file +} +``` + +Now that we have a basic skeleton in place, let's start filling in the pieces. + +## Connecting to the bucket + +The easiest way to open a portable bucket API is with `blob.OpenBucket`. + +```go +package main + +import ( + // previous imports omitted + + "gocloud.dev/blob" +) + +func main() { + // previous code omitted + + // Open a connection to the bucket. + b, err := blob.OpenBucket(context.Background(), bucketURL) + if err != nil { + log.Fatalf("Failed to setup bucket: %s", err) + } + defer b.Close() +} +``` + +This is all we need in the `main` function to connect to the bucket. However, +as written, this function call will always fail: the Go CDK does not link in any +cloud-specific implementations of `blob.OpenBucket` unless you specifically +depend on them. This ensures you're only depending on the code you need. +To link in implementations, use blank imports: + +```go +package main + +import ( + // previous imports omitted + + // Import the blob packages we want to be able to open. + _ "gocloud.dev/blob/azureblob" + _ "gocloud.dev/blob/gcsblob" + _ "gocloud.dev/blob/s3blob" +) + +func main() { + // ... +} +``` + +With the setup done, we're ready to use the bucket connection. Note, as a design +principle of the Go CDK, `blob.Bucket` does not support creating a bucket and +instead focuses solely on interacting with it. This separates the concerns of +provisioning infrastructure and using infrastructure. + +## Reading the file + +We need to read our file into a slice of bytes before uploading it. The process +is the usual one: + +```go +package main + +import ( + // previous imports omitted + "os" + "io/ioutil" +) + +func main() { + // ... previous code omitted + + // Prepare the file for upload. + data, err := os.ReadFile(file) + if err != nil { + log.Fatalf("Failed to read file: %s", err) + } +} +``` + +## Writing the file to the bucket + +Now, we have `data`, our file in a slice of bytes. Let's get to the fun part and +write those bytes to the bucket! + +```go +package main + +// No new imports. + +func main() { + // ... + + w, err := b.NewWriter(ctx, file, nil) + if err != nil { + log.Fatalf("Failed to obtain writer: %s", err) + } + _, err = w.Write(data) + if err != nil { + log.Fatalf("Failed to write to bucket: %s", err) + } + if err := w.Close(); err != nil { + log.Fatalf("Failed to close: %s", err) + } +} +``` + +First, we create a writer based on the bucket connection. In addition to a +`context.Context` type, the method takes the key under which the data will be +stored and the mime type of the data. + +The call to `NewWriter` creates a `blob.Writer`, which implements `io.Writer`. +With the writer, we call `Write` passing in the data. In response, we get the +number of bytes written and any error that might have occurred. + +Finally, we close the writer with `Close` and check the error. + +Alternatively, we could have used the shortcut `b.WriteAll(ctx, file, data, +nil)`. + +## Uploading an image + +That's it! Let's try it out. As setup, we will need to create a +[GCS bucket][gcs-bucket], an [S3 bucket][s3-bucket], and an +[Azure container][azure-container]. In the code above, I called that bucket +`go-cloud-bucket`, but you can change that to match whatever your bucket is +called. Of course, you are free to try the code on any subset of Cloud +providers. + +* For GCP, you will need to login with + [gcloud](https://cloud.google.com/sdk/install). If you do not want to + install `gcloud`, see + [here](https://cloud.google.com/docs/authentication/production) for + alternatives. +* For AWS, you will need an access key ID and a secret access key. See + [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey) + for details. You then need to set the `AWS_REGION` environment variable to + the region your bucket is in. +* For Azure, you will need to add your storage account name and key as + environment variables (`AZURE_STORAGE_ACCOUNT` and + `AZURE_STORAGE_KEY`, respectively). See + [here](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-portal) + for details. + +With our buckets created and our credentials set up, we'll build the program +first: + +```shell +$ go build -o upload +``` + +Then, we will send `gopher.png` (in the same directory as this README) to GCS: + +```shell +$ ./upload gs://go-cloud-bucket gopher.png +``` + +Then, we send that same gopher to S3: + +```shell +$ ./upload s3://go-cloud-bucket?region=us-west-1 gopher.png +``` + +Finally, we send that same gopher to Azure: + +```shell +$ ./upload azblob://go-cloud-bucket gopher.png +``` + +If we check the buckets, we should see our gopher in each of them! We're done! + +[s3-bucket]: https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html +[gcs-bucket]: https://cloud.google.com/storage/docs/creating-buckets +[azure-container]: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction + +## Wrapping Up + +In conclusion, we have a program that can seamlessly switch between multiple +Cloud storage providers using just one code path. You can see the finished +tutorial [on GitHub][samples/tutorial]. + +We hope this example demonstrates how having one type for multiple clouds is a +huge win for simplicity and maintainability. By writing an application using a +generic interface like `*blob.Bucket`, we retain the option of using +infrastructure in whichever cloud that best fits our needs all without having to +worry about a rewrite. If you want to learn more, you can read about +[Structuring Portable Code][]. + +If you want to see how to deploy a Go CDK application, see [other tutorials][]. +If you want to see how to use Go CDK APIs in your application, see the +[how-to guides][]. + +[how-to guides]: {{< ref "/howto/_index.md" >}} +[other tutorials]: {{< ref "/tutorials/_index.md" >}} +[Structuring Portable Code]: {{< ref "/concepts/structure/index.md" >}} diff --git a/go-cloud/internal/website/content/tutorials/guestbook.md b/go-cloud/internal/website/content/tutorials/guestbook.md new file mode 100644 index 000000000..3a8e22e41 --- /dev/null +++ b/go-cloud/internal/website/content/tutorials/guestbook.md @@ -0,0 +1,302 @@ +--- +title: "Tutorial: Guestbook Application" +linkTitle: "Guestbook" +date: 2019-07-10T16:58:00-07:00 +weight: 2 +toc: true +--- + +In this tutorial, we will deploy an existing Go CDK application called Guestbook +locally, then on Google Cloud Platform (GCP), Amazon Web Services (AWS), and +Azure. + + + +Guestbook is a sample application that records visitors' messages and displays a +cloud banner with an administrative message. The main business logic is written +in a cloud-agnostic manner using MySQL, the generic blob API, and the generic +runtimevar API. All platform-specific code is set up by +[Wire](https://github.com/google/wire). + +## Prerequisites + +You will need to install the following software for this tutorial: + +- [Git](https://git-scm.com/) +- [Go](https://golang.org/doc/install) +- [Wire](https://github.com/google/wire/blob/master/README.md#installing) +- [Docker Desktop](https://docs.docker.com/install/) +- [Terraform](https://www.terraform.io/intro/getting-started/install.html) + +### Cloning the Sample + +Before you can do anything else, you need to clone the Go CDK repository. The +repository contains the Guestbook sample. + +```shell +git clone https://github.com/google/go-cloud.git +cd go-cloud/samples/guestbook +``` + +## Building + +Run the following in the `samples/guestbook` directory: + +```shell +go generate && go build +``` + +## Running Locally + +You will need to run a local MySQL database server and create a local message of +the day. `localdb/main.go` runs the local MySQL database server using Docker: + +```shell +go get ./localdb/... # Get package dependencies. +go run localdb/main.go +``` + +In another terminal, run the `guestbook` application: + +```shell +# Set a local Message of the Day. +echo 'Hello, World!' > motd.txt + +# Run the server. +# For blob, it uses fileblob, pointing at the local directory ./blobs. +# For runtimevar, it uses filevar, pointing at the local file ./motd.txt. +# You can update the ./motd.txt while the server is running, refresh +# the page, and see it change. +./guestbook -env=local -bucket=blobs -motd_var=motd.txt +``` + +Your server is now running on http://localhost:8080/. + +You can stop the MySQL database server with Ctrl-\\. MySQL ignores Ctrl-C +(SIGINT). + +## Running on Google Cloud Platform (GCP) + +If you want to run this sample on GCP, you need to create a project, download +the [gcloud CLI][], install `kubectl` and log in. + +[gcloud CLI]: https://cloud.google.com/sdk/downloads + +```shell +# Install kubectl. +gcloud components install kubectl + +# Opens a browser to log you into GCP. +gcloud auth login +``` + +### Provision resources + +You can now use Terraform to set up your project. + +```shell +gcloud auth application-default login +cd gcp +terraform init + +# Terraform will prompt you for your GCP project ID, desired region, +# and desired zone. +terraform apply +``` + +### Deploy the application + +This sample provides a script for building the Guestbook binary and deploying it +to the Kubernetes cluster created by Terraform. + +```shell +go run deploy/main.go +``` + +The deploy script will display the URL of your running service. + +### Cleanup + +To clean up the created resources, run `terraform destroy` inside the `gcp` +directory using the same variables you entered during `terraform apply`. + +## Running on Amazon Web Services (AWS) + +If you want to run this sample on AWS, you need to set up an account, download +the [AWS command line interface][], and log in. There's +[help here][AWS Config Help] if you need it. + +```shell +aws configure +``` + +[AWS command line interface]: https://docs.aws.amazon.com/cli/latest/userguide/installing.html +[AWS Config Help]: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html + +### Agree to the Debian Terms and Conditions + +You have to agree to the [Debian Terms and Conditions][] in order to provision +the resources. Click through the "Continue to Subscribe" button at the top, then +log in to your AWS account and subscribe to Debian. + +[Debian Terms and Conditions]: https://aws.amazon.com/marketplace/pp?sku=55q52qvgjfpdj2fpfy9mb1lo4 + +### SSH Key + +You will also need an SSH key to SSH into the EC2 instance. If you don't already +have one, you can follow [this guide from GitHub][GitHub SSH]. Follow the +instructions for "Adding your key to the ssh-agent" if you want the key to +persist across terminal sessions. + +```shell +ssh-add +``` + +[GitHub SSH]: https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/ + +### Provision resources + +You can now use Terraform to set up your project. This will create an EC2 +instance you can SSH to and run your binary. + +```shell +# Build for deploying on the AWS Linux VM. +GOOS=linux GOARCH=amd64 go build + +# Enter AWS directory from samples/guestbook. +cd aws +terraform init + +# Provisioning can take up to 10 minutes. +# Keep track of the output of this command as it is needed later. +# You can replace us-west-1 with whatever region you want. +terraform apply -var region=us-west-1 -var ssh_public_key="$(cat ~/.ssh/id_rsa.pub)" +``` + +### Deploy the application + +You now need to connect to the new remote server to execute the `guestbook` +binary. The final output of `terraform apply` lists the variables `guestbook` +requires as arguments. Here's an example, with actual strings replaced with +`[redacted]`: + +```shell +# Output from "terraform apply" command.... + + +Outputs: + +bucket = [redacted] +database_host = [redacted] +database_root_password = +instance_host = [redacted] +paramstore_var = /guestbook/motd +region = us-west-1 + +# Print out the database root password, since we'll need it below +# Terraform hides it by default in the Outputs above. +localhost$ terraform output database_root_password +[redacted] + +# SSH into the EC2 instance. +localhost$ ssh "admin@$( terraform output instance_host )" + +# Fill in each command-line argument with the values from the +# Terraform output above. +server$ AWS_REGION= ./guestbook \ + -env=aws \ + -bucket= \ + -db_host= \ + -db_user=root \ + -db_password= \ + -motd_var=/guestbook/motd +``` + +You can now visit the server at `http://:8080/`. + +### Cleanup + +To clean up the created resources, run `terraform destroy` inside the `aws` +directory using the same variables you entered during `terraform apply`. + +## Running on Azure + +The Go CDK doesn't have support for SQL on Azure yet ([#1305][]), so we'll run +MySQL and the binary locally. This tutorial will show how to use Azure storage +for the MOTD and Gopher logo. + +You first need to set up an Azure account and install the [Azure CLI][]. Then, +use the `az` CLI to log in. + +[#1305]: https://github.com/google/go-cloud/issues/1305 +[Azure CLI]: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest + +```shell +az login +``` + +### Provision resources + +We'll use Terraform to set up your project. + +```shell +# Enter the Azure directory from samples/guestbook. +cd azure +terraform init + +# Provisioning can take up to 10 minutes. +# Keep track of the output of this command as it is needed later. +terraform apply -var location="West US" + + +Outputs: + +access_key = [redacted] +storage_account = [redacated] +storage_container = [redacted] +``` + +### Deploy the application + +You will need to run a local MySQL database server, similar to what we did for +running locally earlier. Open a new terminal window, and run: + +```shell +cd .. # back up to samples/guestbook +go get ./localdb/... # Get package dependencies. +go run localdb/main.go +``` + +In the original terminal, add your Azure credentials to the environment and run +the `guestbook` application: + +```shell +# You should be in the "samples/guestbook/azure" directory. + +# Enter the storage_account from the Terraform output earlier. +export AZURE_STORAGE_ACCOUNT= +# Enter the access_key from the Terraform output earlier. +export AZURE_STORAGE_KEY= + +# Run the binary. +# Fill in the -bucket command-line argument with the value from the Terraform +# output. +# +./guestbook -env=azure -bucket= -motd_var=motd +``` + +Your server is now running on http://localhost:8080/. + +You can stop the MySQL database server with Ctrl-\\. MySQL ignores Ctrl-C +(SIGINT). + +### Cleanup + +To clean up the created resources, run `terraform destroy` inside the `azure` +directory using the same variables you entered during `terraform apply`. + +## Gophers + +The Go gopher was designed by Renee French and used under the +[Creative Commons 3.0 Attributions](https://creativecommons.org/licenses/by/3.0/) +license. diff --git a/go-cloud/internal/website/content/tutorials/order.md b/go-cloud/internal/website/content/tutorials/order.md new file mode 100644 index 000000000..4d76a31b2 --- /dev/null +++ b/go-cloud/internal/website/content/tutorials/order.md @@ -0,0 +1,84 @@ +--- +title: "Order Processor" +date: 2019-07-09T10:22:39-04:00 +weight: 5 +toc: true +--- + +In this tutorial, we will run a Go CDK application called Order Processor +on a local machine. + + + +Order Processor is a sample application that lets users place orders to convert +images to PNG format, and to view the results. The main business logic is +written in a cloud-agnostic manner using the generic APIs for blob, pubsub and +docstore. + +The Order Processor application has two parts: a web frontend, and an +image-processing backend called a processor. They communicate over a pubsub +topic, store order information in a docstore collection, and store image files +in a blob bucket. + +## Prerequisites + +You will need to install the following software for this tutorial: + +- [Git](https://git-scm.com/) +- [Go](https://golang.org/doc/install) + +Then you need to clone the Go CDK repository. The +repository contains the Order Processor sample. + +```shell +git clone https://github.com/google/go-cloud.git +cd go-cloud/samples/order +``` + +## Building + +Run the following in the `samples/order` directory: + +```shell +go build +``` + +## Running Locally + +If you run `order` with no arguments, both the frontend and the processor will +run together in the same process. + +```shell +./order +``` +The frontend is now running on http://localhost:10538. + +Visit the home page in your browser and click "Convert an Image". + +Enter an email address (it need not be real) and select any image file from your +computer. Then click Submit. + +Now visit the order list page by returning to the home page and clicking "List +Conversions". It may take a few seconds to process the order (thanks to an +artificial delay in the processor), so refresh the page until you see your order +in the list. + +Then click on the output image link to see the converted image in your browser. + +## Running on a Cloud Provider + +To run the Order Processor application on a cloud provider like Google Cloud +Platform, Amazon AWS or Microsoft Azure, you will have to provision +some resources: + +- A storage bucket, to hold the image files. (See the + [`blob` How-To Guide](https://gocloud.dev/howto/blob/).) +- A Pub/Sub topic and subscription, for requests from the frontend to the + processor. (See the [`pubsub` How-To Guide](https://gocloud.dev/howto/pubsub/).) +- A document store collection to store order metadata. (See the [`docstore` How-To + Guide](https://gocloud.dev/howto/docstore/).) + + +Then launch the `order` program with flags that provide the URLs to your +resources. Run `order -help` to see the list of flags. + diff --git a/go-cloud/internal/website/data/examples.json b/go-cloud/internal/website/data/examples.json new file mode 100644 index 000000000..57165c65c --- /dev/null +++ b/go-cloud/internal/website/data/examples.json @@ -0,0 +1,458 @@ +{ + "gocloud.dev/blob.ExampleBucket_Delete": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/blob\"\n)", + "code": "if err := bucket.Delete(ctx, \"foo.txt\"); err != nil {\n\treturn err\n}" + }, + "gocloud.dev/blob.ExampleBucket_NewRangeReader": { + "imports": "import (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\n\t\"gocloud.dev/blob\"\n)", + "code": "// Open the key \"foo.txt\" for reading at offset 1024 and read up to 4096 bytes.\nr, err := bucket.NewRangeReader(ctx, \"foo.txt\", 1024, 4096, nil)\nif err != nil {\n\treturn err\n}\ndefer r.Close()\n// Copy from the read range to stdout.\nif _, err := io.Copy(os.Stdout, r); err != nil {\n\treturn err\n}" + }, + "gocloud.dev/blob.ExampleBucket_NewReader": { + "imports": "import (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\t\"gocloud.dev/blob\"\n)", + "code": "// Open the key \"foo.txt\" for reading with the default options.\nr, err := bucket.NewReader(ctx, \"foo.txt\", nil)\nif err != nil {\n\treturn err\n}\ndefer r.Close()\n// Readers also have a limited view of the blob's metadata.\nfmt.Println(\"Content-Type:\", r.ContentType())\nfmt.Println()\n// Copy from the reader to stdout.\nif _, err := io.Copy(os.Stdout, r); err != nil {\n\treturn err\n}" + }, + "gocloud.dev/blob.ExampleBucket_NewWriter": { + "imports": "import (\n\t\"context\"\n\t\"fmt\"\n\n\t\"gocloud.dev/blob\"\n)", + "code": "// Open the key \"foo.txt\" for writing with the default options.\nw, err := bucket.NewWriter(ctx, \"foo.txt\", nil)\nif err != nil {\n\treturn err\n}\n_, writeErr := fmt.Fprintln(w, \"Hello, World!\")\n// Always check the return value of Close when writing.\ncloseErr := w.Close()\nif writeErr != nil {\n\tlog.Fatal(writeErr)\n}\nif closeErr != nil {\n\tlog.Fatal(closeErr)\n}" + }, + "gocloud.dev/blob.ExampleBucket_NewWriter_cancel": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/blob\"\n)", + "code": "// Create a cancelable context from the existing context.\nwriteCtx, cancelWrite := context.WithCancel(ctx)\ndefer cancelWrite()\n\n// Open the key \"foo.txt\" for writing with the default options.\nw, err := bucket.NewWriter(writeCtx, \"foo.txt\", nil)\nif err != nil {\n\treturn err\n}\n\n// Assume some writes happened and we encountered an error.\n// Now we want to abort the write.\n\nif err != nil {\n\t// First cancel the context.\n\tcancelWrite()\n\t// You must still close the writer to avoid leaking resources.\n\tw.Close()\n}" + }, + "gocloud.dev/blob.ExamplePrefixedBucket": { + "imports": "import \"gocloud.dev/blob\"", + "code": "// Wrap the bucket using blob.PrefixedBucket.\n// The prefix should end with \"/\", so that the resulting bucket operates\n// in a subfolder.\nbucket = blob.PrefixedBucket(bucket, \"a/subfolder/\")\n\n// The original bucket is no longer usable; it has been closed.\n// The wrapped bucket should be closed when done.\ndefer bucket.Close()\n\n// Bucket operations on \u003ckey\u003e will be translated to \"a/subfolder/\u003ckey\u003e\"." + }, + "gocloud.dev/blob.ExampleSingleKeyBucket": { + "imports": "import \"gocloud.dev/blob\"", + "code": "// Wrap the bucket using blob.SingleKeyBucket.\n// The bucket always references the provided key.\nbucket = blob.SingleKeyBucket(bucket, \"foo.txt\")\n\n// The original bucket is no longer usable; it has been closed.\n// The wrapped bucket should be closed when done.\ndefer bucket.Close()\n\n// Bucket operations will ignore the passed-in key and always reference foo.txt." + }, + "gocloud.dev/blob.Example_openFromURLWithPrefix": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/blob\"\n)", + "code": "// Connect to a bucket using a URL, using the \"prefix\" query parameter to\n// target a subfolder in the bucket.\n// The prefix should end with \"/\", so that the resulting bucket operates\n// in a subfolder.\nb, err := blob.OpenBucket(ctx, \"mem://?prefix=a/subfolder/\")\nif err != nil {\n\treturn err\n}\ndefer b.Close()\n\n// Bucket operations on \u003ckey\u003e will be translated to \"a/subfolder/\u003ckey\u003e\"." + }, + "gocloud.dev/blob.Example_openFromURLWithSingleKey": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/blob\"\n)", + "code": "// Connect to a bucket using a URL, using the \"key\" query parameter to\n// make the bucket always reference that key.\nb, err := blob.OpenBucket(ctx, \"mem://?key=foo.txt\")\nif err != nil {\n\treturn err\n}\ndefer b.Close()\n\n// Bucket operations will ignore the passed-in key and always reference foo.txt." + }, + "gocloud.dev/blob/azureblob.ExampleOpenBucket": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/blob/azureblob\"\n)", + "code": "const (\n\t// The storage container to access.\n\tcontainerName = \"my-container\"\n)\n\n// Construct the service URL.\n// There are many forms of service URLs, see ServiceURLOptions.\nopts := azureblob.NewDefaultServiceURLOptions()\nserviceURL, err := azureblob.NewServiceURL(opts)\nif err != nil {\n\treturn err\n}\n\n// There are many ways to authenticate to Azure.\n// This approach uses environment variables as described in azureblob package\n// documentation.\n// For example, to use shared key authentication, you would set\n// AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_KEY.\n// To use a SAS token, you would set AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_SAS_TOKEN.\n// You can also construct a client using the azblob constructors directly, like\n// azblob.NewServiceClientWithSharedKey.\nclient, err := azureblob.NewDefaultClient(serviceURL, containerName)\nif err != nil {\n\treturn err\n}\n\n// Create a *blob.Bucket.\nb, err := azureblob.OpenBucket(ctx, client, nil)\nif err != nil {\n\treturn err\n}\ndefer b.Close()\n\n// Now we can use b to read or write files to the container.\ndata, err := b.ReadAll(ctx, \"my-key\")\nif err != nil {\n\treturn err\n}\n_ = data" + }, + "gocloud.dev/blob/azureblob.Example_openBucketFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/blob\"\n\t_ \"gocloud.dev/blob/azureblob\"\n)", + "code": "// blob.OpenBucket creates a *blob.Bucket from a URL.\n// This URL will open the container \"my-container\" using default\n// credentials found in environment variables as documented in\n// the package.\n// Assuming AZURE_STORAGE_ACCOUNT is set to \"myaccount\",\n// and other options aren't set, the service URL will look like:\n// \"https://myaccount.blob.core.windows.net/my-container\".\nbucket, err := blob.OpenBucket(ctx, \"azblob://my-container\")\nif err != nil {\n\treturn err\n}\ndefer bucket.Close()\n\n// Another example, against a local emulator.\n// Assuming AZURE_STORAGE_ACCOUNT is set to \"myaccount\",\n// the service URL will look like:\n// \"http://localhost:10001/myaccount/my-container\".\nlocalbucket, err := blob.OpenBucket(ctx, \"azblob://my-container?protocol=http\u0026domain=localhost:10001\")\nif err != nil {\n\treturn err\n}\ndefer localbucket.Close()" + }, + "gocloud.dev/blob/fileblob.ExampleOpenBucket": { + "imports": "import (\n\t\"os\"\n\n\t\"gocloud.dev/blob/fileblob\"\n)", + "code": "// The directory you pass to fileblob.OpenBucket must exist first.\nconst myDir = \"path/to/local/directory\"\nif err := os.MkdirAll(myDir, 0o777); err != nil {\n\treturn err\n}\n\n// Create a file-based bucket.\nbucket, err := fileblob.OpenBucket(myDir, nil)\nif err != nil {\n\treturn err\n}\ndefer bucket.Close()" + }, + "gocloud.dev/blob/gcsblob.ExampleOpenBucket": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/blob/gcsblob\"\n\t\"gocloud.dev/gcp\"\n)", + "code": "// Your GCP credentials.\n// See https://cloud.google.com/docs/authentication/production\n// for more info on alternatives.\ncreds, err := gcp.DefaultCredentials(ctx)\nif err != nil {\n\treturn err\n}\n\n// Create an HTTP client.\n// This example uses the default HTTP transport and the credentials\n// created above.\nclient, err := gcp.NewHTTPClient(\n\tgcp.DefaultTransport(),\n\tgcp.CredentialsTokenSource(creds))\nif err != nil {\n\treturn err\n}\n\n// Create a *blob.Bucket.\nbucket, err := gcsblob.OpenBucket(ctx, client, \"my-bucket\", nil)\nif err != nil {\n\treturn err\n}\ndefer bucket.Close()" + }, + "gocloud.dev/blob/gcsblob.Example_openBucketFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/blob\"\n\t_ \"gocloud.dev/blob/gcsblob\"\n)", + "code": "// blob.OpenBucket creates a *blob.Bucket from a URL.\n// This URL will open the bucket \"my-bucket\" using default credentials.\nbucket, err := blob.OpenBucket(ctx, \"gs://my-bucket\")\nif err != nil {\n\treturn err\n}\ndefer bucket.Close()" + }, + "gocloud.dev/blob/memblob.ExampleOpenBucket": { + "imports": "import (\n\t\"context\"\n\t\"fmt\"\n\n\t\"gocloud.dev/blob/memblob\"\n)", + "code": "// Create an in-memory bucket.\nbucket := memblob.OpenBucket(nil)\ndefer bucket.Close()\n\n// Now we can use bucket to read or write files to the bucket.\nerr := bucket.WriteAll(ctx, \"my-key\", []byte(\"hello world\"), nil)\nif err != nil {\n\treturn err\n}\ndata, err := bucket.ReadAll(ctx, \"my-key\")\nif err != nil {\n\treturn err\n}\nfmt.Println(string(data))\n\n// Output:\n// hello world" + }, + "gocloud.dev/blob/s3blob.ExampleOpenBucket": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/aws/aws-sdk-go-v2/config\"\n\t\"github.com/aws/aws-sdk-go-v2/service/s3\"\n\t\"gocloud.dev/blob/s3blob\"\n)", + "code": "// Establish a AWS Config.\n// See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info.\ncfg, err := config.LoadDefaultConfig(ctx)\nif err != nil {\n\treturn err\n}\n\n// Create a *blob.Bucket.\nclient := s3.NewFromConfig(cfg)\nbucket, err := s3blob.OpenBucket(ctx, client, \"my-bucket\", nil)\nif err != nil {\n\treturn err\n}\ndefer bucket.Close()" + }, + "gocloud.dev/blob/s3blob.Example_openBucketFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/blob\"\n\t_ \"gocloud.dev/blob/s3blob\"\n)", + "code": "// blob.OpenBucket creates a *blob.Bucket from a URL.\nbucket, err := blob.OpenBucket(ctx, \"s3://my-bucket?region=us-west-1\")\nif err != nil {\n\treturn err\n}\ndefer bucket.Close()" + }, + "gocloud.dev/docstore.ExampleCollection_Actions_bulkWrite": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/docstore\"\n)", + "code": "// Build an ActionList to create several new players, then execute it.\n// The actions may happen in any order.\nnewPlayers := []string{\"Pat\", \"Mel\", \"Fran\"}\nactionList := coll.Actions()\nfor _, p := range newPlayers {\n\tactionList.Create(\u0026Player{Name: p, Score: 0})\n}\nif err := actionList.Do(ctx); err != nil {\n\treturn err\n}" + }, + "gocloud.dev/docstore.ExampleCollection_Actions_getAfterWrite": { + "imports": "import (\n\t\"context\"\n\t\"fmt\"\n\n\t\"gocloud.dev/docstore\"\n)", + "code": "// Add a document to the collection, then retrieve it.\n// Because both the Put and the Get refer to the same document,\n// they happen in order.\ngot := Player{Name: \"Pat\"}\nerr := coll.Actions().Put(\u0026Player{Name: \"Pat\", Score: 88}).Get(\u0026got).Do(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(got.Name, got.Score)" + }, + "gocloud.dev/docstore.ExampleCollection_Update": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/docstore\"\n)", + "code": "// Create a player.\npat := \u0026Player{Name: \"Pat\", Score: 0}\nif err := coll.Create(ctx, pat); err != nil {\n\treturn err\n}\n\n// Set the score to a new value.\npat2 := \u0026Player{Name: \"Pat\"}\nerr := coll.Actions().Update(pat, docstore.Mods{\"Score\": 15}).Get(pat2).Do(ctx)\nif err != nil {\n\treturn err\n}\n\n// Increment the score.\nerr = coll.Actions().Update(pat, docstore.Mods{\"Score\": docstore.Increment(5)}).Get(pat2).Do(ctx)\nif err != nil {\n\treturn err\n}" + }, + "gocloud.dev/docstore.ExampleQuery_Get": { + "imports": "import (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"gocloud.dev/docstore\"\n)", + "code": "// Ask for all players with scores at least 20.\niter := coll.Query().Where(\"Score\", \"\u003e=\", 20).OrderBy(\"Score\", docstore.Descending).Get(ctx)\ndefer iter.Stop()\n\n// Query.Get returns an iterator. Call Next on it until io.EOF.\nfor {\n\tvar p Player\n\terr := iter.Next(ctx, \u0026p)\n\tif err == io.EOF {\n\t\tbreak\n\t} else if err != nil {\n\t\treturn err\n\t} else {\n\t\tfmt.Printf(\"%s: %d\\n\", p.Name, p.Score)\n\t}\n}" + }, + "gocloud.dev/docstore.Example_optimisticLocking": { + "imports": "import (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"gocloud.dev/docstore/memdocstore\"\n\t\"gocloud.dev/gcerrors\"\n)", + "code": "coll, err := memdocstore.OpenCollection(\"Name\", nil)\nif err != nil {\n\treturn err\n}\ndefer coll.Close()\n\n// Create a player.\npat := \u0026Player{Name: \"Pat\", Score: 7}\nif err := coll.Create(ctx, pat); err != nil {\n\treturn err\n}\nfmt.Println(pat) // memdocstore revisions are deterministic, so we can check the output.\n\n// Double a player's score. We cannot use Update to multiply, so we use optimistic\n// locking instead.\n\n// We may have to retry a few times; put a time limit on that.\nctx, cancel := context.WithTimeout(ctx, 30*time.Second)\ndefer cancel()\nfor {\n\t// Get the document.\n\tplayer := \u0026Player{Name: \"Pat\"}\n\tif err := coll.Get(ctx, player); err != nil {\n\t\treturn err\n\t}\n\t// player.DocstoreRevision is set to the document's revision.\n\n\t// Modify the document locally.\n\tplayer.Score *= 2\n\n\t// Replace the document. player.DocstoreRevision will be checked against\n\t// the stored document's revision.\n\terr := coll.Replace(ctx, player)\n\tif err != nil {\n\t\tcode := gcerrors.Code(err)\n\t\t// On FailedPrecondition or NotFound, try again.\n\t\tif code == gcerrors.FailedPrecondition || code == gcerrors.NotFound {\n\t\t\tcontinue\n\t\t}\n\t\treturn err\n\t}\n\tfmt.Println(player)\n\tbreak\n}\n\n// Output:\n// \u0026{Pat 7 1}\n// \u0026{Pat 14 2}" + }, + "gocloud.dev/docstore/awsdynamodb.ExampleOpenCollection": { + "imports": "import (\n\t\"github.com/aws/aws-sdk-go/aws/session\"\n\t\"github.com/aws/aws-sdk-go/service/dynamodb\"\n\t\"gocloud.dev/docstore/awsdynamodb\"\n)", + "code": "sess, err := session.NewSession()\nif err != nil {\n\treturn err\n}\ncoll, err := awsdynamodb.OpenCollection(\n\tdynamodb.New(sess), \"docstore-test\", \"partitionKeyField\", \"\", nil)\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/awsdynamodb.Example_openCollectionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/docstore\"\n\t_ \"gocloud.dev/docstore/awsdynamodb\"\n)", + "code": "// docstore.OpenCollection creates a *docstore.Collection from a URL.\ncoll, err := docstore.OpenCollection(ctx, \"dynamodb://my-table?partition_key=name\")\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/awsdynamodb/v2.ExampleOpenCollection": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/aws/aws-sdk-go-v2/config\"\n\t\"github.com/aws/aws-sdk-go-v2/service/dynamodb\"\n\t\"gocloud.dev/docstore/awsdynamodb/v2\"\n)", + "code": "cfg, err := config.LoadDefaultConfig(context.Background())\nif err != nil {\n\treturn err\n}\ncoll, err := awsdynamodb.OpenCollection(\n\tdynamodb.NewFromConfig(cfg), \"docstore-test\", \"partitionKeyField\", \"\", nil)\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/awsdynamodb/v2.Example_openCollectionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/docstore\"\n\t_ \"gocloud.dev/docstore/awsdynamodb\"\n)", + "code": "// docstore.OpenCollection creates a *docstore.Collection from a URL.\ncoll, err := docstore.OpenCollection(ctx, \"dynamodb://my-table?partition_key=name\")\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/gcpfirestore.ExampleOpenCollection": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/docstore/gcpfirestore\"\n\t\"gocloud.dev/gcp\"\n)", + "code": "creds, err := gcp.DefaultCredentials(ctx)\nif err != nil {\n\treturn err\n}\nclient, _, err := gcpfirestore.Dial(ctx, creds.TokenSource)\nif err != nil {\n\treturn err\n}\nresourceID := gcpfirestore.CollectionResourceID(\"my-project\", \"my-collection\")\ncoll, err := gcpfirestore.OpenCollection(client, resourceID, \"userID\", nil)\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/gcpfirestore.ExampleOpenCollectionWithNameFunc": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/docstore\"\n\t\"gocloud.dev/docstore/gcpfirestore\"\n\t\"gocloud.dev/gcp\"\n)", + "code": "creds, err := gcp.DefaultCredentials(ctx)\nif err != nil {\n\treturn err\n}\nclient, _, err := gcpfirestore.Dial(ctx, creds.TokenSource)\nif err != nil {\n\treturn err\n}\n\n// The name of a document is constructed from the Game and Player fields.\nnameFromDocument := func(doc docstore.Document) string {\n\ths := doc.(*HighScore)\n\treturn hs.Game + \"|\" + hs.Player\n}\n\nresourceID := gcpfirestore.CollectionResourceID(\"my-project\", \"my-collection\")\ncoll, err := gcpfirestore.OpenCollectionWithNameFunc(client, resourceID, nameFromDocument, nil)\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/gcpfirestore.Example_openCollectionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/docstore\"\n\t_ \"gocloud.dev/docstore/gcpfirestore\"\n)", + "code": "// docstore.OpenCollection creates a *docstore.Collection from a URL.\nconst url = \"firestore://projects/my-project/databases/(default)/documents/my-collection?name_field=userID\"\ncoll, err := docstore.OpenCollection(ctx, url)\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/memdocstore.ExampleOpenCollection": { + "imports": "import \"gocloud.dev/docstore/memdocstore\"", + "code": "coll, err := memdocstore.OpenCollection(\"keyField\", nil)\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/memdocstore.ExampleOpenCollectionWithKeyFunc": { + "imports": "import (\n\t\"gocloud.dev/docstore\"\n\t\"gocloud.dev/docstore/memdocstore\"\n)", + "code": "// The name of a document is constructed from the Game and Player fields.\nnameFromDocument := func(doc docstore.Document) interface{} {\n\ths := doc.(*HighScore)\n\treturn hs.Game + \"|\" + hs.Player\n}\n\ncoll, err := memdocstore.OpenCollectionWithKeyFunc(nameFromDocument, nil)\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/memdocstore.Example_openCollectionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/docstore\"\n\t_ \"gocloud.dev/docstore/memdocstore\"\n)", + "code": "// docstore.OpenCollection creates a *docstore.Collection from a URL.\ncoll, err := docstore.OpenCollection(ctx, \"mem://collection/keyField\")\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/mongodocstore.ExampleOpenCollection": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/docstore/mongodocstore\"\n)", + "code": "client, err := mongodocstore.Dial(ctx, \"mongodb://my-host\")\nif err != nil {\n\treturn err\n}\nmcoll := client.Database(\"my-db\").Collection(\"my-coll\")\ncoll, err := mongodocstore.OpenCollection(mcoll, \"userID\", nil)\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/mongodocstore.ExampleOpenCollectionWithIDFunc": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/docstore\"\n\t\"gocloud.dev/docstore/mongodocstore\"\n)", + "code": "client, err := mongodocstore.Dial(ctx, \"mongodb://my-host\")\nif err != nil {\n\treturn err\n}\nmcoll := client.Database(\"my-db\").Collection(\"my-coll\")\n\n// The name of a document is constructed from the Game and Player fields.\nnameFromDocument := func(doc docstore.Document) interface{} {\n\ths := doc.(*HighScore)\n\treturn hs.Game + \"|\" + hs.Player\n}\n\ncoll, err := mongodocstore.OpenCollectionWithIDFunc(mcoll, nameFromDocument, nil)\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/docstore/mongodocstore.Example_openCollectionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/docstore\"\n\t_ \"gocloud.dev/docstore/mongodocstore\"\n)", + "code": "// docstore.OpenCollection creates a *docstore.Collection from a URL.\ncoll, err := docstore.OpenCollection(ctx, \"mongo://my-db/my-collection?id_field=userID\")\nif err != nil {\n\treturn err\n}\ndefer coll.Close()" + }, + "gocloud.dev/mysql.ExampleOpen": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/mysql\"\n)", + "code": "// Replace this with your actual settings.\ndb, err := mysql.Open(ctx, \"mysql://user:password@localhost/testdb\")\nif err != nil {\n\treturn err\n}\ndefer db.Close()\n\n// Use database in your program.\ndb.Exec(\"CREATE TABLE foo (bar INT);\")" + }, + "gocloud.dev/mysql/awsmysql.Example": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/mysql\"\n\t_ \"gocloud.dev/mysql/awsmysql\"\n)", + "code": "// Replace these with your actual settings.\ndb, err := mysql.Open(ctx,\n\t\"awsmysql://myrole:swordfish@example01.xyzzy.us-west-1.rds.amazonaws.com/testdb\")\nif err != nil {\n\treturn err\n}\ndefer db.Close()\n\n// Use database in your program.\ndb.ExecContext(ctx, \"CREATE TABLE foo (bar INT);\")" + }, + "gocloud.dev/mysql/azuremysql.Example": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/mysql\"\n\t_ \"gocloud.dev/mysql/azuremysql\"\n)", + "code": "// Replace this with your actual settings.\ndb, err := mysql.Open(ctx,\n\t\"azuremysql://user:password@example00.mysql.database.azure.com/testdb\")\nif err != nil {\n\treturn err\n}\ndefer db.Close()\n\n// Use database in your program.\ndb.Exec(\"CREATE TABLE foo (bar INT);\")" + }, + "gocloud.dev/mysql/gcpmysql.Example": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/mysql\"\n\t_ \"gocloud.dev/mysql/gcpmysql\"\n)", + "code": "// Replace this with your actual settings.\ndb, err := mysql.Open(ctx,\n\t\"gcpmysql://user:password@example-project/region/my-instance01/testdb\")\nif err != nil {\n\treturn err\n}\ndefer db.Close()\n\n// Use database in your program.\ndb.Exec(\"CREATE TABLE foo (bar INT);\")" + }, + "gocloud.dev/postgres.ExampleOpen": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/postgres\"\n)", + "code": "// Replace this with your actual settings.\ndb, err := postgres.Open(ctx, \"postgres://user:password@localhost/testdb\")\nif err != nil {\n\treturn err\n}\ndefer db.Close()\n\n// Use database in your program.\ndb.Exec(\"CREATE TABLE foo (bar INT);\")" + }, + "gocloud.dev/postgres/awspostgres.Example": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/postgres\"\n\t_ \"gocloud.dev/postgres/awspostgres\"\n)", + "code": "// Replace these with your actual settings.\ndb, err := postgres.Open(ctx,\n\t\"awspostgres://myrole:swordfish@example01.xyzzy.us-west-1.rds.amazonaws.com/testdb\")\nif err != nil {\n\treturn err\n}\ndefer db.Close()\n\n// Use database in your program.\ndb.ExecContext(ctx, \"CREATE TABLE foo (bar INT);\")" + }, + "gocloud.dev/postgres/gcppostgres.Example": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/postgres\"\n\t_ \"gocloud.dev/postgres/gcppostgres\"\n)", + "code": "// Replace this with your actual settings.\ndb, err := postgres.Open(ctx,\n\t\"gcppostgres://user:password@example-project/region/my-instance01/testdb\")\nif err != nil {\n\treturn err\n}\ndefer db.Close()\n\n// Use database in your program.\ndb.Exec(\"CREATE TABLE foo (bar INT);\")" + }, + "gocloud.dev/pubsub.ExampleSubscription_Receive": { + "imports": "import (\n\t\"context\"\n\t\"fmt\"\n\n\t\"gocloud.dev/pubsub\"\n)", + "code": "// Loop on received messages.\nfor {\n\tmsg, err := subscription.Receive(ctx)\n\tif err != nil {\n\t\t// Errors from Receive indicate that Receive will no longer succeed.\n\t\tlog.Printf(\"Receiving message: %v\", err)\n\t\tbreak\n\t}\n\t// Do work based on the message, for example:\n\tfmt.Printf(\"Got message: %q\\n\", msg.Body)\n\t// Messages must always be acknowledged with Ack.\n\tmsg.Ack()\n}" + }, + "gocloud.dev/pubsub.ExampleSubscription_Receive_concurrent": { + "imports": "import (\n\t\"context\"\n\t\"fmt\"\n\n\t\"gocloud.dev/pubsub\"\n)", + "code": "// Loop on received messages. We can use a channel as a semaphore to limit how\n// many goroutines we have active at a time as well as wait on the goroutines\n// to finish before exiting.\nconst maxHandlers = 10\nsem := make(chan struct{}, maxHandlers)\nrecvLoop:\nfor {\n\tmsg, err := subscription.Receive(ctx)\n\tif err != nil {\n\t\t// Errors from Receive indicate that Receive will no longer succeed.\n\t\tlog.Printf(\"Receiving message: %v\", err)\n\t\tbreak\n\t}\n\n\t// Wait if there are too many active handle goroutines and acquire the\n\t// semaphore. If the context is canceled, stop waiting and start shutting\n\t// down.\n\tselect {\n\tcase sem \u003c- struct{}{}:\n\tcase \u003c-ctx.Done():\n\t\tbreak recvLoop\n\t}\n\n\t// Handle the message in a new goroutine.\n\tgo func() {\n\t\tdefer func() { \u003c-sem }() // Release the semaphore.\n\t\tdefer msg.Ack() // Messages must always be acknowledged with Ack.\n\n\t\t// Do work based on the message, for example:\n\t\tfmt.Printf(\"Got message: %q\\n\", msg.Body)\n\t}()\n}\n\n// We're no longer receiving messages. Wait to finish handling any\n// unacknowledged messages by totally acquiring the semaphore.\nfor n := 0; n \u003c maxHandlers; n++ {\n\tsem \u003c- struct{}{}\n}" + }, + "gocloud.dev/pubsub.ExampleTopic_Send": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n)", + "code": "err := topic.Send(ctx, \u0026pubsub.Message{\n\tBody: []byte(\"Hello, World!\\n\"),\n\t// Metadata is optional and can be nil.\n\tMetadata: map[string]string{\n\t\t// These are examples of metadata.\n\t\t// There is nothing special about the key names.\n\t\t\"language\": \"en\",\n\t\t\"importance\": \"high\",\n\t},\n})\nif err != nil {\n\treturn err\n}" + }, + "gocloud.dev/pubsub/awssnssqs.ExampleOpenSNSTopic": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/aws/aws-sdk-go-v2/config\"\n\t\"github.com/aws/aws-sdk-go-v2/service/sns\"\n\t\"gocloud.dev/pubsub/awssnssqs\"\n)", + "code": "// Establish a AWS V2 Config.\n// See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info.\ncfg, err := config.LoadDefaultConfig(ctx)\nif err != nil {\n\treturn err\n}\n\n// Create a *pubsub.Topic.\nconst topicARN = \"arn:aws:sns:us-east-2:123456789012:mytopic\"\nclient := sns.NewFromConfig(cfg)\ntopic := awssnssqs.OpenSNSTopic(ctx, client, topicARN, nil)\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/awssnssqs.ExampleOpenSQSTopic": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/aws/aws-sdk-go-v2/config\"\n\t\"github.com/aws/aws-sdk-go-v2/service/sqs\"\n\t\"gocloud.dev/pubsub/awssnssqs\"\n)", + "code": "// Establish a AWS V2 Config.\n// See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info.\ncfg, err := config.LoadDefaultConfig(ctx)\nif err != nil {\n\treturn err\n}\n\n// Create a *pubsub.Topic.\nconst queueURL = \"https://sqs.us-east-2.amazonaws.com/123456789012/myqueue\"\nclient := sqs.NewFromConfig(cfg)\ntopic := awssnssqs.OpenSQSTopic(ctx, client, queueURL, nil)\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/awssnssqs.ExampleOpenSubscription": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/aws/aws-sdk-go-v2/config\"\n\t\"github.com/aws/aws-sdk-go-v2/service/sqs\"\n\t\"gocloud.dev/pubsub/awssnssqs\"\n)", + "code": "// Establish a AWS V2 Config.\n// See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info.\ncfg, err := config.LoadDefaultConfig(ctx)\nif err != nil {\n\treturn err\n}\n\n// Construct a *pubsub.Subscription.\n// https://docs.aws.amazon.com/sdk-for-net/v2/developer-guide/QueueURL.html\nconst queueURL = \"https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue\"\nclient := sqs.NewFromConfig(cfg)\nsubscription := awssnssqs.OpenSubscription(ctx, client, queueURL, nil)\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/awssnssqs.Example_openSNSTopicFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/awssnssqs\"\n)", + "code": "const topicARN = \"arn:aws:sns:us-east-2:123456789012:mytopic\"\n// Note the 3 slashes; ARNs have multiple colons and therefore aren't valid\n// as hostnames in the URL.\ntopic, err := pubsub.OpenTopic(ctx, \"awssns:///\"+topicARN+\"?region=us-east-2\")\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/awssnssqs.Example_openSQSTopicFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/awssnssqs\"\n)", + "code": "// https://docs.aws.amazon.com/sdk-for-net/v2/developer-guide/QueueURL.html\nconst queueURL = \"sqs.us-east-2.amazonaws.com/123456789012/myqueue\"\ntopic, err := pubsub.OpenTopic(ctx, \"awssqs://\"+queueURL+\"?region=us-east-2\")\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/awssnssqs.Example_openSubscriptionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/awssnssqs\"\n)", + "code": "// pubsub.OpenSubscription creates a *pubsub.Subscription from a URL.\n// This URL will open the subscription with the URL\n// \"https://sqs.us-east-2.amazonaws.com/123456789012/myqueue\".\nsubscription, err := pubsub.OpenSubscription(ctx,\n\t\"awssqs://sqs.us-east-2.amazonaws.com/123456789012/\"+\n\t\t\"myqueue?region=us-east-2\")\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/azuresb.ExampleOpenSubscription": { + "imports": "import (\n\t\"context\"\n\t\"os\"\n\n\t\"gocloud.dev/pubsub/azuresb\"\n)", + "code": "// Change these as needed for your application.\nserviceBusConnString := os.Getenv(\"SERVICEBUS_CONNECTION_STRING\")\nconst topicName = \"test-topic\"\nconst subscriptionName = \"test-subscription\"\n\n// Connect to Azure Service Bus for the given subscription.\nsbClient, err := azuresb.NewClientFromConnectionString(serviceBusConnString, nil)\nif err != nil {\n\treturn err\n}\nsbReceiver, err := azuresb.NewReceiver(sbClient, topicName, subscriptionName, nil)\nif err != nil {\n\treturn err\n}\ndefer sbReceiver.Close(ctx)\n\n// Construct a *pubsub.Subscription.\nsubscription, err := azuresb.OpenSubscription(ctx, sbClient, sbReceiver, nil)\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/azuresb.ExampleOpenTopic": { + "imports": "import (\n\t\"context\"\n\t\"os\"\n\n\t\"gocloud.dev/pubsub/azuresb\"\n)", + "code": "// Change these as needed for your application.\nconnString := os.Getenv(\"SERVICEBUS_CONNECTION_STRING\")\ntopicName := \"test-topic\"\n\nif connString == \"\" {\n\tlog.Fatal(\"Service Bus ConnectionString is not set\")\n}\n\n// Connect to Azure Service Bus for the given topic.\nsbClient, err := azuresb.NewClientFromConnectionString(connString, nil)\nif err != nil {\n\treturn err\n}\nsbSender, err := azuresb.NewSender(sbClient, topicName, nil)\nif err != nil {\n\treturn err\n}\ndefer sbSender.Close(ctx)\n\n// Construct a *pubsub.Topic.\ntopic, err := azuresb.OpenTopic(ctx, sbSender, nil)\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/azuresb.Example_openSubscriptionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/azuresb\"\n)", + "code": "// pubsub.OpenSubscription creates a *pubsub.Subscription from a URL.\n// This URL will open the subscription \"mysubscription\" for the topic\n// \"mytopic\" using a connection string from the environment variable\n// SERVICEBUS_CONNECTION_STRING.\nsubscription, err := pubsub.OpenSubscription(ctx,\n\t\"azuresb://mytopic?subscription=mysubscription\")\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/azuresb.Example_openTopicFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/azuresb\"\n)", + "code": "// pubsub.OpenTopic creates a *pubsub.Topic from a URL.\n// This URL will open the topic \"mytopic\" using a connection string\n// from the environment variable SERVICEBUS_CONNECTION_STRING.\ntopic, err := pubsub.OpenTopic(ctx, \"azuresb://mytopic\")\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/gcppubsub.ExampleOpenSubscription": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/gcp\"\n\t\"gocloud.dev/pubsub/gcppubsub\"\n)", + "code": "// Your GCP credentials.\n// See https://cloud.google.com/docs/authentication/production\n// for more info on alternatives.\ncreds, err := gcp.DefaultCredentials(ctx)\nif err != nil {\n\treturn err\n}\n\n// Open a gRPC connection to the GCP Pub/Sub API.\nconn, cleanup, err := gcppubsub.Dial(ctx, creds.TokenSource)\nif err != nil {\n\treturn err\n}\ndefer cleanup()\n\n// Construct a SubscriberClient using the connection.\nsubClient, err := gcppubsub.SubscriberClient(ctx, conn)\nif err != nil {\n\treturn err\n}\ndefer subClient.Close()\n\n// Construct a *pubsub.Subscription.\nsubscription, err := gcppubsub.OpenSubscriptionByPath(\n\tsubClient, \"projects/myprojectID/subscriptions/example-subscription\", nil)\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/gcppubsub.ExampleOpenTopic": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/gcp\"\n\t\"gocloud.dev/pubsub/gcppubsub\"\n)", + "code": "// Your GCP credentials.\n// See https://cloud.google.com/docs/authentication/production\n// for more info on alternatives.\ncreds, err := gcp.DefaultCredentials(ctx)\nif err != nil {\n\treturn err\n}\n// Open a gRPC connection to the GCP Pub/Sub API.\nconn, cleanup, err := gcppubsub.Dial(ctx, creds.TokenSource)\nif err != nil {\n\treturn err\n}\ndefer cleanup()\n\n// Construct a PublisherClient using the connection.\npubClient, err := gcppubsub.PublisherClient(ctx, conn)\nif err != nil {\n\treturn err\n}\ndefer pubClient.Close()\n\n// Construct a *pubsub.Topic.\ntopic, err := gcppubsub.OpenTopicByPath(pubClient, \"projects/myprojectID/topics/example-topic\", nil)\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/gcppubsub.Example_openSubscriptionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/gcppubsub\"\n)", + "code": "subscription, err := pubsub.OpenSubscription(ctx,\n\t\"gcppubsub://projects/my-project/subscriptions/my-subscription\")\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/gcppubsub.Example_openTopicFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/gcppubsub\"\n)", + "code": "topic, err := pubsub.OpenTopic(ctx, \"gcppubsub://projects/myproject/topics/mytopic\")\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/kafkapubsub.ExampleOpenSubscription": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub/kafkapubsub\"\n)", + "code": "// The set of brokers in the Kafka cluster.\naddrs := []string{\"1.2.3.4:9092\"}\n// The Kafka client configuration to use.\nconfig := kafkapubsub.MinimalConfig()\n\n// Construct a *pubsub.Subscription, joining the consumer group \"my-group\"\n// and receiving messages from \"my-topic\".\nsubscription, err := kafkapubsub.OpenSubscription(\n\taddrs, config, \"my-group\", []string{\"my-topic\"}, nil)\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/kafkapubsub.ExampleOpenTopic": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub/kafkapubsub\"\n)", + "code": "// The set of brokers in the Kafka cluster.\naddrs := []string{\"1.2.3.4:9092\"}\n// The Kafka client configuration to use.\nconfig := kafkapubsub.MinimalConfig()\n\n// Construct a *pubsub.Topic.\ntopic, err := kafkapubsub.OpenTopic(addrs, config, \"my-topic\", nil)\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/kafkapubsub.Example_openSubscriptionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/kafkapubsub\"\n)", + "code": "// pubsub.OpenSubscription creates a *pubsub.Subscription from a URL.\n// The host + path are used as the consumer group name.\n// The \"topic\" query parameter sets one or more topics to subscribe to.\n// The set of brokers must be in an environment variable KAFKA_BROKERS.\nsubscription, err := pubsub.OpenSubscription(ctx,\n\t\"kafka://my-group?topic=my-topic\")\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/kafkapubsub.Example_openTopicFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/kafkapubsub\"\n)", + "code": "// pubsub.OpenTopic creates a *pubsub.Topic from a URL.\n// The host + path are the topic name to send to.\n// The set of brokers must be in an environment variable KAFKA_BROKERS.\ntopic, err := pubsub.OpenTopic(ctx, \"kafka://my-topic?key_name=x-partition-key\")\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/mempubsub.ExampleNewSubscription": { + "imports": "import (\n\t\"context\"\n\t\"time\"\n\n\t\"gocloud.dev/pubsub/mempubsub\"\n)", + "code": "// Construct a *pubsub.Topic.\ntopic := mempubsub.NewTopic()\ndefer topic.Shutdown(ctx)\n\n// Construct a *pubsub.Subscription for the topic.\nsubscription := mempubsub.NewSubscription(topic, 1*time.Minute /* ack deadline */)\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/mempubsub.ExampleNewTopic": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub/mempubsub\"\n)", + "code": "topic := mempubsub.NewTopic()\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/mempubsub.Example_openSubscriptionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/mempubsub\"\n)", + "code": "// Create a topic.\ntopic, err := pubsub.OpenTopic(ctx, \"mem://topicA\")\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)\n\n// Create a subscription connected to that topic.\nsubscription, err := pubsub.OpenSubscription(ctx, \"mem://topicA\")\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/mempubsub.Example_openTopicFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/mempubsub\"\n)", + "code": "topic, err := pubsub.OpenTopic(ctx, \"mem://topicA\")\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/natspubsub.ExampleOpenSubscription": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/nats-io/nats.go\"\n\t\"gocloud.dev/pubsub/natspubsub\"\n)", + "code": "natsConn, err := nats.Connect(\"nats://nats.example.com\")\nif err != nil {\n\treturn err\n}\ndefer natsConn.Close()\n\nsubscription, err := natspubsub.OpenSubscription(\n\tnatsConn,\n\t\"example.mysubject\",\n\tnil)\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/natspubsub.ExampleOpenSubscriptionV2": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/nats-io/nats.go\"\n\t\"gocloud.dev/pubsub/natspubsub\"\n)", + "code": "subscription, err := natspubsub.OpenSubscriptionV2(\n\tnatsConn,\n\t\"example.mysubject\",\n\tnil)\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/natspubsub.ExampleOpenSubscription_queue": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/nats-io/nats.go\"\n\t\"gocloud.dev/pubsub/natspubsub\"\n)", + "code": "natsConn, err := nats.Connect(\"nats://nats.example.com\")\nif err != nil {\n\treturn err\n}\ndefer natsConn.Close()\n\nsubscription, err := natspubsub.OpenSubscription(\n\tnatsConn,\n\t\"example.mysubject\",\n\t\u0026natspubsub.SubscriptionOptions{Queue: \"queue1\"})\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/natspubsub.ExampleOpenTopic": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/nats-io/nats.go\"\n\t\"gocloud.dev/pubsub/natspubsub\"\n)", + "code": "natsConn, err := nats.Connect(\"nats://nats.example.com\")\nif err != nil {\n\treturn err\n}\ndefer natsConn.Close()\n\ntopic, err := natspubsub.OpenTopic(natsConn, \"example.mysubject\", nil)\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/natspubsub.ExampleOpenTopicV2": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/nats-io/nats.go\"\n\t\"gocloud.dev/pubsub/natspubsub\"\n)", + "code": "natsConn, err := nats.Connect(\"nats://nats.example.com\")\nif err != nil {\n\treturn err\n}\ndefer natsConn.Close()\n\ntopic, err := natspubsub.OpenTopicV2(natsConn, \"example.mysubject\", nil)\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/natspubsub.Example_openQueueSubscriptionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/natspubsub\"\n)", + "code": "// pubsub.OpenSubscription creates a *pubsub.Subscription from a URL.\n// This URL will Dial the NATS server at the URL in the environment variable\n// NATS_SERVER_URL and receive messages with subject \"example.mysubject\"\n// This URL will be parsed and the queue attribute will be used as the Queue parameter when creating the NATS Subscription.\nsubscription, err := pubsub.OpenSubscription(ctx, \"nats://example.mysubject?queue=myqueue\")\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/natspubsub.Example_openSubscriptionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/natspubsub\"\n)", + "code": "// pubsub.OpenSubscription creates a *pubsub.Subscription from a URL.\n// This URL will Dial the NATS server at the URL in the environment variable\n// NATS_SERVER_URL and receive messages with subject \"example.mysubject\".\nsubscription, err := pubsub.OpenSubscription(ctx, \"nats://example.mysubject\")\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/natspubsub.Example_openSubscriptionV2FromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/natspubsub\"\n)", + "code": "// pubsub.OpenSubscription creates a *pubsub.Subscription from a URL.\n// This URL will Dial the NATS server at the URL in the environment variable\n// NATS_SERVER_URL and receive messages with subject \"example.mysubject\".\n// This URL will be parsed and the natsv2 attribute will be used to\n// use NATS v2.2.0+ native message headers as the message metadata.\nsubscription, err := pubsub.OpenSubscription(ctx, \"nats://example.mysubject?natsv2\")\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/natspubsub.Example_openTopicFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/natspubsub\"\n)", + "code": "// pubsub.OpenTopic creates a *pubsub.Topic from a URL.\n// This URL will Dial the NATS server at the URL in the environment variable\n// NATS_SERVER_URL and send messages with subject \"example.mysubject\".\ntopic, err := pubsub.OpenTopic(ctx, \"nats://example.mysubject\")\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/natspubsub.Example_openTopicV2FromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/natspubsub\"\n)", + "code": "// pubsub.OpenTopic creates a *pubsub.Topic from a URL.\n// This URL will Dial the NATS server at the URL in the environment variable\n// NATS_SERVER_URL and send messages with subject \"example.mysubject\".\n// This URL will be parsed and the natsv2 attribute will be used to\n// use NATS v2.2.0+ native message headers as the message metadata.\ntopic, err := pubsub.OpenTopic(ctx, \"nats://example.mysubject?natsv2\")\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/rabbitpubsub.ExampleOpenSubscription": { + "imports": "import (\n\t\"context\"\n\n\tamqp \"github.com/rabbitmq/amqp091-go\"\n\t\"gocloud.dev/pubsub/rabbitpubsub\"\n)", + "code": "rabbitConn, err := amqp.Dial(\"amqp://guest:guest@localhost:5672/\")\nif err != nil {\n\treturn err\n}\ndefer rabbitConn.Close()\nsubscription := rabbitpubsub.OpenSubscription(rabbitConn, \"myqueue\", nil)\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/rabbitpubsub.ExampleOpenTopic": { + "imports": "import (\n\t\"context\"\n\n\tamqp \"github.com/rabbitmq/amqp091-go\"\n\t\"gocloud.dev/pubsub/rabbitpubsub\"\n)", + "code": "rabbitConn, err := amqp.Dial(\"amqp://guest:guest@localhost:5672/\")\nif err != nil {\n\treturn err\n}\ndefer rabbitConn.Close()\ntopic := rabbitpubsub.OpenTopic(rabbitConn, \"myexchange\", nil)\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/rabbitpubsub.Example_openSubscriptionFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/rabbitpubsub\"\n)", + "code": "// pubsub.OpenSubscription creates a *pubsub.Subscription from a URL.\n// This URL will Dial the RabbitMQ server at the URL in the environment\n// variable RABBIT_SERVER_URL and open the queue \"myqueue\".\nsubscription, err := pubsub.OpenSubscription(ctx, \"rabbit://myqueue\")\nif err != nil {\n\treturn err\n}\ndefer subscription.Shutdown(ctx)" + }, + "gocloud.dev/pubsub/rabbitpubsub.Example_openTopicFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/pubsub\"\n\t_ \"gocloud.dev/pubsub/rabbitpubsub\"\n)", + "code": "// pubsub.OpenTopic creates a *pubsub.Topic from a URL.\n// This URL will Dial the RabbitMQ server at the URL in the environment\n// variable RABBIT_SERVER_URL and open the exchange \"myexchange\".\ntopic, err := pubsub.OpenTopic(ctx, \"rabbit://myexchange\")\nif err != nil {\n\treturn err\n}\ndefer topic.Shutdown(ctx)" + }, + "gocloud.dev/runtimevar.ExampleDecryptDecode": { + "imports": "import (\n\t\"gocloud.dev/runtimevar\"\n\t\"gocloud.dev/secrets\"\n)", + "code": "decodeFunc := runtimevar.DecryptDecode(keeper, runtimevar.StringDecode)\ndecoder := runtimevar.NewDecoder(\"\", decodeFunc)" + }, + "gocloud.dev/runtimevar.ExampleVariable_Latest": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/runtimevar\"\n)", + "code": "snapshot, err := v.Latest(context.Background())\nif err != nil {\n\tlog.Fatalf(\"Error in retrieving variable: %v\", err)\n}" + }, + "gocloud.dev/runtimevar.Example_jsonDecoder": { + "imports": "import (\n\t\"context\"\n\t\"fmt\"\n\n\t\"gocloud.dev/runtimevar\"\n\t\"gocloud.dev/runtimevar/constantvar\"\n)", + "code": "// Config is the sample config struct we're going to parse our JSON into.\ntype Config struct {\n\tHost string\n\tPort int\n}\n\n// A sample JSON config that will decode into Config.\nconst jsonConfig = `{\"Host\": \"gocloud.dev\", \"Port\": 8080}`\n\n// Construct a Decoder that decodes raw bytes into our config.\ndecoder := runtimevar.NewDecoder(Config{}, runtimevar.JSONDecode)\n\n// Next, a construct a *Variable using a constructor or URL opener.\n// This example uses constantvar.\n// If you're using a URL opener, you can't decode JSON into a struct, but\n// you can use the query parameter \"decoder=jsonmap\" to decode into a map.\nv := constantvar.NewBytes([]byte(jsonConfig), decoder)\ndefer v.Close()\n// snapshot.Value will be of type Config." + }, + "gocloud.dev/runtimevar/awsparamstore.ExampleOpenVariable": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/aws/aws-sdk-go-v2/config\"\n\t\"github.com/aws/aws-sdk-go-v2/service/ssm\"\n\t\"gocloud.dev/runtimevar\"\n\t\"gocloud.dev/runtimevar/awsparamstore\"\n)", + "code": "// Establish a AWS V2 Config.\n// See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info.\nctx := context.Background()\ncfg, err := config.LoadDefaultConfig(ctx)\nif err != nil {\n\treturn err\n}\n\n// Construct a *runtimevar.Variable that watches the variable.\nclient := ssm.NewFromConfig(cfg)\nv, err := awsparamstore.OpenVariable(client, \"cfg-variable-name\", runtimevar.StringDecoder, nil)\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/awsparamstore.Example_openVariableFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/runtimevar\"\n\t_ \"gocloud.dev/runtimevar/awsparamstore\"\n)", + "code": "// runtimevar.OpenVariable creates a *runtimevar.Variable from a URL.\nv, err := runtimevar.OpenVariable(ctx, \"awsparamstore://myvar?region=us-west-1\u0026decoder=string\")\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/awssecretsmanager.ExampleOpenVariable": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/aws/aws-sdk-go-v2/config\"\n\t\"github.com/aws/aws-sdk-go-v2/service/secretsmanager\"\n\t\"gocloud.dev/runtimevar\"\n\t\"gocloud.dev/runtimevar/awssecretsmanager\"\n)", + "code": "// Establish a AWS V2 Config.\n// See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info.\nctx := context.Background()\ncfg, err := config.LoadDefaultConfig(ctx)\nif err != nil {\n\treturn err\n}\n\n// Construct a *runtimevar.Variable that watches the variable.\n// `secret-variable-name` must be a friendly name of the secret, NOT the Amazon Resource Name (ARN).\nclient := secretsmanager.NewFromConfig(cfg)\nv, err := awssecretsmanager.OpenVariable(client, \"secret-variable-name\", runtimevar.StringDecoder, nil)\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/awssecretsmanager.Example_openVariableFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/runtimevar\"\n\t_ \"gocloud.dev/runtimevar/awssecretsmanager\"\n)", + "code": "// runtimevar.OpenVariable creates a *runtimevar.Variable from a URL.\n// `secret-variable-name` must be a friendly name of the secret, NOT the Amazon Resource Name (ARN).\nv, err := runtimevar.OpenVariable(ctx, \"awssecretsmanager://secret-variable-name?region=us-east-2\u0026decoder=string\")\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/blobvar.Example_openVariableFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/runtimevar\"\n\t_ \"gocloud.dev/runtimevar/blobvar\"\n)", + "code": "// runtimevar.OpenVariable creates a *runtimevar.Variable from a URL.\n// The default opener opens a blob.Bucket via a URL, based on the environment\n// variable BLOBVAR_BUCKET_URL.\n\nv, err := runtimevar.OpenVariable(ctx, \"blob://myvar.txt?decoder=string\")\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/constantvar.Example_openVariableFromURL": { + "imports": "import (\n\t\"context\"\n\t\"fmt\"\n\n\t\"gocloud.dev/runtimevar\"\n\t_ \"gocloud.dev/runtimevar/constantvar\"\n)", + "code": "// runtimevar.OpenVariable creates a *runtimevar.Variable from a URL.\n// The constant value is in the URL param \"val\".\nv, err := runtimevar.OpenVariable(ctx, \"constant://?val=hello+world\u0026decoder=string\")\nif err != nil {\n\treturn err\n}\ndefer v.Close()\n\n// The constant value is read from an environment variable specified in \"envvar\".\nv2, err := runtimevar.OpenVariable(ctx, \"constant://?envvar=MY_ENVIRONMENT_VARIABLE\u0026decoder=string\")\nif err != nil {\n\treturn err\n}\ndefer v2.Close()" + }, + "gocloud.dev/runtimevar/etcdvar.ExampleOpenVariable": { + "imports": "import (\n\t\"go.etcd.io/etcd/client/v3\"\n\t\"gocloud.dev/runtimevar\"\n\t\"gocloud.dev/runtimevar/etcdvar\"\n)", + "code": "// Connect to the etcd server.\nclient, err := clientv3.NewFromURL(\"http://your.etcd.server:9999\")\nif err != nil {\n\treturn err\n}\n\n// Construct a *runtimevar.Variable that watches the variable.\nv, err := etcdvar.OpenVariable(client, \"cfg-variable-name\", runtimevar.StringDecoder, nil)\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/etcdvar.Example_openVariableFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/runtimevar\"\n\t_ \"gocloud.dev/runtimevar/etcdvar\"\n)", + "code": "// runtimevar.OpenVariable creates a *runtimevar.Variable from a URL.\n// The default opener connects to an etcd server based on the environment\n// variable ETCD_SERVER_URL.\n\nv, err := runtimevar.OpenVariable(ctx, \"etcd://myvarname?decoder=string\")\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/filevar.Example_openVariableFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/runtimevar\"\n\t_ \"gocloud.dev/runtimevar/filevar\"\n)", + "code": "// runtimevar.OpenVariable creates a *runtimevar.Variable from a URL.\n\nv, err := runtimevar.OpenVariable(ctx, \"file:///path/to/config.txt?decoder=string\")\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/gcpruntimeconfig.ExampleOpenVariable": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/gcp\"\n\t\"gocloud.dev/runtimevar\"\n\t\"gocloud.dev/runtimevar/gcpruntimeconfig\"\n)", + "code": "// Your GCP credentials.\n// See https://cloud.google.com/docs/authentication/production\n// for more info on alternatives.\ncreds, err := gcp.DefaultCredentials(ctx)\nif err != nil {\n\treturn err\n}\n\n// Connect to the Runtime Configurator service.\nclient, cleanup, err := gcpruntimeconfig.Dial(ctx, creds.TokenSource)\nif err != nil {\n\treturn err\n}\ndefer cleanup()\n\n// You can use the VariableKey helper to construct a Variable key from\n// your project ID, config ID, and the variable name; alternatively,\n// you can construct the full string yourself (e.g.,\n// \"projects/gcp-project-id/configs/config-id/variables/variable-name\").\n// See https://cloud.google.com/deployment-manager/runtime-configurator/\n// for more details.\n//\n// For this example, the GCP Cloud Runtime Configurator variable being\n// referenced should have a JSON string that decodes into MyConfig.\nvariableKey := gcpruntimeconfig.VariableKey(\"gcp-project-id\", \"config-id\", \"variable-name\")\n\n// Construct a *runtimevar.Variable that watches the variable.\nv, err := gcpruntimeconfig.OpenVariable(client, variableKey, runtimevar.StringDecoder, nil)\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/gcpruntimeconfig.Example_openVariableFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/runtimevar\"\n\t_ \"gocloud.dev/runtimevar/gcpruntimeconfig\"\n)", + "code": "// runtimevar.OpenVariable creates a *runtimevar.Variable from a URL.\n// The URL Host+Path are used as the GCP Runtime Configurator Variable key;\n// see https://cloud.google.com/deployment-manager/runtime-configurator/\n// for more details.\n\nv, err := runtimevar.OpenVariable(ctx, \"gcpruntimeconfig://projects/myproject/configs/myconfigid/variables/myvar?decoder=string\")\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/gcpsecretmanager.ExampleOpenVariable": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/gcp\"\n\t\"gocloud.dev/runtimevar\"\n\t\"gocloud.dev/runtimevar/gcpsecretmanager\"\n)", + "code": "// Your GCP credentials.\n// See https://cloud.google.com/docs/authentication/production\n// for more info on alternatives.\ncreds, err := gcp.DefaultCredentials(ctx)\nif err != nil {\n\treturn err\n}\n\n// Connect to the GCP Secret Manager service.\nclient, cleanup, err := gcpsecretmanager.Dial(ctx, creds.TokenSource)\nif err != nil {\n\treturn err\n}\ndefer cleanup()\n\n// You can use the SecretKey helper to construct a secret key from\n// your project ID and the secret ID; alternatively,\n// you can construct the full string yourself (e.g.,\n// \"projects/gcp-project-id/secrets/secret-id\").\n// gcpsecretmanager package will always use the latest secret value,\n// so `/version/latest` postfix must NOT be added to the secret key.\n// See https://cloud.google.com/secret-manager\n// for more details.\n//\n// For this example, the GCP Secret Manager secret being\n// referenced should have a JSON string that decodes into MyConfig.\nvariableKey := gcpsecretmanager.SecretKey(\"gcp-project-id\", \"secret-id\")\n\n// Construct a *runtimevar.Variable that watches the variable.\nv, err := gcpsecretmanager.OpenVariable(client, variableKey, runtimevar.StringDecoder, nil)\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/gcpsecretmanager.Example_openVariableFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/runtimevar\"\n\t_ \"gocloud.dev/runtimevar/gcpsecretmanager\"\n)", + "code": "// runtimevar.OpenVariable creates a *runtimevar.Variable from a URL.\n// The URL Host+Path are used as the GCP Secret Manager secret key;\n// see https://cloud.google.com/secret-manager\n// for more details.\n\nv, err := runtimevar.OpenVariable(ctx, \"gcpsecretmanager://projects/myproject/secrets/mysecret?decoder=string\")\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/httpvar.ExampleOpenVariable": { + "imports": "import (\n\t\"net/http\"\n\n\t\"gocloud.dev/runtimevar\"\n\t\"gocloud.dev/runtimevar/httpvar\"\n)", + "code": "// Create an HTTP.Client\nhttpClient := http.DefaultClient\n\n// Construct a *runtimevar.Variable that watches the page.\nv, err := httpvar.OpenVariable(httpClient, \"http://example.com\", runtimevar.StringDecoder, nil)\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/runtimevar/httpvar.Example_openVariableFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/runtimevar\"\n\t_ \"gocloud.dev/runtimevar/httpvar\"\n)", + "code": "// runtimevar.OpenVariable creates a *runtimevar.Variable from a URL.\n// The default opener connects to an etcd server based on the environment\n// variable ETCD_SERVER_URL.\n\nv, err := runtimevar.OpenVariable(ctx, \"http://myserver.com/foo.txt?decoder=string\")\nif err != nil {\n\treturn err\n}\ndefer v.Close()" + }, + "gocloud.dev/secrets.ExampleKeeper_Decrypt": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/secrets\"\n)", + "code": "var cipherText []byte // obtained from elsewhere and random-looking\nplainText, err := keeper.Decrypt(ctx, cipherText)\nif err != nil {\n\treturn err\n}" + }, + "gocloud.dev/secrets.ExampleKeeper_Encrypt": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/secrets\"\n)", + "code": "plainText := []byte(\"Secrets secrets...\")\ncipherText, err := keeper.Encrypt(ctx, plainText)\nif err != nil {\n\treturn err\n}" + }, + "gocloud.dev/secrets/awskms.ExampleOpenKeeper": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/aws/aws-sdk-go-v2/config\"\n\t\"gocloud.dev/secrets/awskms\"\n)", + "code": "// Establish a AWS V2 Config.\n// See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info.\nctx := context.Background()\ncfg, err := config.LoadDefaultConfig(ctx)\nif err != nil {\n\treturn err\n}\n\n// Get a client to use with the KMS API.\nclient, err := awskms.Dial(cfg)\nif err != nil {\n\treturn err\n}\n\n// Construct a *secrets.Keeper.\nkeeper := awskms.OpenKeeper(client, \"alias/test-secrets\", nil)\ndefer keeper.Close()" + }, + "gocloud.dev/secrets/awskms.Example_openFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/secrets\"\n\t_ \"gocloud.dev/secrets/awskms\"\n)", + "code": "// Use one of the following:\n\n// 1. By ID.\nkeeperByID, err := secrets.OpenKeeper(ctx,\n\t\"awskms://1234abcd-12ab-34cd-56ef-1234567890ab?region=us-east-1\")\nif err != nil {\n\treturn err\n}\ndefer keeperByID.Close()\n\n// 2. By alias.\nkeeperByAlias, err := secrets.OpenKeeper(ctx,\n\t\"awskms://alias/ExampleAlias?region=us-east-1\")\nif err != nil {\n\treturn err\n}\ndefer keeperByAlias.Close()\n\n// 3. By ARN. Note that ARN may contain \":\" characters, which cannot be escaped\n// in the Host part of a URL, so the \"awskms:///\u003cARN\u003e\" form should be used.\nconst arn = \"arn:aws:kms:us-east-1:111122223333:key/\" +\n\t\"1234abcd-12ab-34bc-56ef-1234567890ab\"\nkeeperByARN, err := secrets.OpenKeeper(ctx,\n\t\"awskms:///\"+arn+\"?region=us-east-1\")\nif err != nil {\n\treturn err\n}\ndefer keeperByARN.Close()" + }, + "gocloud.dev/secrets/azurekeyvault.ExampleOpenKeeper": { + "imports": "import \"gocloud.dev/secrets/azurekeyvault\"", + "code": "// Makes a client to use with the Azure KeyVault API, using default\n// authorization from the environment.\nclientMaker := azurekeyvault.DefaultClientMaker\n\n// Construct a *secrets.Keeper.\nkeeper, err := azurekeyvault.OpenKeeper(clientMaker, \"https://mykeyvaultname.vault.azure.net/keys/mykeyname\", nil)\nif err != nil {\n\treturn err\n}\ndefer keeper.Close()" + }, + "gocloud.dev/secrets/azurekeyvault.Example_openFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/secrets\"\n\t_ \"gocloud.dev/secrets/azurekeyvault\"\n)", + "code": "// The \"azurekeyvault\" URL scheme is replaced with \"https\" to construct an Azure\n// Key Vault keyID, as described in https://docs.microsoft.com/en-us/azure/key-vault/about-keys-secrets-and-certificates.\n// You can add an optional \"/{key-version}\" to the path to use a specific\n// version of the key; it defaults to the latest version.\nkeeper, err := secrets.OpenKeeper(ctx, \"azurekeyvault://mykeyvaultname.vault.azure.net/keys/mykeyname\")\nif err != nil {\n\treturn err\n}\ndefer keeper.Close()" + }, + "gocloud.dev/secrets/gcpkms.ExampleOpenKeeper": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/secrets/gcpkms\"\n)", + "code": "// Get a client to use with the KMS API.\nclient, done, err := gcpkms.Dial(ctx, nil)\nif err != nil {\n\treturn err\n}\n// Close the connection when done.\ndefer done()\n\n// You can also use gcpkms.KeyResourceID to construct this string.\nconst keyID = \"projects/MYPROJECT/\" +\n\t\"locations/MYLOCATION/\" +\n\t\"keyRings/MYKEYRING/\" +\n\t\"cryptoKeys/MYKEY\"\n\n// Construct a *secrets.Keeper.\nkeeper := gcpkms.OpenKeeper(client, keyID, nil)\ndefer keeper.Close()" + }, + "gocloud.dev/secrets/gcpkms.Example_openFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/secrets\"\n\t_ \"gocloud.dev/secrets/gcpkms\"\n)", + "code": "keeper, err := secrets.OpenKeeper(ctx,\n\t\"gcpkms://projects/MYPROJECT/\"+\n\t\t\"locations/MYLOCATION/\"+\n\t\t\"keyRings/MYKEYRING/\"+\n\t\t\"cryptoKeys/MYKEY\")\nif err != nil {\n\treturn err\n}\ndefer keeper.Close()" + }, + "gocloud.dev/secrets/hashivault.ExampleOpenKeeper": { + "imports": "import (\n\t\"context\"\n\n\t\"github.com/hashicorp/vault/api\"\n\t\"gocloud.dev/secrets/hashivault\"\n)", + "code": "// Get a client to use with the Vault API.\nclient, err := hashivault.Dial(ctx, \u0026hashivault.Config{\n\tToken: \"CLIENT_TOKEN\",\n\tAPIConfig: api.Config{\n\t\tAddress: \"http://127.0.0.1:8200\",\n\t},\n})\nif err != nil {\n\treturn err\n}\n\n// Construct a *secrets.Keeper.\nkeeper := hashivault.OpenKeeper(client, \"my-key\", nil)\ndefer keeper.Close()" + }, + "gocloud.dev/secrets/hashivault.Example_openFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/secrets\"\n\t_ \"gocloud.dev/secrets/hashivault\"\n)", + "code": "keeper, err := secrets.OpenKeeper(ctx, \"hashivault://mykey\")\nif err != nil {\n\treturn err\n}\ndefer keeper.Close()" + }, + "gocloud.dev/secrets/localsecrets.ExampleNewKeeper": { + "imports": "import \"gocloud.dev/secrets/localsecrets\"", + "code": "secretKey, err := localsecrets.NewRandomKey()\nif err != nil {\n\treturn err\n}\nkeeper := localsecrets.NewKeeper(secretKey)\ndefer keeper.Close()" + }, + "gocloud.dev/secrets/localsecrets.Example_openFromURL": { + "imports": "import (\n\t\"context\"\n\n\t\"gocloud.dev/secrets\"\n\t_ \"gocloud.dev/secrets/localsecrets\"\n)", + "code": "// Using \"base64key://\", a new random key will be generated.\nrandomKeyKeeper, err := secrets.OpenKeeper(ctx, \"base64key://\")\nif err != nil {\n\treturn err\n}\ndefer randomKeyKeeper.Close()\n\n// Otherwise, the URL hostname must be a base64-encoded key, of length 32 bytes when decoded.\n// Note that base64.URLEncode should be used, to avoid URL-unsafe characters.\nsavedKeyKeeper, err := secrets.OpenKeeper(ctx, \"base64key://smGbjm71Nxd1Ig5FS0wj9SlbzAIrnolCz9bQQ6uAhl4=\")\nif err != nil {\n\treturn err\n}\ndefer savedKeyKeeper.Close()" + }, + "gocloud.dev/server.ExampleServer": { + "imports": "import (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"gocloud.dev/server\"\n)", + "code": "// Use the constructor function to create the server.\nsrv := server.New(http.DefaultServeMux, nil)\n\n// Register a route.\nhttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintln(w, \"Hello, World!\")\n})\n\n// Start the server. If ListenAndServe returns an error, print it and exit.\nif err := srv.ListenAndServe(\":8080\"); err != nil {\n\tlog.Fatalf(\"%v\", err)\n}" + }, + "gocloud.dev/server.ExampleServer_withHealthChecks": { + "imports": "import (\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"gocloud.dev/server\"\n\t\"gocloud.dev/server/health\"\n)", + "code": "// Create a health.Checker from the type we defined for our application.\n// In this example, healthCheck will report the server is unhealthy for 10 seconds\n// after startup, and as healthy henceforth. Check the /healthz/readiness\n// HTTP path to see readiness.\nhealthCheck := new(customHealthCheck)\ntime.AfterFunc(10*time.Second, func() {\n\thealthCheck.mu.Lock()\n\tdefer healthCheck.mu.Unlock()\n\thealthCheck.healthy = true\n})\n\n// The server.Options struct takes a slice of health checks, because you\n// may need to check several things.\nsrvOptions := \u0026server.Options{\n\tHealthChecks: []health.Checker{healthCheck},\n}\n\n// Pass the options to the Server constructor.\nsrv := server.New(http.DefaultServeMux, srvOptions)\n\n// Register a route.\nhttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintln(w, \"Hello, World!\")\n})\n\n// Start the server. You will see requests logged to STDOUT.\nif err := srv.ListenAndServe(\":8080\"); err != nil {\n\tlog.Fatalf(\"%v\", err)\n}" + }, + "gocloud.dev/server.ExampleServer_withRequestLogger": { + "imports": "import (\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"gocloud.dev/server\"\n\t\"gocloud.dev/server/requestlog\"\n)", + "code": "// Create a logger, and assign it to the RequestLogger field of a\n// server.Options struct.\nsrvOptions := \u0026server.Options{\n\tRequestLogger: requestlog.NewNCSALogger(os.Stdout, func(error) {}),\n}\n\n// Pass the options to the Server constructor.\nsrv := server.New(http.DefaultServeMux, srvOptions)\n\n// Register a route.\nhttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintln(w, \"Hello, World!\")\n})\n\n// Start the server. You will see requests logged to STDOUT.\nif err := srv.ListenAndServe(\":8080\"); err != nil {\n\tlog.Fatalf(\"%v\", err)\n}" + } +} diff --git a/go-cloud/internal/website/gatherexamples/gatherexamples.go b/go-cloud/internal/website/gatherexamples/gatherexamples.go new file mode 100644 index 000000000..ceb788607 --- /dev/null +++ b/go-cloud/internal/website/gatherexamples/gatherexamples.go @@ -0,0 +1,327 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// Command gatherexamples extracts examples in a Go module into a JSON-formatted +// object. This is used as input for building the Go CDK Hugo website. +// +// Examples must include a comment +// "// PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored." +// somewhere in the function body in order to be included in this tool's output. +// +// gatherexamples does some minimal rewriting of the example source code for +// presentation: +// +// - Any imports the example uses will be prepended to the code. +// - log.Fatal(err) -> return err +// - A comment line "// PRAGMA: On gocloud.dev, hide lines until the next blank line." will +// remove any code up to the next blank line. This is intended for +// compiler-mandated setup like `ctx := context.Background()`. +// - A comment line "// PRAGMA: On gocloud.dev, hide the rest of the function." will +// remove any code until the end of the function. This is intended for +// compiler-mandated assignments like `_ = bucket`. +// - A comment line "// PRAGMA: On gocloud.dev, add a blank import: _ "example.com/foo"" +// will add the blank import to the example's imports. +// +// The key of each JSON object entry will be the import path of the package, +// followed by a dot ("."), followed by the name of the example function. The +// value of each JSON object entry is an object like +// {"imports": "import (\n\t\"fmt\"\n)", "code": "/* ... */"}. These are +// separated so that templating can format or show them separately. +package main + +import ( + "encoding/json" + "flag" + "fmt" + "go/ast" + "go/format" + "go/printer" + "go/types" + "os" + "sort" + "strconv" + "strings" + + "golang.org/x/tools/go/packages" +) + +func main() { + flag.Usage = func() { + out := flag.CommandLine.Output() + fmt.Fprintln(out, "usage: gatherexamples [options] DIR [...]") + fmt.Fprintln(out) + fmt.Fprintln(out, "Options:") + flag.PrintDefaults() + } + pattern := flag.String("pattern", "./...", "Go package pattern to use at each directory argument") + flag.Parse() + if flag.NArg() == 0 { + flag.Usage() + os.Exit(2) // matches with flag package + } + + // Load packages in each module named on the command line and find + // all examples. + allExamples := make(map[string]example) + for _, dir := range flag.Args() { + cfg := &packages.Config{ + Mode: gatherLoadMode, + Dir: dir, + Tests: true, + } + pkgs, err := packages.Load(cfg, *pattern) + if err != nil { + fmt.Fprintf(os.Stderr, "gatherexamples: load %s: %v\n", dir, err) + os.Exit(1) + } + examples, err := gather(pkgs) + if err != nil { + fmt.Fprintf(os.Stderr, "gatherexamples: gather: %v", err) + os.Exit(1) + } + for exampleName, ex := range examples { + allExamples[exampleName] = ex + } + } + + // Write all examples as a JSON object. + data, err := json.MarshalIndent(allExamples, "", "\t") + if err != nil { + fmt.Fprintf(os.Stderr, "gatherexamples: generate JSON: %v\n", err) + os.Exit(1) + } + data = append(data, '\n') + if _, err := os.Stdout.Write(data); err != nil { + fmt.Fprintf(os.Stderr, "gatherexamples: write output: %v\n", err) + os.Exit(1) + } +} + +const gatherLoadMode packages.LoadMode = packages.NeedName | + packages.NeedFiles | + packages.NeedTypes | + packages.NeedSyntax | + packages.NeedTypesInfo | + packages.NeedImports | + // TODO(light): We really only need name from deps, but there's no way to + // specify that in the current go/packages API. This sadly makes this program + // 10x slower. Reported as https://github.com/golang/go/issues/31699. + packages.NeedDeps + +// pragmaPrefix is the prefix for all comments in examples that are used as +// directives for formatting. +const pragmaPrefix = "// PRAGMA: " + +// inclusionComment is the comment used to signify whether the example should be +// included in the output. +const inclusionComment = pragmaPrefix + "This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored." + +type example struct { + Imports string `json:"imports"` + Code string `json:"code"` +} + +// gather extracts the code from the example functions in the given packages +// and returns a map like the one described in the package documentation. +func gather(pkgs []*packages.Package) (map[string]example, error) { + examples := make(map[string]example) + for _, pkg := range pkgs { + for _, file := range pkg.Syntax { + for _, decl := range file.Decls { + // Determine whether this declaration is an example function. + fn, ok := decl.(*ast.FuncDecl) + if !ok || !strings.HasPrefix(fn.Name.Name, "Example") || len(fn.Type.Params.List) > 0 || len(fn.Type.Params.List) > 0 { + continue + } + + // Format example into string. + sb := new(strings.Builder) + err := format.Node(sb, pkg.Fset, &printer.CommentedNode{ + Node: fn.Body, + Comments: file.Comments, + }) + if err != nil { + return nil, err // will only occur for bad invocations of Fprint + } + original := sb.String() + if !strings.Contains(original, inclusionComment) { + // Does not contain the inclusion comment. Skip it, but first verify + // that it doesn't contain any PRAGMA comments; only examples with + // the inclusion comment should include pragmas. + if strings.Contains(original, pragmaPrefix) { + return nil, fmt.Errorf("%s in package %s has PRAGMA(s) for gatherexamples, but is not marked for inclusion with %q", fn.Name.Name, pkg.PkgPath, inclusionComment) + } + continue + } + exampleCode, blankImports := rewriteBlock(original) + + // Gather map of imported packages to overridden identifier. + usedPackages := make(map[string]string) + for _, path := range blankImports { + usedPackages[path] = "_" + } + ast.Inspect(fn.Body, func(node ast.Node) bool { + id, ok := node.(*ast.Ident) + if !ok { + return true + } + refPkg, ok := pkg.TypesInfo.ObjectOf(id).(*types.PkgName) + if !ok { + return true + } + overrideName := "" + if id.Name != refPkg.Imported().Name() { + overrideName = id.Name + } + usedPackages[refPkg.Imported().Path()] = overrideName + return true + }) + // Remove "log" import since it's almost always used for log.Fatal(err). + delete(usedPackages, "log") + + pkgPath := strings.TrimSuffix(pkg.PkgPath, "_test") + exampleName := pkgPath + "." + fn.Name.Name + examples[exampleName] = example{ + Imports: formatImports(usedPackages), + Code: exampleCode, + } + } + } + } + return examples, nil +} + +// rewriteBlock reformats a Go block statement for display as an example. +// It also extracts any blank imports found +func rewriteBlock(block string) (_ string, blankImports []string) { + // Trim block. + block = strings.TrimPrefix(block, "{") + block = strings.TrimSuffix(block, "}") + + // Rewrite line-by-line. + sb := new(strings.Builder) +rewrite: + for len(block) > 0 { + var line string + line, block = nextLine(block) + + // Dedent line. + // TODO(light): In the case of a multi-line raw string literal, + // this can produce incorrect rewrites. + line = strings.TrimPrefix(line, "\t") + + // Write the line to sb, performing textual substitutions as needed. + start := strings.IndexFunc(line, func(r rune) bool { return r != ' ' && r != '\t' }) + if start == -1 { + // Blank. + sb.WriteString(line) + sb.WriteByte('\n') + continue + } + const importBlankPrefix = pragmaPrefix + "On gocloud.dev, add a blank import: _ " + indent, lineContent := line[:start], line[start:] + switch { + case lineContent == pragmaPrefix+"On gocloud.dev, hide lines until the next blank line.": + // Skip lines until we hit a blank line. + for len(block) > 0 { + var next string + next, block = nextLine(block) + if strings.TrimSpace(next) == "" { + break + } + } + case lineContent == pragmaPrefix+"On gocloud.dev, hide the rest of the function.": + // Ignore remaining lines. + break rewrite + case lineContent == "log.Fatal(err)": + sb.WriteString(indent) + sb.WriteString("return err") + sb.WriteByte('\n') + case strings.HasPrefix(lineContent, importBlankPrefix): + // Blank import. + path, err := strconv.Unquote(lineContent[len(importBlankPrefix):]) + if err == nil { + blankImports = append(blankImports, path) + } + case strings.Contains(lineContent, inclusionComment): + // inclusion comment. Skip it. + default: + // Ordinary line, write as-is. + sb.WriteString(line) + sb.WriteByte('\n') + } + } + return strings.TrimSpace(sb.String()), blankImports +} + +// nextLine splits the string at the next linefeed. +func nextLine(s string) (line, tail string) { + i := strings.IndexByte(s, '\n') + if i == -1 { + return s, "" + } + return s[:i], s[i+1:] +} + +// formatImports formats a map of imports to their package identifiers into a +// Go import declaration. +func formatImports(usedPackages map[string]string) string { + if len(usedPackages) == 0 { + return "" + } + if len(usedPackages) == 1 { + // Special case: one-line import. + for path, id := range usedPackages { + if id != "" { + return fmt.Sprintf("import %s %q", id, path) + } + return fmt.Sprintf("import %q", path) + } + } + // Typical case: multiple imports in factored declaration form. + // Group into standard library imports then third-party imports. + sortedStdlib := make([]string, 0, len(usedPackages)) + sortedThirdParty := make([]string, 0, len(usedPackages)) + for path := range usedPackages { + if strings.ContainsRune(path, '.') { + // Third-party imports almost always contain a dot for a domain name, + // especially in GOPATH/Go modules workspaces. + sortedThirdParty = append(sortedThirdParty, path) + } else { + sortedStdlib = append(sortedStdlib, path) + } + } + sort.Strings(sortedStdlib) + sort.Strings(sortedThirdParty) + sb := new(strings.Builder) + sb.WriteString("import (\n") + printImports := func(paths []string) { + for _, path := range paths { + id := usedPackages[path] + if id == "" { + fmt.Fprintf(sb, "\t%q\n", path) + } else { + fmt.Fprintf(sb, "\t%s %q\n", id, path) + } + } + } + printImports(sortedStdlib) + if len(sortedStdlib) > 0 && len(sortedThirdParty) > 0 { + // Insert blank line to separate. + sb.WriteByte('\n') + } + printImports(sortedThirdParty) + sb.WriteString(")") + return sb.String() +} diff --git a/go-cloud/internal/website/gatherexamples/gatherexamples_test.go b/go-cloud/internal/website/gatherexamples/gatherexamples_test.go new file mode 100644 index 000000000..1e8a274e0 --- /dev/null +++ b/go-cloud/internal/website/gatherexamples/gatherexamples_test.go @@ -0,0 +1,355 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "golang.org/x/tools/go/packages" + "golang.org/x/tools/go/packages/packagestest" +) + +func TestGather(t *testing.T) { + tests := []struct { + name string + module packagestest.Module + want map[string]example + wantErr bool + }{ + { + name: "NoExamples", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\nfunc main() {}\n", + }, + }, + want: map[string]example{}, + }, + { + name: "EmptyExample", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\n", + "example_test.go": `package foo_test + +func Example() {}`, + }, + }, + want: map[string]example{}, + }, + { + name: "EmptyExampleFoo", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\n", + "example_test.go": `package foo_test + +func ExampleFoo() { +}`, + }, + }, + want: map[string]example{}, + }, + { + name: "NonSignifiedExampleWithPragma", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\n", + "example_test.go": `package foo_test + +func ExampleFoo() { + // PRAGMA: Do something. +}`, + }, + }, + want: map[string]example{}, + wantErr: true, + }, + { + name: "EmptyExampleWithComment", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\n", + "example_test.go": `package foo_test + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. +}`, + }, + }, + want: map[string]example{ + "example.com/foo.Example": {Code: ""}, + }, + }, + { + name: "EmptyExampleFooWithComment", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\n", + "example_test.go": `package foo_test + +func ExampleFoo() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. +}`, + }, + }, + want: map[string]example{ + "example.com/foo.ExampleFoo": {Code: ""}, + }, + }, + { + name: "NoImportsExample", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\n", + "example_test.go": `package foo_test + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // Unattached comment. + + // Outside inner block comment. + panic("ohai") + if false { + // something + } + return +}`, + }, + }, + want: map[string]example{ + "example.com/foo.Example": {Code: "// Unattached comment.\n\n" + + "// Outside inner block comment.\n" + + "panic(\"ohai\")\n" + + "if false {\n\t// something\n}\n" + + "return"}, + }, + }, + { + name: "OneImportExample", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\n", + "example_test.go": `package foo_test + +import "fmt" + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + fmt.Println(42) +}`, + }, + }, + want: map[string]example{ + "example.com/foo.Example": { + Imports: "import \"fmt\"", + Code: "fmt.Println(42)", + }, + }, + }, + { + name: "TwoImportsExample", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\n", + "example_test.go": `package foo_test + +import "fmt" +import "math" + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + fmt.Println(math.Pi) +}`, + }, + }, + want: map[string]example{ + "example.com/foo.Example": { + Imports: "import (\n\t\"fmt\"\n\t\"math\"\n)", + Code: "fmt.Println(math.Pi)", + }, + }, + }, + { + name: "LogFatalToReturnErr", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\n", + "example_test.go": `package foo_test + +import "log" + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + var err error + if err != nil { + log.Fatal(err) + } +}`, + }, + }, + want: map[string]example{ + "example.com/foo.Example": {Code: "var err error\n" + + "if err != nil {\n\treturn err\n}"}, + }, + }, + { + name: "IgnoreSections", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\n", + "example_test.go": `package foo_test + +import "context" + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // do something + + // PRAGMA: On gocloud.dev, hide the rest of the function. + _ = ctx +}`, + }, + }, + want: map[string]example{ + "example.com/foo.Example": { + Imports: "import \"context\"", + Code: "// do something", + }, + }, + }, + { + name: "BlankImports", + module: packagestest.Module{ + Name: "example.com/foo", + Files: map[string]any{ + "foo.go": "package foo\n", + "example_test.go": `package foo_test + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // PRAGMA: On gocloud.dev, add a blank import: _ "example.com/bar" + _ = 42 +}`, + }, + }, + want: map[string]example{ + "example.com/foo.Example": { + Imports: "import _ \"example.com/bar\"", + Code: "_ = 42", + }, + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + exported := packagestest.Export(t, packagestest.Modules, []packagestest.Module{test.module}) + defer exported.Cleanup() + exported.Config.Mode = gatherLoadMode + pkgs, err := packages.Load(exported.Config, "./...") + if err != nil { + t.Fatal(err) + } + + got, err := gather(pkgs) + if (err != nil) != test.wantErr { + t.Errorf("gather(pkgs) got err %v want err? %v", err, test.wantErr) + } + if diff := cmp.Diff(test.want, got, cmpopts.EquateEmpty()); diff != "" { + t.Errorf("gather(pkgs) diff (-want +got):\n%s", diff) + } + }) + } +} + +func TestFormatImports(t *testing.T) { + tests := []struct { + name string + usedPackages map[string]string + want string + }{ + { + name: "Empty", + usedPackages: nil, + want: "", + }, + { + name: "One", + usedPackages: map[string]string{"fmt": ""}, + want: "import \"fmt\"", + }, + { + name: "Two", + usedPackages: map[string]string{ + "fmt": "", + "log": "", + }, + want: "import (\n\t\"fmt\"\n\t\"log\"\n)", + }, + { + name: "Renamed", + usedPackages: map[string]string{ + "fmt": "zzz", + "log": "aaa", + }, + want: "import (\n\tzzz \"fmt\"\n\taaa \"log\"\n)", + }, + { + name: "StdlibSeparateFromThirdParty", + usedPackages: map[string]string{ + "context": "", + "fmt": "", + "log": "", + "github.com/google/go-cmp/cmp": "", + "gocloud.dev/blob": "", + }, + want: "import (\n" + + "\t\"context\"\n" + + "\t\"fmt\"\n" + + "\t\"log\"\n" + + "\n" + + "\t\"github.com/google/go-cmp/cmp\"\n" + + "\t\"gocloud.dev/blob\"\n" + + ")", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := formatImports(test.usedPackages) + if got != test.want { + t.Errorf("formatImports(%+v) =\n%s\n// want:\n%s", test.usedPackages, got, test.want) + } + }) + } +} diff --git a/go-cloud/internal/website/gatherexamples/run.sh b/go-cloud/internal/website/gatherexamples/run.sh new file mode 100755 index 000000000..20bf36e44 --- /dev/null +++ b/go-cloud/internal/website/gatherexamples/run.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Run gatherexamples for the project. +# The output of this script should be piped into +# internal/website/data/examples.json, where it's picked up by Hugo. + +set -eo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")/../../.." +cd internal/website/gatherexamples +go build gatherexamples.go +cd ../../.. +sed -e '/^#/d' -e '/^$/d' allmodules | awk '{print $1}' | xargs internal/website/gatherexamples/gatherexamples diff --git a/go-cloud/internal/website/go.mod b/go-cloud/internal/website/go.mod new file mode 100644 index 000000000..7691f7d47 --- /dev/null +++ b/go-cloud/internal/website/go.mod @@ -0,0 +1,15 @@ +module gocloud.dev/internal/website + +go 1.23.0 + +require ( + github.com/google/go-cmp v0.6.0 + golang.org/x/tools v0.35.0 + golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated +) + +require ( + golang.org/x/mod v0.26.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/tools/go/expect v0.1.0-deprecated // indirect +) diff --git a/go-cloud/internal/website/go.sum b/go-cloud/internal/website/go.sum new file mode 100644 index 000000000..ddef62165 --- /dev/null +++ b/go-cloud/internal/website/go.sum @@ -0,0 +1,12 @@ +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= +golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= +golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= +golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY= +golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= diff --git a/go-cloud/internal/website/layouts/404.html b/go-cloud/internal/website/layouts/404.html new file mode 100644 index 000000000..43de36bb8 --- /dev/null +++ b/go-cloud/internal/website/layouts/404.html @@ -0,0 +1,7 @@ +{{ define "main" }} +

404: Page not found

+

+ Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. + Head back home to try finding it again. +

+{{ end }} diff --git a/go-cloud/internal/website/layouts/_default/baseof.html b/go-cloud/internal/website/layouts/_default/baseof.html new file mode 100644 index 000000000..5f8ac4885 --- /dev/null +++ b/go-cloud/internal/website/layouts/_default/baseof.html @@ -0,0 +1,81 @@ + + + + + {{ .Hugo.Generator }} + + + {{ if .IsHome -}} + {{ .Site.Title }} + {{- else -}} + {{ .Title }} · {{ .Site.Title }} + {{- end }} + + + + + + {{- range .AlternativeOutputFormats }} + + {{- end }} + {{- if .Page.Params.pkgmeta }} + + + {{- end }} + {{ template "_internal/google_analytics_async.html" . }} + + +
+ +
+
+ {{- block "main" .}}{{end -}} +
+
+ + +
+ + diff --git a/go-cloud/internal/website/layouts/_default/li.html b/go-cloud/internal/website/layouts/_default/li.html new file mode 100644 index 000000000..18596ce89 --- /dev/null +++ b/go-cloud/internal/website/layouts/_default/li.html @@ -0,0 +1,5 @@ + diff --git a/go-cloud/internal/website/layouts/_default/list.html b/go-cloud/internal/website/layouts/_default/list.html new file mode 100644 index 000000000..6abf580fc --- /dev/null +++ b/go-cloud/internal/website/layouts/_default/list.html @@ -0,0 +1,14 @@ +{{ define "main" -}} +

{{ .Title }}

+{{ partial "page-toc.html" . }} +{{ partial "header-link.html" .Content }} +{{ with .Data.Pages.GroupBy "Weight" }} +
+{{- range .}} +{{- range .Pages.ByTitle}} + {{.Render "li"}} +{{- end }} +{{- end }} +
+{{end}} +{{- end }} diff --git a/go-cloud/internal/website/layouts/_default/single.html b/go-cloud/internal/website/layouts/_default/single.html new file mode 100644 index 000000000..255d7fa09 --- /dev/null +++ b/go-cloud/internal/website/layouts/_default/single.html @@ -0,0 +1,5 @@ +{{ define "main" -}} +

{{ .Title }}

+{{ partial "page-toc.html" . }} +{{ partial "header-link.html" .Content }} +{{- end }} diff --git a/go-cloud/internal/website/layouts/_default/sitemap.xml b/go-cloud/internal/website/layouts/_default/sitemap.xml new file mode 100644 index 000000000..679af7513 --- /dev/null +++ b/go-cloud/internal/website/layouts/_default/sitemap.xml @@ -0,0 +1,22 @@ +{{ printf "" | safeHTML }} + + {{ range sort .Data.Pages "Permalink" }} + + {{ .Permalink }}{{ if not .Lastmod.IsZero }} + {{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }}{{ end }}{{ with .Sitemap.ChangeFreq }} + {{ . }}{{ end }}{{ if ge .Sitemap.Priority 0.0 }} + {{ .Sitemap.Priority }}{{ end }}{{ if .IsTranslated }}{{ range .Translations }} + {{ end }} + {{ end }} + + {{ end }} + diff --git a/go-cloud/internal/website/layouts/howto/li.html b/go-cloud/internal/website/layouts/howto/li.html new file mode 100644 index 000000000..03aa3ec27 --- /dev/null +++ b/go-cloud/internal/website/layouts/howto/li.html @@ -0,0 +1,3 @@ +
  • + {{ .LinkTitle }} +
  • diff --git a/go-cloud/internal/website/layouts/howto/list.html b/go-cloud/internal/website/layouts/howto/list.html new file mode 100644 index 000000000..2e387d7d6 --- /dev/null +++ b/go-cloud/internal/website/layouts/howto/list.html @@ -0,0 +1,14 @@ +{{ define "main" -}} +

    {{ .Title }}

    +{{ partial "page-toc.html" . }} +{{ partial "header-link.html" .Content }} +{{ if or .Data.Pages }} +
      +{{- range .Data.Pages.GroupBy "Weight" }} +{{- range .ByTitle }} + {{.Render "li"}} +{{- end }} +{{- end }} +
    +{{- end }} +{{- end }} diff --git a/go-cloud/internal/website/layouts/index.html b/go-cloud/internal/website/layouts/index.html new file mode 100644 index 000000000..49d209c7a --- /dev/null +++ b/go-cloud/internal/website/layouts/index.html @@ -0,0 +1,3 @@ +{{ define "main" -}} +{{ partial "header-link.html" .Content }} +{{- end }} diff --git a/go-cloud/internal/website/layouts/partials/header-link.html b/go-cloud/internal/website/layouts/partials/header-link.html new file mode 100644 index 000000000..9a257e28e --- /dev/null +++ b/go-cloud/internal/website/layouts/partials/header-link.html @@ -0,0 +1,2 @@ +{{- /* https://zwbetz.com/create-header-links-hugo-vs-javascript/ */ -}} +{{ . | replaceRE "()(.+)()" `${1} ${3}🔗${4}` | safeHTML -}} diff --git a/go-cloud/internal/website/layouts/partials/hook_head_end.html b/go-cloud/internal/website/layouts/partials/hook_head_end.html new file mode 100644 index 000000000..3a30830b2 --- /dev/null +++ b/go-cloud/internal/website/layouts/partials/hook_head_end.html @@ -0,0 +1,4 @@ +{{if .Page.Params.pkgmeta}} + + +{{end}} diff --git a/go-cloud/internal/website/layouts/partials/page-toc.html b/go-cloud/internal/website/layouts/partials/page-toc.html new file mode 100644 index 000000000..0aa388957 --- /dev/null +++ b/go-cloud/internal/website/layouts/partials/page-toc.html @@ -0,0 +1,6 @@ +{{if .Page.Params.toc}} + +{{end -}} diff --git a/go-cloud/internal/website/layouts/pkg/list.html b/go-cloud/internal/website/layouts/pkg/list.html new file mode 100644 index 000000000..e767a157c --- /dev/null +++ b/go-cloud/internal/website/layouts/pkg/list.html @@ -0,0 +1,11 @@ + + + + + + + + + Nothing to see here; see the package on godoc. + + diff --git a/go-cloud/internal/website/layouts/pkg/single.html b/go-cloud/internal/website/layouts/pkg/single.html new file mode 100644 index 000000000..e767a157c --- /dev/null +++ b/go-cloud/internal/website/layouts/pkg/single.html @@ -0,0 +1,11 @@ + + + + + + + + + Nothing to see here; see the package on godoc. + + diff --git a/go-cloud/internal/website/layouts/shortcodes/goexample.html b/go-cloud/internal/website/layouts/shortcodes/goexample.html new file mode 100644 index 000000000..b3f8ad2a2 --- /dev/null +++ b/go-cloud/internal/website/layouts/shortcodes/goexample.html @@ -0,0 +1,29 @@ +{{/* +Usage: + +goexample "gocloud.dev/foo.ExampleBar" +goexample src="gocloud.dev/foo.ExampleBar" +goexample src="gocloud.dev/foo.ExampleBar" imports="0" + +*/ -}} +{{ if .IsNamedParams -}} + {{ with index .Site.Data.examples (.Get "src") -}} + {{ if and .imports (ne ($.Get "imports") "0") -}} + {{ highlight (printf "%s\n\n%s\n" .imports .code) "go" "" -}} + {{ else -}} + {{ highlight (printf "%s\n" .code) "go" "" -}} + {{ end -}} + {{ else -}} + {{ errorf "%s: Example %q does not exist" ($.Page.File.Path) (.Get "src") -}} + {{end -}} +{{ else -}} + {{ with index .Site.Data.examples (.Get 0) -}} + {{ if .imports -}} + {{ highlight (printf "%s\n\n%s\n" .imports .code) "go" "" -}} + {{ else -}} + {{ highlight (printf "%s\n" .code) "go" "" -}} + {{ end -}} + {{ else -}} + {{ errorf "%s: Example %q does not exist" ($.Page.File.Path) (.Get 0) -}} + {{end -}} +{{ end -}} diff --git a/go-cloud/internal/website/layouts/shortcodes/snippet.html b/go-cloud/internal/website/layouts/shortcodes/snippet.html new file mode 100644 index 000000000..6b1080cbf --- /dev/null +++ b/go-cloud/internal/website/layouts/shortcodes/snippet.html @@ -0,0 +1 @@ +{{ readFile (.Get 0 | printf "/snippets/%s") | markdownify -}} diff --git a/go-cloud/internal/website/listnewpkgs.sh b/go-cloud/internal/website/listnewpkgs.sh new file mode 100755 index 000000000..2d5d50908 --- /dev/null +++ b/go-cloud/internal/website/listnewpkgs.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# This script lists the package names that makeimports.sh would create +# _index.md files for, one per line. + + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +# except x is too verbose +set -euo pipefail + +# Change into repository root. +cd "$(dirname "$0")/../.." +OUTDIR=internal/website/content + +shopt -s nullglob # glob patterns that don't match turn into the empty string, instead of themselves + +function files_exist() { # assumes nullglob + [[ ${1:-""} != "" ]] +} + +# Find all directories that do not begin with '.' or '_' or contain 'testdata'. Use the %P printf +# directive to remove the initial './'. +for pkg in $(find . -type d \( -name '[._]?*' -prune -o -name testdata -prune -o -printf '%P ' \)); do + # Only consider directories that contain Go source files. + outfile="$OUTDIR/$pkg/_index.md" + if files_exist $pkg/*.go && [[ ! -e "$outfile" ]]; then + echo "$pkg" + fi +done + diff --git a/go-cloud/internal/website/makeimports.sh b/go-cloud/internal/website/makeimports.sh new file mode 100755 index 000000000..c002c346a --- /dev/null +++ b/go-cloud/internal/website/makeimports.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +# This script generates Markdown files that will include suitable for +# "go get"'s import path redirection feature (see +# https://golang.org/cmd/go/#hdr-Remote_import_paths) in the final Hugo output. + + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +# except x is too verbose +set -euo pipefail + +# Change into repository root. +cd "$(dirname "$0")/../.." +OUTDIR=internal/website/content + +for pkg in $(internal/website/listnewpkgs.sh); do + # Only consider directories that contain Go source files. + outfile="$OUTDIR/$pkg/_index.md" + mkdir -p "$OUTDIR/$pkg" + echo "Generating gocloud.dev/$pkg" + echo "---" >> "$outfile" + echo "title: gocloud.dev/$pkg" >> "$outfile" + echo "type: pkg" >> "$outfile" + echo "---" >> "$outfile" +done + diff --git a/go-cloud/internal/website/static/css/style.css b/go-cloud/internal/website/static/css/style.css new file mode 100644 index 000000000..4942102f3 --- /dev/null +++ b/go-cloud/internal/website/static/css/style.css @@ -0,0 +1,367 @@ +/* +Copyright 2019 The Go Cloud Development Kit 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 + + https://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. +*/ + +/* Basic layout {{{1 */ +html { + font: 14px/1.5 'Roboto', sans-serif; + margin: 0; + padding: 0; +} +@media (min-width: 768px) { + html { + font-size: 16px; + } +} +body { + background: #fff; + color: #000; + margin: 0; + padding: 0; +} +.PageLayout { + display: grid; + grid-template-columns: 15rem 1fr; + grid-template-rows: minmax(4rem, auto) 1fr minmax(4rem, auto); + grid-template-areas: + 'hd hd' + 'sd main' + 'ft ft'; + margin: 0; + min-height: 100vh; + padding: 0; + width: 100vw; +} +@media (max-width: 768px) { + .PageLayout { + grid-template-columns: 100%; + grid-template-areas: 'hd' 'main' 'sd' 'ft'; + } +} +.PageHeader { + background: #00add8; + grid-area: hd; + margin: 0; + padding: 0; +} +.PageLogo { + box-sizing: border-box; + margin: 0 auto; + padding: 1.25rem 0; + text-align: center; + width: 20rem; +} +.PageLogo-image { + height: 80px; +} +@media (max-width: 768px) { + .PageLogo-image { + height: 72px; + } +} +.MainContent { + box-sizing: border-box; + grid-area: main; + margin: 0; + overflow-x: hidden; /* creates a new block formatting context for children overflows */ + padding: 2rem 2rem 3rem; +} +.MainContent-bounds { + box-sizing: border-box; + margin: 0; + padding: 0; + max-width: 50rem; +} +.Sidenav { + background: #dbd9d6; + box-sizing: border-box; + font-family: 'Work Sans', 'Roboto', sans-serif; + font-size: 0.8rem; + grid-area: sd; + margin: 0; + padding: 1rem 2rem 2rem 1rem; +} +.Sidenav-list { + margin: 0; + padding: 0; + list-style: none; +} +.Sidenav-pageList { + margin: 0 0 0 2rem; + padding: 0; + list-style: none; +} +.Sidenav-section { + margin: 0.5rem 0 0; + padding: 0; +} +.Sidenav-sectionLink { + color: #000; + font-weight: bold; + text-decoration: none; +} +.Sidenav-page { + margin: 0.3rem 0 0; + padding: 0; +} +.Sidenav-pageLink { + color: #000; + font-weight: normal; + text-decoration: none; +} +.Sidenav-sectionLink:hover, +.Sidenav-sectionLink:active, +.Sidenav-pageLink:hover, +.Sidenav-pageLink:active { + text-decoration: underline; +} +.PageTOC { + border-left: 2px solid #dbd9d6; + float: right; + margin: 0.25rem 0 1rem 2rem; + max-width: 25%; + min-width: 15%; + padding: 0.5rem 0 0.5rem 1rem; +} +@media (max-width: 1024px) { + .PageTOC { + border: none; + float: none; + margin: 1.5rem 0 0.5rem; + max-width: none; + min-width: none; + padding: 0; + } +} +.PageTOC { + font-size: 0.85rem; +} +.PageTOC-heading { + font: 700 1rem/1.25 'Work Sans', 'Roboto', sans-serif; + margin: 0 0 0.5rem; + text-rendering: optimizeLegibility; +} +.PageTOC>nav>ul>li>ul { + /* Don't indent top-level list. */ + margin: 0; +} +.PageTOC ul { + list-style: none; + margin: 0 0 0 1rem; + padding: 0; +} +.PageTOC li { + margin: 0.3rem 0; + padding: 0; +} +.PageTOC>nav>ul { + /* CSS trick to remove h1 level from TOC. + * https://github.com/gohugoio/hugo/issues/1778 */ + display: block; + margin: 0; + padding: 0; +} +.PageTOC>nav>ul>li { + /* CSS trick to remove h1 level from TOC. + * https://github.com/gohugoio/hugo/issues/1778 */ + display: block; + margin: 0; + padding: 0; +} +.PageFooter { + background: #555759; + box-sizing: border-box; + color: #ffffff; + font-size: 0.95rem; + grid-area: ft; + line-height: 1; + margin: 0; + padding: 2rem 2rem 1rem; +} +.PageFooter-paragraph { + margin: 1em auto; + max-width: 40rem; + text-align: justify; +} +.PageFooter-link { + color: #ffffff; + text-decoration: underline; +} +.FooterLinks { + box-sizing: border-box; + font-size: 1rem; + line-height: 1.5; + list-style: none; + margin: 0 auto 2rem; + padding: 0; + max-width: 40rem; +} +.FooterLinks-item { + margin: 0; + padding: 0; + text-align: justify; +} +.FooterLinks-link { + color: #9eecff; + text-decoration: none; +} +.FooterLinks-link:hover, +.FooterLinks-link:active { + text-decoration: underline; +} +.PageList { + box-sizing: border-box; + display: grid; + grid-auto-rows: fit-content(5rem); + grid-template-columns: repeat(2, minmax(15rem, 1fr)); + margin: 0; + padding: 0; +} +@media (max-width: 768px) { + .PageList { + grid-template-columns: minmax(15rem, 1fr); + } +} +.PageList-item { + box-sizing: border-box; + display: flex; + flex-direction: column; + margin: 0 0.5rem; + padding: 0 1rem; + place-content: start; +} +.PageList-itemTitle { + color: #000; +} +.PageList-summary { + flex: 1; + margin: 0; + padding: 0; +} +.PageList-readMore { + margin: 1rem 0 0; + padding: 0; +} +.HowtoList { + font: 300 1.5rem/1.25 'Roboto', sans-serif; + margin: 1rem 0 0; + padding: 0; +} +.HowtoList-item { + margin: 0.5rem 0 0.5rem 2rem; + padding: 0; +} + +/* Content styling {{{1 */ +/* Headings */ +.MainContent h1 { + font: 700 2rem/1.25 'Work Sans', 'Roboto', sans-serif; + margin: 0 0 0.5rem; + text-rendering: optimizeLegibility; +} +.MainContent h2 { + font: 700 1.5rem/1.25 'Work Sans', 'Roboto', sans-serif; + margin: 2rem 0 0.5rem; + text-rendering: optimizeLegibility; +} +.MainContent h3 { + font: 700 1.25rem/1.25 'Work Sans', 'Roboto', sans-serif; + margin: 3rem 0 0.5rem; + text-rendering: optimizeLegibility; +} +.MainContent h4, +.MainContent h5, +.MainContent h6 { + font: 700 1rem/1.25 'Work Sans', 'Roboto', sans-serif; + margin: 2rem 0 0.5rem; + text-rendering: optimizeLegibility; +} +.MainContent h1 .anchor, +.MainContent h2 .anchor, +.MainContent h3 .anchor, +.MainContent h4 .anchor, +.MainContent h5 .anchor, +.MainContent h6 .anchor { + display: none; + font-size: 1rem; + margin: 0 0.2rem; +} +.MainContent h1 :link:hover, +.MainContent h2 :link:hover, +.MainContent h3 :link:hover, +.MainContent h4 :link:hover, +.MainContent h5 :link:hover, +.MainContent h6 :link:hover { + text-decoration: none; +} +.MainContent h1:hover .anchor, +.MainContent h2:hover .anchor, +.MainContent h3:hover .anchor, +.MainContent h4:hover .anchor, +.MainContent h5:hover .anchor, +.MainContent h6:hover .anchor { + display: inline; +} +/* Code */ +.MainContent code { + font-size: 85%; + font-family: 'Source Code Pro', monospace; +} +.MainContent pre { + box-sizing: border-box; + background: #f9f9f9; + border-radius: 4px; + display: block; + font: 0.8rem/1.4 'Source Code Pro', monospace; + margin: 0 0 1rem; + overflow-x: auto; + padding: 1rem; + white-space: pre; + width: 100%; +} +.MainContent pre code { + font-size: 100%; +} +.highlight { + box-sizing: border-box; + margin: 0; + padding: 0; + width: 100%; +} +/* Figures */ +.FullWidthFigure { + border: thin solid #dbd9d6; + border-radius: 4px; + margin: 1rem 0; + padding: 0.5rem 0; +} +.FullWidthFigure img { + width: 100%; +} +/* Links */ +.MainContent :link { + color: #00758d; + text-decoration: none; +} +.MainContent :visited { + color: #00758d; + text-decoration: none; +} +.MainContent :link:hover, +.MainContent :link:focus, +.MainContent :visited:hover, +.MainContent :visited:focus { + text-decoration: underline; +} diff --git a/go-cloud/internal/website/static/css/syntax.css b/go-cloud/internal/website/static/css/syntax.css new file mode 100644 index 000000000..e22d015c8 --- /dev/null +++ b/go-cloud/internal/website/static/css/syntax.css @@ -0,0 +1,45 @@ +/* Keyword */ .chroma .k { color: #00758d; font-weight: bold } +/* KeywordConstant */ .chroma .kc { color: #00758d; font-weight: bold } +/* KeywordDeclaration */ .chroma .kd { color: #00758d; font-weight: bold } +/* KeywordNamespace */ .chroma .kn { color: #00758d; font-weight: bold } +/* KeywordPseudo */ .chroma .kp { color: #00758d } +/* KeywordReserved */ .chroma .kr { color: #00758d; font-weight: bold } +/* KeywordType */ .chroma .kt { color: #00758d } +/* NameBuiltin */ .chroma .nb { color: #00758d } +/* LiteralString */ .chroma .s { color: #ce3262 } +/* LiteralStringAffix */ .chroma .sa { color: #ce3262 } +/* LiteralStringBacktick */ .chroma .sb { color: #ce3262 } +/* LiteralStringChar */ .chroma .sc { color: #ce3262 } +/* LiteralStringDelimiter */ .chroma .dl { color: #ce3262 } +/* LiteralStringDoc */ .chroma .sd { color: #ce3262; font-style: italic } +/* LiteralStringDouble */ .chroma .s2 { color: #ce3262 } +/* LiteralStringEscape */ .chroma .se { color: #ce3262; font-weight: bold } +/* LiteralStringHeredoc */ .chroma .sh { color: #ce3262 } +/* LiteralStringInterpol */ .chroma .si { color: #ce3262; font-style: italic } +/* LiteralStringOther */ .chroma .sx { color: #ce3262 } +/* LiteralStringRegex */ .chroma .sr { color: #ce3262 } +/* LiteralStringSingle */ .chroma .s1 { color: #ce3262 } +/* LiteralStringSymbol */ .chroma .ss { color: #ce3262 } +/* LiteralNumber */ .chroma .m { color: #ce3262 } +/* LiteralNumberBin */ .chroma .mb { color: #ce3262 } +/* LiteralNumberFloat */ .chroma .mf { color: #ce3262 } +/* LiteralNumberHex */ .chroma .mh { color: #ce3262 } +/* LiteralNumberInteger */ .chroma .mi { color: #ce3262 } +/* LiteralNumberIntegerLong */ .chroma .il { color: #ce3262 } +/* LiteralNumberOct */ .chroma .mo { color: #ce3262 } +/* Comment */ .chroma .c { color: #555759; font-style: italic } +/* CommentHashbang */ .chroma .ch { color: #555759; font-style: italic } +/* CommentMultiline */ .chroma .cm { color: #555759; font-style: italic } +/* CommentSingle */ .chroma .c1 { color: #555759; font-style: italic } +/* CommentSpecial */ .chroma .cs { color: #555759; font-style: italic } +/* CommentPreproc */ .chroma .cp { color: #555759; font-style: italic } +/* CommentPreprocFile */ .chroma .cpf { color: #555759; font-style: italic } +/* GenericDeleted */ .chroma .gd { color: #a00000 } +/* GenericEmph */ .chroma .ge { font-style: italic } +/* GenericError */ .chroma .gr { color: #ff0000 } +/* GenericHeading */ .chroma .gh { font-weight: bold } +/* GenericInserted */ .chroma .gi { color: #00a000 } +/* GenericPrompt */ .chroma .gp { font-weight: bold } +/* GenericStrong */ .chroma .gs { font-weight: bold } +/* GenericSubheading */ .chroma .gu { font-weight: bold } +/* GenericUnderline */ .chroma .gl { text-decoration: underline } diff --git a/go-cloud/internal/website/static/favicon-32x32.png b/go-cloud/internal/website/static/favicon-32x32.png new file mode 100644 index 000000000..f406f9cb0 Binary files /dev/null and b/go-cloud/internal/website/static/favicon-32x32.png differ diff --git a/go-cloud/internal/website/static/gh.png b/go-cloud/internal/website/static/gh.png new file mode 100644 index 000000000..628da97c7 Binary files /dev/null and b/go-cloud/internal/website/static/gh.png differ diff --git a/go-cloud/internal/website/static/go-cdk-logo-gopherblue-small.png b/go-cloud/internal/website/static/go-cdk-logo-gopherblue-small.png new file mode 100644 index 000000000..1a548dfe1 Binary files /dev/null and b/go-cloud/internal/website/static/go-cdk-logo-gopherblue-small.png differ diff --git a/go-cloud/internal/website/static/go-cdk-logo-gopherblue.png b/go-cloud/internal/website/static/go-cdk-logo-gopherblue.png new file mode 100644 index 000000000..19cccb47c Binary files /dev/null and b/go-cloud/internal/website/static/go-cdk-logo-gopherblue.png differ diff --git a/go-cloud/internal/website/static/go-cdk-logo-white.png b/go-cloud/internal/website/static/go-cdk-logo-white.png new file mode 100644 index 000000000..300938e5a Binary files /dev/null and b/go-cloud/internal/website/static/go-cdk-logo-white.png differ diff --git a/go-cloud/internal/website/static/placeholder-logo.png b/go-cloud/internal/website/static/placeholder-logo.png new file mode 100644 index 000000000..8320a2021 Binary files /dev/null and b/go-cloud/internal/website/static/placeholder-logo.png differ diff --git a/go-cloud/mysql/awsmysql/awsmysql.go b/go-cloud/mysql/awsmysql/awsmysql.go new file mode 100644 index 000000000..d75a85085 --- /dev/null +++ b/go-cloud/mysql/awsmysql/awsmysql.go @@ -0,0 +1,142 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awsmysql provides connections to AWS RDS MySQL instances. +// +// # URLs +// +// For mysql.Open, awsmysql registers for the scheme "awsmysql". +// The default URL opener will create a connection using the default +// credentials from the environment, as described in +// https://docs.aws.amazon.com/sdk-for-go/api/aws/session/. +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// +// See https://gocloud.dev/concepts/urls/ for background information. +package awsmysql // import "gocloud.dev/mysql/awsmysql" + +import ( + "context" + "crypto/tls" + "database/sql" + "database/sql/driver" + "fmt" + "net/url" + + "github.com/XSAM/otelsql" + "github.com/go-sql-driver/mysql" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/aws/rds" + gcmysql "github.com/DataDog/iceberg-go/go-cloud/mysql" +) + +// Set is a Wire provider set that provides a *sql.DB given +// *Params and an HTTP client. +var Set = wire.NewSet( + wire.Struct(new(URLOpener), "CertSource"), + rds.CertFetcherSet, +) + +// URLOpener opens RDS MySQL URLs +// like "awsmysql://user:password@myinstance.borkxyzzy.us-west-1.rds.amazonaws.com:3306/mydb". +type URLOpener struct { + // CertSource specifies how the opener will obtain the RDS Certificate + // Authority. If nil, it will use the default *rds.CertFetcher. + CertSource rds.CertPoolProvider + // TraceOpts contains options for OpenTelemetry. + TraceOpts []otelsql.Option +} + +// Scheme is the URL scheme awsmysql registers its URLOpener under on +// mysql.DefaultMux. +const Scheme = "awsmysql" + +func init() { + gcmysql.DefaultURLMux().RegisterMySQL(Scheme, &URLOpener{}) +} + +// OpenMySQLURL opens a new RDS database connection wrapped with OpenTelemetry instrumentation. +func (uo *URLOpener) OpenMySQLURL(_ context.Context, u *url.URL) (*sql.DB, error) { + source := uo.CertSource + if source == nil { + source = new(rds.CertFetcher) + } + if u.Host == "" { + return nil, fmt.Errorf("open RDS: empty endpoint") + } + + cfg, err := gcmysql.ConfigFromURL(u) + if err != nil { + return nil, err + } + c := &connector{ + dsn: cfg.FormatDSN(), + // Make a copy of TraceOpts to avoid caller modifying. + traceOpts: append([]otelsql.Option(nil), uo.TraceOpts...), + provider: source, + + sem: make(chan struct{}, 1), + ready: make(chan struct{}), + } + c.sem <- struct{}{} + return sql.OpenDB(c), nil +} + +type connector struct { + traceOpts []otelsql.Option + + sem chan struct{} // receive to acquire, send to release + provider CertPoolProvider + + ready chan struct{} // closed after resolving dsn + dsn string +} + +func (c *connector) Connect(ctx context.Context) (driver.Conn, error) { + select { + case <-c.sem: + certPool, err := c.provider.RDSCertPool(ctx) + if err != nil { + c.sem <- struct{}{} // release + return nil, fmt.Errorf("connect RDS: %v", err) + } + cfg, err := mysql.ParseDSN(c.dsn) + if err != nil { + c.sem <- struct{}{} // release + return nil, fmt.Errorf("connect RDS: parse DSN: %v", err) + } + cfg.TLS = &tls.Config{ + RootCAs: certPool, + } + c.dsn = cfg.FormatDSN() + close(c.ready) + // Don't release sem: make it block forever, so this case won't be run again. + case <-c.ready: + // Already succeeded. + case <-ctx.Done(): + return nil, fmt.Errorf("connect RDS: waiting for certificates: %v", ctx.Err()) + } + return c.Driver().Open(c.dsn) +} + +func (c *connector) Driver() driver.Driver { + return otelsql.WrapDriver(mysql.MySQLDriver{}, c.traceOpts...) +} + +// A CertPoolProvider obtains a certificate pool that contains the RDS CA certificate. +type CertPoolProvider = rds.CertPoolProvider + +// CertFetcher pulls the RDS CA certificates from Amazon's servers. The zero +// value will fetch certificates using the default HTTP client. +type CertFetcher = rds.CertFetcher diff --git a/go-cloud/mysql/awsmysql/awsmysql_test.go b/go-cloud/mysql/awsmysql/awsmysql_test.go new file mode 100644 index 000000000..1f759d0bf --- /dev/null +++ b/go-cloud/mysql/awsmysql/awsmysql_test.go @@ -0,0 +1,58 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awsmysql + +import ( + "context" + "fmt" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/terraform" + "github.com/DataDog/iceberg-go/go-cloud/mysql" +) + +func TestOpen(t *testing.T) { + // This test will be skipped unless the project is set up with Terraform. + // Before running go test, run in this directory: + // + // terraform init + // terraform apply + + tfOut, err := terraform.ReadOutput(".") + if err != nil || len(tfOut) == 0 { + t.Skipf("Could not obtain harness info: %v", err) + } + endpoint, _ := tfOut["endpoint"].Value.(string) + username, _ := tfOut["username"].Value.(string) + password, _ := tfOut["password"].Value.(string) + databaseName, _ := tfOut["database"].Value.(string) + if endpoint == "" || username == "" || databaseName == "" { + t.Fatalf("Missing one or more required Terraform outputs; got endpoint=%q username=%q database=%q", endpoint, username, databaseName) + } + + ctx := context.Background() + urlstr := fmt.Sprintf("awsmysql://%s:%s@%s/%s", username, password, endpoint, databaseName) + t.Log("Connecting to:", urlstr) + db, err := mysql.Open(ctx, urlstr) + if err != nil { + t.Fatal(err) + } + if err := db.Ping(); err != nil { + t.Error("Ping:", err) + } + if err := db.Close(); err != nil { + t.Error("Close:", err) + } +} diff --git a/go-cloud/mysql/awsmysql/example_test.go b/go-cloud/mysql/awsmysql/example_test.go new file mode 100644 index 000000000..0f5f6cc5a --- /dev/null +++ b/go-cloud/mysql/awsmysql/example_test.go @@ -0,0 +1,41 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awsmysql_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/mysql" + _ "github.com/DataDog/iceberg-go/go-cloud/mysql/awsmysql" +) + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/mysql/awsmysql" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Replace these with your actual settings. + db, err := mysql.Open(ctx, + "awsmysql://myrole:swordfish@example01.xyzzy.us-west-1.rds.amazonaws.com/testdb") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + // Use database in your program. + db.ExecContext(ctx, "CREATE TABLE foo (bar INT);") +} diff --git a/go-cloud/mysql/awsmysql/main.tf b/go-cloud/mysql/awsmysql/main.tf new file mode 100644 index 000000000..12c46db85 --- /dev/null +++ b/go-cloud/mysql/awsmysql/main.tf @@ -0,0 +1,99 @@ +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +# Harness for MySQL tests. + +terraform { + required_version = "~>0.12" +} + +provider "aws" { + version = "~> 2.7" + region = var.region +} + +provider "random" { + version = "~> 2.1" +} + +variable "region" { + type = string + description = "Region to create resources in. See https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html for valid values." +} + +resource "aws_security_group" "main" { + name_prefix = "testdb" + description = "Security group for the Go CDK MySQL test database." + + ingress { + from_port = 3306 + to_port = 3306 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + description = "Public MySQL access" + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + description = "All outgoing traffic allowed" + } +} + +resource "random_string" "db_password" { + keepers = { + region = var.region + } + + special = false + length = 20 +} + +resource "aws_db_instance" "main" { + identifier_prefix = "go-cloud-test" + engine = "mysql" + engine_version = "5.6.39" + instance_class = "db.t2.micro" + allocated_storage = 20 + username = "root" + password = random_string.db_password.result + name = "testdb" + publicly_accessible = true + vpc_security_group_ids = [aws_security_group.main.id] + skip_final_snapshot = true +} + +output "endpoint" { + value = aws_db_instance.main.endpoint + description = "The RDS instance's host/port." +} + +output "username" { + value = "root" + description = "The MySQL username to connect with." +} + +output "password" { + value = random_string.db_password.result + sensitive = true + description = "The RDS instance password for the user." +} + +output "database" { + value = "testdb" + description = "The name of the database inside the RDS instance." +} + diff --git a/go-cloud/mysql/azuremysql/azuremysql.go b/go-cloud/mysql/azuremysql/azuremysql.go new file mode 100644 index 000000000..7f66f3b8e --- /dev/null +++ b/go-cloud/mysql/azuremysql/azuremysql.go @@ -0,0 +1,138 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 azuremysql provides connections to Azure Database for MySQL. +// See https://docs.microsoft.com/en-us/azure/mysql. +// +// # URLs +// +// For mysql.Open, azuremysql registers for the scheme "azuremysql". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// +// See https://gocloud.dev/concepts/urls/ for background information. +package azuremysql // import "gocloud.dev/mysql/azuremysql" + +import ( + "context" + "crypto/tls" + "database/sql" + "database/sql/driver" + "fmt" + "net/url" + "strings" + + "github.com/XSAM/otelsql" + "github.com/go-sql-driver/mysql" + "github.com/DataDog/iceberg-go/go-cloud/azure/azuredb" + cdkmysql "github.com/DataDog/iceberg-go/go-cloud/mysql" +) + +// URLOpener opens Azure MySQL URLs +// like "azuremysql://user:password@myinstance.mysql.database.azure.com/mydb". +type URLOpener struct { + // CertSource specifies how the opener will obtain the Azure Certificate + // Authority. If nil, it will use the default *azuredb.CertFetcher. + CertSource azuredb.CertPoolProvider + // TraceOpts contains options for OpenTelemetry. + TraceOpts []otelsql.Option +} + +// Scheme is the URL scheme azuremysql registers its URLOpener under on +// mysql.DefaultMux. +const Scheme = "azuremysql" + +func init() { + cdkmysql.DefaultURLMux().RegisterMySQL(Scheme, &URLOpener{}) +} + +// OpenMySQLURL opens an encrypted connection to an Azure MySQL database. +func (uo *URLOpener) OpenMySQLURL(ctx context.Context, u *url.URL) (*sql.DB, error) { + source := uo.CertSource + if source == nil { + source = new(azuredb.CertFetcher) + } + if u.Host == "" { + return nil, fmt.Errorf("open Azure database: empty endpoint") + } + password, _ := u.User.Password() + c := &connector{ + addr: u.Host, + user: u.User.Username(), + password: password, + dbName: strings.TrimPrefix(u.Path, "/"), + // Make a copy of TraceOpts to avoid caller modifying. + traceOpts: append([]otelsql.Option(nil), uo.TraceOpts...), + provider: source, + + sem: make(chan struct{}, 1), + ready: make(chan struct{}), + } + c.sem <- struct{}{} + return sql.OpenDB(c), nil +} + +type connector struct { + addr string + user string + password string + dbName string + traceOpts []otelsql.Option + + sem chan struct{} // receive to acquire, send to release + provider CertPoolProvider // provides the CA certificate pool + + ready chan struct{} // closed after writing dsn + dsn string +} + +func (c *connector) Connect(ctx context.Context) (driver.Conn, error) { + select { + case <-c.sem: + certPool, err := c.provider.AzureCertPool(ctx) + if err != nil { + c.sem <- struct{}{} // release + return nil, fmt.Errorf("connect Azure MySql: %v", err) + } + cfg := &mysql.Config{ + Net: "tcp", + Addr: c.addr, + User: c.user, + Passwd: c.password, + TLS: &tls.Config{RootCAs: certPool}, + AllowCleartextPasswords: true, + AllowNativePasswords: true, + DBName: c.dbName, + } + c.dsn = cfg.FormatDSN() + close(c.ready) + // Don't release sem: make it block forever, so this case won't be run again. + case <-c.ready: + // Already succeeded. + case <-ctx.Done(): + return nil, fmt.Errorf("connect Azure MySql: waiting for certificates: %v", ctx.Err()) + } + return c.Driver().Open(c.dsn) +} + +func (c *connector) Driver() driver.Driver { + return otelsql.WrapDriver(mysql.MySQLDriver{}, c.traceOpts...) +} + +// A CertPoolProvider obtains a certificate pool that contains the Azure CA certificate. +type CertPoolProvider = azuredb.CertPoolProvider + +// CertFetcher is a default CertPoolProvider that can fetch CA certificates from +// any publicly accessible URI or File. +type CertFetcher = azuredb.CertFetcher diff --git a/go-cloud/mysql/azuremysql/azuremysql_test.go b/go-cloud/mysql/azuremysql/azuremysql_test.go new file mode 100644 index 000000000..a69407023 --- /dev/null +++ b/go-cloud/mysql/azuremysql/azuremysql_test.go @@ -0,0 +1,67 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// Read the documentation on Azure Database for MySql for more information. +// See https://docs.microsoft.com/en-us/azure/mysql/howto-configure-ssl. +// To run this test, create a MySQL instance using Azure Portal or Terraform. +// For Azure Portal, see https://docs.microsoft.com/en-us/azure/mysql/quickstart-create-mysql-server-database-using-azure-portal. +// For Terraform, see https://www.terraform.io/docs/providers/azurerm/r/mysql_database.html. +package azuremysql + +import ( + "context" + "fmt" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/terraform" + "github.com/DataDog/iceberg-go/go-cloud/mysql" +) + +func TestURLOpener(t *testing.T) { + // This test will be skipped unless the project is set up with Terraform. + // Before running go test: + // + // 1. Install Azure CLI (az) (https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-linux) + // 2. Run "az login" + // 3. terraform init + // 4. terraform apply + + tfOut, err := terraform.ReadOutput(".") + if err != nil || len(tfOut) == 0 { + t.Skipf("Could not obtain harness info: %v", err) + } + + serverName, _ := tfOut["servername"].Value.(string) + username, _ := tfOut["username"].Value.(string) + password, _ := tfOut["password"].Value.(string) + databaseName, _ := tfOut["database"].Value.(string) + + ctx := context.Background() + db, err := mysql.Open(ctx, fmt.Sprintf("azuremysql://%s:%s@%s/%s", username, password, serverName, databaseName)) + if err != nil { + t.Fatal(err) + } + if err := db.Ping(); err != nil { + t.Error("Ping: ", err) + } + if _, err = db.ExecContext(ctx, "CREATE TABLE tblTester (id INT NOT NULL, PRIMARY KEY(id))"); err != nil { + t.Error("ExecContext: ", err) + } + if _, err = db.ExecContext(ctx, "DROP TABLE tblTester"); err != nil { + t.Error("ExecContext: ", err) + } + if err := db.Close(); err != nil { + t.Error("Close: ", err) + } +} diff --git a/go-cloud/mysql/azuremysql/example_test.go b/go-cloud/mysql/azuremysql/example_test.go new file mode 100644 index 000000000..84b740b4e --- /dev/null +++ b/go-cloud/mysql/azuremysql/example_test.go @@ -0,0 +1,41 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 azuremysql_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/mysql" + _ "github.com/DataDog/iceberg-go/go-cloud/mysql/azuremysql" +) + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/mysql/azuremysql" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Replace this with your actual settings. + db, err := mysql.Open(ctx, + "azuremysql://user:password@example00.mysql.database.azure.com/testdb") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + // Use database in your program. + db.Exec("CREATE TABLE foo (bar INT);") +} diff --git a/go-cloud/mysql/azuremysql/main.tf b/go-cloud/mysql/azuremysql/main.tf new file mode 100644 index 000000000..660fe001f --- /dev/null +++ b/go-cloud/mysql/azuremysql/main.tf @@ -0,0 +1,107 @@ +terraform { + required_version = "~>0.12" +} + +# See documentation for more info: https://www.terraform.io/docs/providers/azurerm/auth/azure_cli.html +provider "azurerm" { + version = "~> 1.22" +} + +provider "random" { + version = "~> 2.1" +} + +# Run Azure CLI command "az account list-locations" to see list of all locations. +variable "location" { + description = "The Azure Region in which all resources in this example should be created." +} + +# See documentation for more info: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview +variable "resourcegroup" { + description = "The Azure Resource Group Name within your Subscription in which this resource will be created." +} + +resource "random_string" "db_password" { + keepers = { + region = var.location + } + + special = false + length = 20 +} + +resource "random_id" "serverid" { + keepers = { + region = var.location + } + + byte_length = 2 +} + +resource "azurerm_resource_group" "mysqlrg" { + name = var.resourcegroup + location = var.location +} + +resource "azurerm_mysql_server" "mysqlserver" { + name = format("go-cdk-test-%v", random_id.serverid.dec) + location = azurerm_resource_group.mysqlrg.location + resource_group_name = azurerm_resource_group.mysqlrg.name + + sku { + name = "B_Gen5_2" + capacity = 2 + tier = "Basic" + family = "Gen5" + } + + storage_profile { + storage_mb = 5120 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } + + administrator_login = "gocloudadmin" + administrator_login_password = random_string.db_password.result + version = "5.7" + ssl_enforcement = "Enabled" +} + +# See documentation for more info: https://www.terraform.io/docs/providers/azurerm/r/sql_firewall_rule.html +resource "azurerm_mysql_firewall_rule" "addrule" { + name = "ClientIPAddress" + resource_group_name = azurerm_resource_group.mysqlrg.name + server_name = azurerm_mysql_server.mysqlserver.name + start_ip_address = "0.0.0.0" + end_ip_address = "255.255.255.255" +} + +resource "azurerm_mysql_database" "mysqldb" { + name = "testdb" + resource_group_name = azurerm_resource_group.mysqlrg.name + server_name = azurerm_mysql_server.mysqlserver.name + charset = "utf8" + collation = "utf8_unicode_ci" +} + +output "username" { + value = "${azurerm_mysql_server.mysqlserver.administrator_login}@${azurerm_mysql_server.mysqlserver.name}" + description = "The MySQL username to connect with." +} + +output "password" { + value = random_string.db_password.result + sensitive = true + description = "The MySQL instance password for the user." +} + +output "servername" { + value = azurerm_mysql_server.mysqlserver.fqdn + description = "The host name of the Azure Database for MySQL instance." +} + +output "database" { + value = "testdb" + description = "The databasename of the Azure Database for MySQL instance." +} + diff --git a/go-cloud/mysql/example_test.go b/go-cloud/mysql/example_test.go new file mode 100644 index 000000000..180295778 --- /dev/null +++ b/go-cloud/mysql/example_test.go @@ -0,0 +1,38 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mysql_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/mysql" +) + +func ExampleOpen() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Replace this with your actual settings. + db, err := mysql.Open(ctx, "mysql://user:password@localhost/testdb") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + // Use database in your program. + db.Exec("CREATE TABLE foo (bar INT);") +} diff --git a/go-cloud/mysql/gcpmysql/example_test.go b/go-cloud/mysql/gcpmysql/example_test.go new file mode 100644 index 000000000..4bcc7ad64 --- /dev/null +++ b/go-cloud/mysql/gcpmysql/example_test.go @@ -0,0 +1,41 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcpmysql_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/mysql" + _ "github.com/DataDog/iceberg-go/go-cloud/mysql/gcpmysql" +) + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/mysql/gcpmysql" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Replace this with your actual settings. + db, err := mysql.Open(ctx, + "gcpmysql://user:password@example-project/region/my-instance01/testdb") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + // Use database in your program. + db.Exec("CREATE TABLE foo (bar INT);") +} diff --git a/go-cloud/mysql/gcpmysql/gcpmysql.go b/go-cloud/mysql/gcpmysql/gcpmysql.go new file mode 100644 index 000000000..21ecb00c7 --- /dev/null +++ b/go-cloud/mysql/gcpmysql/gcpmysql.go @@ -0,0 +1,174 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcpmysql provides connections to managed MySQL Cloud SQL instances. +// See https://cloud.google.com/sql/docs/mysql/ for more information. +// +// # URLs +// +// For mysql.Open, gcpmysql registers for the scheme "gcpmysql". +// The default URL opener will create a connection using the default +// credentials from the environment, as described in +// https://cloud.google.com/docs/authentication/production. +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// +// See https://gocloud.dev/concepts/urls/ for background information. +package gcpmysql // import "gocloud.dev/mysql/gcpmysql" + +import ( + "context" + "database/sql" + "database/sql/driver" + "fmt" + "net/url" + "strings" + "sync" + "sync/atomic" + + "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/proxy" + "github.com/XSAM/otelsql" + "github.com/go-sql-driver/mysql" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/gcp/cloudsql" + cdkmysql "github.com/DataDog/iceberg-go/go-cloud/mysql" +) + +// Scheme is the URL scheme gcpmysql registers its URLOpener under on +// mysql.DefaultMux. +const Scheme = "gcpmysql" + +func init() { + cdkmysql.DefaultURLMux().RegisterMySQL(Scheme, new(lazyCredsOpener)) +} + +// lazyCredsOpener obtains Application Default Credentials on the first call +// to OpenMySQLURL. +type lazyCredsOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazyCredsOpener) OpenMySQLURL(ctx context.Context, u *url.URL) (*sql.DB, error) { + o.init.Do(func() { + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + o.err = err + return + } + client, err := gcp.NewHTTPClient(gcp.DefaultTransport(), creds.TokenSource) + if err != nil { + o.err = err + return + } + certSource := cloudsql.NewCertSource(client) + o.opener = &URLOpener{CertSource: certSource} + }) + if o.err != nil { + return nil, fmt.Errorf("gcpmysql open %v: %v", u, o.err) + } + return o.opener.OpenMySQLURL(ctx, u) +} + +// URLOpener opens Cloud MySQL URLs like +// "gcpmysql://user:password@project/region/instance/dbname". +type URLOpener struct { + // CertSource specifies how the opener will obtain authentication information. + // CertSource must not be nil. + CertSource proxy.CertSource + + // TraceOpts contains options for OpenTelemetry. + TraceOpts []otelsql.Option +} + +// OpenMySQLURL opens a new GCP database connection wrapped with OpenTelemetry instrumentation. +func (uo *URLOpener) OpenMySQLURL(ctx context.Context, u *url.URL) (*sql.DB, error) { + if uo.CertSource == nil { + return nil, fmt.Errorf("gcpmysql: URLOpener CertSource is nil") + } + dialerName := fmt.Sprintf("gocloud.dev/mysql/gcpmysql/%d", + atomic.AddUint32(&dialerCounter, 1)) + cfg, err := configFromURL(u, dialerName) + if err != nil { + return nil, fmt.Errorf("gcpmysql: open config %v", err) + } + + client := &proxy.Client{ + Port: 3307, + Certs: uo.CertSource, + } + mysql.RegisterDialContext(dialerName, client.DialContext) + + db := sql.OpenDB(connector{cfg.FormatDSN(), uo.TraceOpts}) + return db, nil +} + +func configFromURL(u *url.URL, dialerName string) (*mysql.Config, error) { + instance, dbName, err := instanceFromURL(u) + if err != nil { + return nil, err + } + + var cfg *mysql.Config + switch { + case len(u.RawQuery) > 0: + optDsn := fmt.Sprintf("/%s?%s", dbName, u.RawQuery) + if cfg, err = mysql.ParseDSN(optDsn); err != nil { + return nil, err + } + default: + cfg = mysql.NewConfig() + } + + password, _ := u.User.Password() + + cfg.AllowNativePasswords = true + cfg.Net = dialerName + cfg.Addr = instance + cfg.User = u.User.Username() + cfg.Passwd = password + cfg.DBName = dbName + + return cfg, nil +} + +func instanceFromURL(u *url.URL) (instance, db string, _ error) { + path := u.Host + u.Path // everything after scheme but before query or fragment + parts := strings.SplitN(path, "/", 4) + if len(parts) < 4 { + return "", "", fmt.Errorf("%s is not in the form project/region/instance/dbname", path) + } + for _, part := range parts { + if part == "" { + return "", "", fmt.Errorf("%s is not in the form project/region/instance/dbname", path) + } + } + return parts[0] + ":" + parts[1] + ":" + parts[2], parts[3], nil +} + +var dialerCounter uint32 + +type connector struct { + dsn string + traceOpts []otelsql.Option +} + +func (c connector) Connect(ctx context.Context) (driver.Conn, error) { + return c.Driver().Open(c.dsn) +} + +func (c connector) Driver() driver.Driver { + return otelsql.WrapDriver(mysql.MySQLDriver{}, c.traceOpts...) +} diff --git a/go-cloud/mysql/gcpmysql/gcpmysql_test.go b/go-cloud/mysql/gcpmysql/gcpmysql_test.go new file mode 100644 index 000000000..9d1574099 --- /dev/null +++ b/go-cloud/mysql/gcpmysql/gcpmysql_test.go @@ -0,0 +1,239 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcpmysql + +import ( + "context" + "fmt" + "net/url" + "reflect" + "testing" + + drvr "github.com/go-sql-driver/mysql" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/terraform" + "github.com/DataDog/iceberg-go/go-cloud/mysql" +) + +func TestOpen(t *testing.T) { + // This test will be skipped unless the project is set up with Terraform. + // Before running go test, run in this directory: + // + // terraform init + // terraform apply + + tfOut, err := terraform.ReadOutput(".") + if err != nil || len(tfOut) == 0 { + t.Skipf("Could not obtain harness info: %v", err) + } + project, _ := tfOut["project"].Value.(string) + region, _ := tfOut["region"].Value.(string) + instance, _ := tfOut["instance"].Value.(string) + username, _ := tfOut["username"].Value.(string) + password, _ := tfOut["password"].Value.(string) + databaseName, _ := tfOut["database"].Value.(string) + if project == "" || region == "" || instance == "" || username == "" || databaseName == "" { + t.Fatalf("Missing one or more required Terraform outputs; got project=%q region=%q instance=%q username=%q database=%q", project, region, instance, username, databaseName) + } + + ctx := context.Background() + urlstr := fmt.Sprintf("gcpmysql://%s:%s@%s/%s/%s/%s", username, password, project, region, instance, databaseName) + t.Log("Connecting to", urlstr) + db, err := mysql.Open(ctx, urlstr) + if err != nil { + t.Fatal(err) + } + if err := db.Ping(); err != nil { + t.Error("Ping:", err) + } + if err := db.Close(); err != nil { + t.Error("Close:", err) + } +} + +func TestInstanceFromURL(t *testing.T) { + tests := []struct { + name string + urlString string + wantInstance string + wantDatabase string + wantErr bool + }{ + { + name: "AllValuesSpecified", + urlString: "gcpmysql://username:password@my-project-id/us-central1/my-instance-id/my-db?foo=bar&baz=quux", + wantInstance: "my-project-id:us-central1:my-instance-id", + wantDatabase: "my-db", + }, + { + name: "OptionalValuesOmitted", + urlString: "gcpmysql://my-project-id/us-central1/my-instance-id/my-db", + wantInstance: "my-project-id:us-central1:my-instance-id", + wantDatabase: "my-db", + }, + { + name: "DatabaseNameEmpty", + urlString: "gcpmysql://my-project-id/us-central1/my-instance-id/", + wantErr: true, + }, + { + name: "InstanceEmpty", + urlString: "gcpmysql://my-project-id/us-central1//my-db", + wantErr: true, + }, + { + name: "RegionEmpty", + urlString: "gcpmysql://my-project-id//my-instance-id/my-db", + wantErr: true, + }, + { + name: "ProjectEmpty", + urlString: "gcpmysql:///us-central1/my-instance-id/my-db", + wantErr: true, + }, + { + name: "DatabaseNameWithSlashes", + urlString: "gcpmysql://my-project-id/us-central1/my-instance-id/foo/bar/baz", + wantInstance: "my-project-id:us-central1:my-instance-id", + wantDatabase: "foo/bar/baz", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + u, err := url.Parse(test.urlString) + if err != nil { + t.Fatalf("failed to parse URL %q: %v", test.urlString, err) + } + instance, database, err := instanceFromURL(u) + if err != nil { + t.Logf("instanceFromURL(url.Parse(%q)): %v", u, err) + if !test.wantErr { + t.Fail() + } + return + } + if test.wantErr { + t.Fatalf("instanceFromURL(url.Parse(%q)) = %q, %q, ; want error", test.urlString, instance, database) + } + if instance != test.wantInstance || database != test.wantDatabase { + t.Errorf("instanceFromURL(url.Parse(%q)) = %q, %q, ; want %q, %q, ", test.urlString, instance, database, test.wantInstance, test.wantDatabase) + } + }) + } +} + +func Test_configFromURL(t *testing.T) { + type args struct { + urlStr string + dialerName string + } + tests := []struct { + name string + args args + want *drvr.Config + wantErr bool + }{ + { + name: "ConfigWithNoOptions", + args: args{ + urlStr: "gcpmysql://user:password@my-project-id/us-central1/my-instance-id/my-db", + dialerName: "gocloud.dev/mysql/gcpmysql/1", + }, + want: func() *drvr.Config { + cfg := drvr.NewConfig() + cfg.AllowNativePasswords = true + cfg.Net = "gocloud.dev/mysql/gcpmysql/1" + cfg.Addr = "my-project-id:us-central1:my-instance-id" + cfg.User = "user" + cfg.Passwd = "password" + cfg.DBName = "my-db" + return cfg + }(), + wantErr: false, + }, + { + name: "ConfigWithSignalOptions", + args: args{ + urlStr: "gcpmysql://user:password@my-project-id/us-central1/my-instance-id/my-db?parseTime=true", + dialerName: "gocloud.dev/mysql/gcpmysql/1", + }, + want: func() *drvr.Config { + cfg := drvr.NewConfig() + cfg.AllowNativePasswords = true + cfg.ParseTime = true + cfg.Net = "gocloud.dev/mysql/gcpmysql/1" + cfg.Addr = "my-project-id:us-central1:my-instance-id" + cfg.User = "user" + cfg.Passwd = "password" + cfg.DBName = "my-db" + return cfg + }(), + wantErr: false, + }, + { + name: "ConfigWithMultipleOptions", + args: args{ + urlStr: "gcpmysql://user:password@my-project-id/us-central1/my-instance-id/my-db?columnsWithAlias=true&parseTime=true", + dialerName: "gocloud.dev/mysql/gcpmysql/1", + }, + want: func() *drvr.Config { + cfg := drvr.NewConfig() + cfg.AllowNativePasswords = true + cfg.ColumnsWithAlias = true + cfg.ParseTime = true + cfg.Net = "gocloud.dev/mysql/gcpmysql/1" + cfg.Addr = "my-project-id:us-central1:my-instance-id" + cfg.User = "user" + cfg.Passwd = "password" + cfg.DBName = "my-db" + return cfg + }(), + wantErr: false, + }, + { + name: "InstanceFromURLError", + args: args{ + urlStr: "gcpmysql://user:password@my-project-id/us-central1/my-db", + dialerName: "gocloud.dev/mysql/gcpmysql/1", + }, + want: nil, + wantErr: true, + }, + { + name: "DNSParseError", + args: args{ + urlStr: "gcpmysql://user:password@my-project-id/us-central1/my-instance-id/my-db?parseTime=nope", + dialerName: "gocloud.dev/mysql/gcpmysql/1", + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + u, err := url.Parse(tt.args.urlStr) + if err != nil { + t.Fatalf("failed to parse URL %q: %v", tt.args.urlStr, err) + } + got, err := configFromURL(u, tt.args.dialerName) + if (err != nil) != tt.wantErr { + t.Errorf("configFromURL() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("configFromURL() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/go-cloud/mysql/gcpmysql/main.tf b/go-cloud/mysql/gcpmysql/main.tf new file mode 100644 index 000000000..ee18cbd87 --- /dev/null +++ b/go-cloud/mysql/gcpmysql/main.tf @@ -0,0 +1,132 @@ +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +# Harness for MySQL tests. + +terraform { + required_version = "~>0.12" +} + +provider "google" { + version = "~> 2.5" + project = var.project +} + +provider "random" { + version = "~> 2.1" +} + +variable "project" { + type = string + description = "Project to set up." +} + +variable "region" { + default = "us-central1" + description = "GCP region to create database and storage in, for example 'us-central1'. See https://cloud.google.com/compute/docs/regions-zones/ for valid values." +} + +locals { + sql_instance = "go-cloud-test-${random_id.sql_instance.hex}" +} + +resource "google_project_service" "sql" { + service = "sql-component.googleapis.com" + disable_on_destroy = false +} + +resource "google_project_service" "sqladmin" { + service = "sqladmin.googleapis.com" + disable_on_destroy = false +} + +resource "random_id" "sql_instance" { + keepers = { + project = var.project + region = var.region + } + + byte_length = 12 +} + +resource "google_sql_database_instance" "main" { + name = local.sql_instance + database_version = "MYSQL_5_6" + region = var.region + project = var.project + + settings { + tier = "db-f1-micro" + disk_size = 10 # GiB + } + + depends_on = [ + google_project_service.sql, + google_project_service.sqladmin, + ] +} + +resource "google_sql_database" "main" { + name = "testdb" + instance = google_sql_database_instance.main.name +} + +resource "random_string" "db_password" { + keepers = { + project = var.project + db_name = local.sql_instance + region = var.region + } + + special = false + length = 20 +} + +resource "google_sql_user" "root" { + name = "root" + instance = google_sql_database_instance.main.name + password = random_string.db_password.result +} + +output "project" { + value = var.project + description = "The GCP project ID." +} + +output "region" { + value = var.region + description = "The Cloud SQL instance region." +} + +output "instance" { + value = local.sql_instance + description = "The Cloud SQL instance region." +} + +output "username" { + value = "root" + description = "The Cloud SQL username to connect with." +} + +output "password" { + value = random_string.db_password.result + sensitive = true + description = "The Cloud SQL instance password for the user." +} + +output "database" { + value = "testdb" + description = "The name of the database inside the Cloud SQL instance." +} + diff --git a/go-cloud/mysql/main.tf b/go-cloud/mysql/main.tf new file mode 100644 index 000000000..089f6ab67 --- /dev/null +++ b/go-cloud/mysql/main.tf @@ -0,0 +1,86 @@ +# Copyright 2020 The Go Cloud Development Kit 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 +# +# https://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. + +# Harness for MySQL tests. + +terraform { + required_version = ">= 0.13" + required_providers { + docker = { + source = "terraform-providers/docker" + version = "~> 2.0" + } + random = { + source = "hashicorp/random" + version = "~> 2.0" + } + } +} + +variable port { + type = number + description = "Port exposed out of the MySQL container." + default = 3306 +} + +resource random_pet mysql {} + +resource random_password db_password { + special = false + length = 20 +} + +locals { + db_name = "testdb" +} + +resource docker_container mysql { + name = random_pet.mysql.id + image = docker_image.mysql.latest + + env = [ + "MYSQL_ROOT_PASSWORD=${random_password.db_password.result}", + "MYSQL_DATABASE=${local.db_name}", + ] + ports { + internal = 3306 + external = var.port + } +} + +resource docker_image mysql { + name = "mysql" +} + +output endpoint { + value = "localhost:${var.port}" + description = "The MySQL instance's host/port." +} + +output username { + value = "root" + description = "The MySQL username to connect with." +} + +output password { + value = random_password.db_password.result + sensitive = true + description = "The MySQL instance password for the user." +} + +output database { + value = local.db_name + description = "The name of the database inside the MySQL instance." +} + diff --git a/go-cloud/mysql/mysql.go b/go-cloud/mysql/mysql.go new file mode 100644 index 000000000..8a33f993b --- /dev/null +++ b/go-cloud/mysql/mysql.go @@ -0,0 +1,160 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mysql provides functions to open MySQL databases with OpenTelemetry instrumentation. +package mysql + +import ( + "context" + "database/sql" + "database/sql/driver" + "fmt" + "net/url" + "regexp" + "strings" + + "github.com/XSAM/otelsql" + "github.com/go-sql-driver/mysql" + "github.com/DataDog/iceberg-go/go-cloud/internal/openurl" +) + +// Scheme is the URL scheme this package registers its URLOpener under on +// DefaultMux. +const Scheme = "mysql" + +func init() { + DefaultURLMux().RegisterMySQL(Scheme, &URLOpener{}) +} + +// URLOpener opens URLs like "mysql://" by using the underlying MySQL driver. +// like "mysql://user:password@localhost:3306/mydb". +type URLOpener struct { + TraceOpts []otelsql.Option +} + +// OpenMySQLURL opens a new database connection wrapped with OpenTelemetry instrumentation. +func (uo *URLOpener) OpenMySQLURL(_ context.Context, u *url.URL) (*sql.DB, error) { + cfg, err := ConfigFromURL(u) + if err != nil { + return nil, err + } + return sql.OpenDB(connector{ + dsn: cfg.FormatDSN(), + traceOpts: append([]otelsql.Option(nil), uo.TraceOpts...), + }), nil +} + +var netAddrRE = regexp.MustCompile(`^(.+)\((.+)\)$`) + +// ConfigFromURL creates a mysql.Config from URL. +func ConfigFromURL(u *url.URL) (cfg *mysql.Config, err error) { + dbName := strings.TrimPrefix(u.Path, "/") + if u.RawQuery != "" { + optDsn := fmt.Sprintf("/%s?%s", dbName, u.RawQuery) + if cfg, err = mysql.ParseDSN(optDsn); err != nil { + return nil, err + } + } else { + cfg = mysql.NewConfig() + } + if matches := netAddrRE.FindStringSubmatch(u.Host); len(matches) == 3 { + cfg.Net = matches[1] + cfg.Addr = matches[2] + } else { + cfg.Net = "tcp" + cfg.Addr = u.Host + } + cfg.User = u.User.Username() + cfg.Passwd, _ = u.User.Password() + cfg.DBName = dbName + cfg.AllowCleartextPasswords = true + cfg.AllowNativePasswords = true + return cfg, nil +} + +type connector struct { + dsn string + traceOpts []otelsql.Option +} + +func (c connector) Connect(context.Context) (driver.Conn, error) { + return c.Driver().Open(c.dsn) +} + +func (c connector) Driver() driver.Driver { + return otelsql.WrapDriver(mysql.MySQLDriver{}, c.traceOpts...) +} + +// MySQLURLOpener implements MySQLURLOpener and can open connections based on a URL. +// The opener must not modify the URL argument. OpenMySQLURL must be safe to +// call from multiple goroutines. +// +// This interface is generally implemented by types in driver packages. +type MySQLURLOpener interface { + OpenMySQLURL(ctx context.Context, u *url.URL) (*sql.DB, error) +} + +// URLMux is a URL opener multiplexer. It matches the scheme of the URLs +// against a set of registered schemes and calls the opener that matches the +// URL's scheme. +// +// The zero value is a multiplexer with no registered schemes. +type URLMux struct { + schemes openurl.SchemeMap +} + +// RegisterMySQL registers the opener with the given scheme. If an opener +// already exists for the scheme, RegisterMySQL panics. +func (mux *URLMux) RegisterMySQL(scheme string, opener MySQLURLOpener) { + mux.schemes.Register("mysql", "DB", scheme, opener) +} + +// OpenMySQL calls OpenMySQLURL with the URL parsed from urlstr. +// OpenMySQL is safe to call from multiple goroutines. +func (mux *URLMux) OpenMySQL(ctx context.Context, urlstr string) (*sql.DB, error) { + opener, u, err := mux.schemes.FromString("DB", urlstr) + if err != nil { + return nil, err + } + return opener.(MySQLURLOpener).OpenMySQLURL(ctx, u) +} + +// OpenMySQLURL dispatches the URL to the opener that is registered with the +// URL's scheme. OpenMySQLURL is safe to call from multiple goroutines. +func (mux *URLMux) OpenMySQLURL(ctx context.Context, u *url.URL) (*sql.DB, error) { + opener, err := mux.schemes.FromURL("DB", u) + if err != nil { + return nil, err + } + return opener.(MySQLURLOpener).OpenMySQLURL(ctx, u) +} + +var defaultURLMux = new(URLMux) + +// DefaultURLMux returns the URLMux used by OpenMySql. +// +// Driver packages can use this to register their MySQLURLOpener on the mux. +func DefaultURLMux() *URLMux { + return defaultURLMux +} + +// Open opens the bucket identified by the URL given. URL openers must be +// registered in the DefaultURLMux, which is typically done in driver +// packages' initialization. +// +// See the URLOpener documentation in driver subpackages for more +// details on supported scheme(s) and URL parameter(s). +func Open(ctx context.Context, urlstr string) (*sql.DB, error) { + return defaultURLMux.OpenMySQL(ctx, urlstr) +} diff --git a/go-cloud/mysql/mysql_test.go b/go-cloud/mysql/mysql_test.go new file mode 100644 index 000000000..0321073cd --- /dev/null +++ b/go-cloud/mysql/mysql_test.go @@ -0,0 +1,93 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mysql + +import ( + "context" + "fmt" + "net/url" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/terraform" +) + +func TestOpen(t *testing.T) { + // This test will be skipped unless the project is set up with Terraform. + // Before running go test, run in this directory: + // + // terraform init + // terraform apply + + tfOut, err := terraform.ReadOutput(".") + if err != nil || len(tfOut) == 0 { + t.Skipf("Could not obtain harness info: %v", err) + } + endpoint, _ := tfOut["endpoint"].Value.(string) + username, _ := tfOut["username"].Value.(string) + password, _ := tfOut["password"].Value.(string) + databaseName, _ := tfOut["database"].Value.(string) + if endpoint == "" || username == "" || databaseName == "" { + t.Fatalf("Missing one or more required Terraform outputs; got endpoint=%q username=%q database=%q", endpoint, username, databaseName) + } + + ctx := context.Background() + urlstr := fmt.Sprintf("%s://%s:%s@%s/%s", Scheme, username, password, endpoint, databaseName) + t.Log("Connecting to:", urlstr) + db, err := Open(ctx, urlstr) + if err != nil { + t.Fatal(err) + } + if err := db.Ping(); err != nil { + t.Error("Ping:", err) + } + if err := db.Close(); err != nil { + t.Error("Close:", err) + } +} + +func TestConfigFromURL(t *testing.T) { + for _, host := range []string{ + "localhost", + "tcp(localhost)", + } { + urlstr := "mysql://user:password@" + host + "/db?parseTime=true&interpolateParams=true" + u, err := url.Parse(urlstr) + if err != nil { + t.Fatal(err) + } + cfg, err := ConfigFromURL(u) + if err != nil { + t.Fatal(err) + } + if got, want := cfg.User, "user"; got != want { + t.Errorf(`User = %q; want %q`, got, want) + } + if got, want := cfg.Passwd, "password"; got != want { + t.Errorf(`Passwd = %q; want %q`, got, want) + } + if got, want := cfg.Net, "tcp"; got != want { + t.Errorf(`Net = %q; want %q`, got, want) + } + if got, want := cfg.Addr, "localhost"; got != want { + t.Errorf(`Addr = %q; want %q`, got, want) + } + if !cfg.ParseTime { + t.Error("ParseTime = false; want true") + } + if !cfg.InterpolateParams { + t.Error("InterpolateParams = false; want true") + } + } +} diff --git a/go-cloud/postgres/awspostgres/awspostgres.go b/go-cloud/postgres/awspostgres/awspostgres.go new file mode 100644 index 000000000..f3ac5ba32 --- /dev/null +++ b/go-cloud/postgres/awspostgres/awspostgres.go @@ -0,0 +1,186 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awspostgres provides connections to AWS RDS PostgreSQL instances. +// +// # URLs +// +// For postgres.Open, awspostgres registers for the scheme "awspostgres". +// The default URL opener will create a connection using the default +// credentials from the environment, as described in +// https://docs.aws.amazon.com/sdk-for-go/api/aws/session/. +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// +// See https://gocloud.dev/concepts/urls/ for background information. +package awspostgres // import "gocloud.dev/postgres/awspostgres" + +import ( + "context" + "crypto/tls" + "database/sql" + "database/sql/driver" + "fmt" + "io" + "net" + "net/url" + "time" + + "github.com/XSAM/otelsql" + "github.com/lib/pq" + "github.com/DataDog/iceberg-go/go-cloud/aws/rds" + "github.com/DataDog/iceberg-go/go-cloud/postgres" +) + +// URLOpener opens RDS PostgreSQL URLs +// like "awspostgres://user:password@myinstance.borkxyzzy.us-west-1.rds.amazonaws.com:5432/mydb". +type URLOpener struct { + // CertSource specifies how the opener will obtain the RDS Certificate + // Authority. If nil, it will use the default *rds.CertFetcher. + CertSource rds.CertPoolProvider + // TraceOpts contains options for OpenTelemetry. + TraceOpts []otelsql.Option +} + +// Scheme is the URL scheme awspostgres registers its URLOpener under on +// postgres.DefaultMux. +const Scheme = "awspostgres" + +func init() { + postgres.DefaultURLMux().RegisterPostgres(Scheme, &URLOpener{}) +} + +// OpenPostgresURL opens a new RDS database connection wrapped with OpenTelemetry instrumentation. +func (uo *URLOpener) OpenPostgresURL(ctx context.Context, u *url.URL) (*sql.DB, error) { + source := uo.CertSource + if source == nil { + source = new(rds.CertFetcher) + } + + query := u.Query() + for k := range query { + // Forbid SSL-related parameters. + if k == "sslmode" || k == "sslcert" || k == "sslkey" || k == "sslrootcert" { + return nil, fmt.Errorf("awspostgres: open: parameter %q not allowed; sslmode must be disabled because the underlying dialer is already providing TLS", k) + } + } + // sslmode must be disabled because the underlying dialer is already providing TLS. + query.Set("sslmode", "disable") + + u2 := new(url.URL) + *u2 = *u + u2.Scheme = "postgres" + u2.RawQuery = query.Encode() + db := sql.OpenDB(connector{ + provider: source, + pqConn: u2.String(), + traceOpts: append([]otelsql.Option(nil), uo.TraceOpts...), + }) + return db, nil +} + +type pqDriver struct { + provider rds.CertPoolProvider + traceOpts []otelsql.Option +} + +func (d pqDriver) Open(name string) (driver.Conn, error) { + c, _ := d.OpenConnector(name) + return c.Connect(context.Background()) +} + +func (d pqDriver) OpenConnector(name string) (driver.Connector, error) { + return connector{d.provider, name + " sslmode=disable", d.traceOpts}, nil +} + +type connector struct { + provider rds.CertPoolProvider + pqConn string + traceOpts []otelsql.Option +} + +func (c connector) Connect(context.Context) (driver.Conn, error) { + conn, err := pq.DialOpen(dialer{c.provider}, c.pqConn) + if err != nil { + return nil, err + } + return conn, nil +} + +func (c connector) Driver() driver.Driver { + return otelsql.WrapDriver(pqDriver{c.provider, c.traceOpts}, c.traceOpts...) +} + +type dialer struct { + provider rds.CertPoolProvider +} + +func (d dialer) dial(ctx context.Context, network, address string) (net.Conn, error) { + host, _, err := net.SplitHostPort(address) + if err != nil { + return nil, fmt.Errorf("awspostgres: parse address: %v", err) + } + certPool, err := d.provider.RDSCertPool(ctx) + if err != nil { + return nil, err + } + conn, err := new(net.Dialer).DialContext(ctx, network, address) + if err != nil { + return nil, err + } + + // Write the PostgreSQL SSLRequest message described in + // https://www.postgresql.org/docs/11/protocol-message-formats.html + // to upgrade to a TLS connection. + _, err = conn.Write([]byte{ + // Message length (Int32), including message length. + 0x00, 0x00, 0x00, 0x08, + // Magic number: 80877103. + 0x04, 0xd2, 0x16, 0x2f, + }) + if err != nil { + return nil, err + } + // Server must respond back with 'S'. + var readBuf [1]byte + if _, err := io.ReadFull(conn, readBuf[:]); err != nil { + return nil, err + } + if readBuf[0] != 'S' { + return nil, pq.ErrSSLNotSupported + } + + // Begin TLS communication. + crypt := tls.Client(conn, &tls.Config{ + ServerName: host, + RootCAs: certPool, + Renegotiation: tls.RenegotiateFreelyAsClient, + }) + err = crypt.Handshake() + if err != nil { + return nil, err + } + return crypt, nil +} + +func (d dialer) Dial(network, address string) (net.Conn, error) { + return d.dial(context.Background(), network, address) +} + +func (d dialer) DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + conn, err := d.dial(ctx, network, address) + cancel() + return conn, err +} diff --git a/go-cloud/postgres/awspostgres/awspostgres_test.go b/go-cloud/postgres/awspostgres/awspostgres_test.go new file mode 100644 index 000000000..43de582c6 --- /dev/null +++ b/go-cloud/postgres/awspostgres/awspostgres_test.go @@ -0,0 +1,85 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awspostgres + +import ( + "context" + "fmt" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/terraform" + "github.com/DataDog/iceberg-go/go-cloud/postgres" +) + +func TestURLOpener(t *testing.T) { + // This test will be skipped unless the project is set up with Terraform. + // Before running go test, run in this directory: + // + // terraform init + // terraform apply + + tfOut, err := terraform.ReadOutput(".") + if err != nil || len(tfOut) == 0 { + t.Skipf("Could not obtain harness info: %v", err) + } + endpoint, _ := tfOut["endpoint"].Value.(string) + username, _ := tfOut["username"].Value.(string) + password, _ := tfOut["password"].Value.(string) + databaseName, _ := tfOut["database"].Value.(string) + if endpoint == "" || username == "" || databaseName == "" { + t.Fatalf("Missing one or more required Terraform outputs; got endpoint=%q username=%q database=%q", endpoint, username, databaseName) + } + + tests := []struct { + urlstr string + wantErr bool + wantPingErr bool + }{ + // OK. + {fmt.Sprintf("awspostgres://%s:%s@%s/%s", username, password, endpoint, databaseName), false, false}, + // Invalid URL parameters: db creation fails. + {fmt.Sprintf("awspostgres://%s:%s@%s/%s?sslcert=foo", username, password, endpoint, databaseName), true, false}, + {fmt.Sprintf("awspostgres://%s:%s@%s/%s?sslkey=foo", username, password, endpoint, databaseName), true, false}, + {fmt.Sprintf("awspostgres://%s:%s@%s/%s?sslrootcert=foo", username, password, endpoint, databaseName), true, false}, + {fmt.Sprintf("awspostgres://%s:%s@%s/%s?sslmode=require", username, password, endpoint, databaseName), true, false}, + // Invalid connection info: db is created, but Ping fails. + {fmt.Sprintf("awspostgres://%s:badpwd@%s/%s", username, endpoint, databaseName), false, true}, + {fmt.Sprintf("awspostgres://badusername:%s@%s/%s", password, endpoint, databaseName), false, true}, + {fmt.Sprintf("awspostgres://%s:%s@localhost:9999/%s", username, password, databaseName), false, true}, + {fmt.Sprintf("awspostgres://%s:%s@%s/wrongdbname", username, password, endpoint), false, true}, + {fmt.Sprintf("awspostgres://%s:%s@%s/%s?foo=bar", username, password, endpoint, databaseName), false, true}, + } + ctx := context.Background() + for _, test := range tests { + t.Run(test.urlstr, func(t *testing.T) { + db, err := postgres.Open(ctx, test.urlstr) + if err != nil != test.wantErr { + t.Fatalf("got err %v, wanted error? %v", err, test.wantErr) + } + if err != nil { + return + } + defer func() { + if err := db.Close(); err != nil { + t.Error("Close:", err) + } + }() + err = db.Ping() + if err != nil != test.wantPingErr { + t.Errorf("ping got err %v, wanted error? %v", err, test.wantPingErr) + } + }) + } +} diff --git a/go-cloud/postgres/awspostgres/example_test.go b/go-cloud/postgres/awspostgres/example_test.go new file mode 100644 index 000000000..dacc9ff4b --- /dev/null +++ b/go-cloud/postgres/awspostgres/example_test.go @@ -0,0 +1,41 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awspostgres_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/postgres" + _ "github.com/DataDog/iceberg-go/go-cloud/postgres/awspostgres" +) + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/postgres/awspostgres" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Replace these with your actual settings. + db, err := postgres.Open(ctx, + "awspostgres://myrole:swordfish@example01.xyzzy.us-west-1.rds.amazonaws.com/testdb") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + // Use database in your program. + db.ExecContext(ctx, "CREATE TABLE foo (bar INT);") +} diff --git a/go-cloud/postgres/awspostgres/main.tf b/go-cloud/postgres/awspostgres/main.tf new file mode 100644 index 000000000..0af12e571 --- /dev/null +++ b/go-cloud/postgres/awspostgres/main.tf @@ -0,0 +1,110 @@ +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +# Harness for RDS PostgreSQL tests. + +terraform { + required_version = "~>0.12" +} + +provider "aws" { + version = "~> 2.7" + region = var.region +} + +provider "random" { + version = "~> 2.1" +} + +variable "region" { + type = string + description = "Region to create resources in. See https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html for valid values." +} + +resource "aws_security_group" "main" { + name_prefix = "testdb" + description = "Security group for the Go CDK Postgres test database." + + ingress { + from_port = 5432 + to_port = 5432 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + description = "Public Postgres access" + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + description = "All outgoing traffic allowed" + } +} + +resource "random_string" "db_password" { + keepers = { + region = var.region + } + + special = false + length = 20 +} + +resource "aws_db_instance" "main" { + identifier_prefix = "go-cloud-test" + engine = "postgres" + engine_version = "10.5" + instance_class = "db.t2.micro" + allocated_storage = 20 + username = "root" + password = random_string.db_password.result + name = "testdb" + publicly_accessible = true + vpc_security_group_ids = [aws_security_group.main.id] + skip_final_snapshot = true + parameter_group_name = aws_db_parameter_group.main.name +} + +resource "aws_db_parameter_group" "main" { + name_prefix = "go-cloud-test" + family = "postgres10" + + parameter { + name = "rds.force_ssl" + value = "1" + } +} + +output "endpoint" { + value = aws_db_instance.main.endpoint + description = "The RDS instance's host/port." +} + +output "username" { + value = "root" + description = "The PostgreSQL username to connect with." +} + +output "password" { + value = random_string.db_password.result + sensitive = true + description = "The RDS instance password for the user." +} + +output "database" { + value = "testdb" + description = "The name of the database inside the RDS instance." +} + diff --git a/go-cloud/postgres/example_test.go b/go-cloud/postgres/example_test.go new file mode 100644 index 000000000..3458c8dda --- /dev/null +++ b/go-cloud/postgres/example_test.go @@ -0,0 +1,38 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 postgres_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/postgres" +) + +func ExampleOpen() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Replace this with your actual settings. + db, err := postgres.Open(ctx, "postgres://user:password@localhost/testdb") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + // Use database in your program. + db.Exec("CREATE TABLE foo (bar INT);") +} diff --git a/go-cloud/postgres/gcppostgres/example_test.go b/go-cloud/postgres/gcppostgres/example_test.go new file mode 100644 index 000000000..dfa78e08f --- /dev/null +++ b/go-cloud/postgres/gcppostgres/example_test.go @@ -0,0 +1,41 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcppostgres_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/postgres" + _ "github.com/DataDog/iceberg-go/go-cloud/postgres/gcppostgres" +) + +func Example() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/postgres/gcppostgres" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Replace this with your actual settings. + db, err := postgres.Open(ctx, + "gcppostgres://user:password@example-project/region/my-instance01/testdb") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + // Use database in your program. + db.Exec("CREATE TABLE foo (bar INT);") +} diff --git a/go-cloud/postgres/gcppostgres/gcppostgres.go b/go-cloud/postgres/gcppostgres/gcppostgres.go new file mode 100644 index 000000000..ce771b62e --- /dev/null +++ b/go-cloud/postgres/gcppostgres/gcppostgres.go @@ -0,0 +1,194 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcppostgres provides connections to managed PostgreSQL Cloud SQL instances. +// See https://cloud.google.com/sql/docs/postgres/ for more information. +// +// # URLs +// +// For postgres.Open, gcppostgres registers for the scheme "gcppostgres". +// The default URL opener will create a connection using the default +// credentials from the environment, as described in +// https://cloud.google.com/docs/authentication/production. +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// +// See https://gocloud.dev/concepts/urls/ for background information. +package gcppostgres // import "gocloud.dev/postgres/gcppostgres" + +import ( + "context" + "database/sql" + "database/sql/driver" + "errors" + "fmt" + "net" + "net/url" + "strings" + "sync" + "time" + + "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/proxy" + "github.com/XSAM/otelsql" + "github.com/lib/pq" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/gcp/cloudsql" + "github.com/DataDog/iceberg-go/go-cloud/postgres" +) + +// Scheme is the URL scheme gcppostgres registers its URLOpener under on +// postgres.DefaultMux. +const Scheme = "gcppostgres" + +func init() { + postgres.DefaultURLMux().RegisterPostgres(Scheme, new(lazyCredsOpener)) +} + +// lazyCredsOpener obtains Application Default Credentials on the first call +// to OpenPostgresURL. +type lazyCredsOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazyCredsOpener) OpenPostgresURL(ctx context.Context, u *url.URL) (*sql.DB, error) { + o.init.Do(func() { + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + o.err = err + return + } + client, err := gcp.NewHTTPClient(gcp.DefaultTransport(), creds.TokenSource) + if err != nil { + o.err = err + return + } + certSource := cloudsql.NewCertSourceWithIAM(client, creds.TokenSource) + o.opener = &URLOpener{CertSource: certSource} + }) + if o.err != nil { + return nil, fmt.Errorf("gcppostgres open %v: %v", u, o.err) + } + return o.opener.OpenPostgresURL(ctx, u) +} + +// URLOpener opens GCP PostgreSQL URLs +// like "gcppostgres://user:password@myproject/us-central1/instanceId/mydb". +type URLOpener struct { + // CertSource specifies how the opener will obtain authentication information. + // CertSource must not be nil. + CertSource proxy.CertSource + + // TraceOpts contains options for OpenTelemetry. + TraceOpts []otelsql.Option +} + +// OpenPostgresURL opens a new GCP database connection wrapped with OpenTelemetry instrumentation. +func (uo *URLOpener) OpenPostgresURL(ctx context.Context, u *url.URL) (*sql.DB, error) { + if uo.CertSource == nil { + return nil, fmt.Errorf("gcppostgres: URLOpener CertSource is nil") + } + instance, dbName, err := instanceFromURL(u) + if err != nil { + return nil, fmt.Errorf("gcppostgres: open %v: %v", u, err) + } + + query := u.Query() + for k := range query { + // Only permit parameters that do not conflict with other behavior. + if k == "sslmode" || k == "sslcert" || k == "sslkey" || k == "sslrootcert" { + return nil, fmt.Errorf("gcppostgres: open: extra parameter %s not allowed", k) + } + } + query.Set("sslmode", "disable") + + u2 := new(url.URL) + *u2 = *u + u2.Scheme = "postgres" + u2.Host = "cloudsql" + u2.Path = "/" + dbName + u2.RawQuery = query.Encode() + db := sql.OpenDB(connector{ + client: &proxy.Client{ + Port: 3307, + Certs: uo.CertSource, + }, + instance: instance, + pqConn: u2.String(), + traceOpts: append([]otelsql.Option(nil), uo.TraceOpts...), + }) + return db, nil +} + +func instanceFromURL(u *url.URL) (instance, db string, _ error) { + path := u.Host + u.Path // everything after scheme but before query or fragment + parts := strings.SplitN(path, "/", 4) + if len(parts) < 4 { + return "", "", fmt.Errorf("%s is not in the form project/region/instance/dbname", path) + } + for _, part := range parts { + if part == "" { + return "", "", fmt.Errorf("%s is not in the form project/region/instance/dbname", path) + } + } + return parts[0] + ":" + parts[1] + ":" + parts[2], parts[3], nil +} + +type pqDriver struct { + client *proxy.Client + instance string + traceOpts []otelsql.Option +} + +func (d pqDriver) Open(name string) (driver.Conn, error) { + c, _ := d.OpenConnector(name) + return c.Connect(context.Background()) +} + +func (d pqDriver) OpenConnector(name string) (driver.Connector, error) { + return connector{d.client, d.instance, name, d.traceOpts}, nil +} + +type connector struct { + client *proxy.Client + instance string + pqConn string + traceOpts []otelsql.Option +} + +func (c connector) Connect(context.Context) (driver.Conn, error) { + conn, err := pq.DialOpen(dialer{c.client, c.instance}, c.pqConn) + if err != nil { + return nil, err + } + return conn, nil +} + +func (c connector) Driver() driver.Driver { + return otelsql.WrapDriver(pqDriver{c.client, c.instance, c.traceOpts}, c.traceOpts...) +} + +type dialer struct { + client *proxy.Client + instance string +} + +func (d dialer) Dial(network, address string) (net.Conn, error) { + return d.client.Dial(d.instance) +} + +func (d dialer) DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) { + return nil, errors.New("gcppostgres: DialTimeout not supported") +} diff --git a/go-cloud/postgres/gcppostgres/gcppostgres_test.go b/go-cloud/postgres/gcppostgres/gcppostgres_test.go new file mode 100644 index 000000000..c92c89df6 --- /dev/null +++ b/go-cloud/postgres/gcppostgres/gcppostgres_test.go @@ -0,0 +1,162 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcppostgres + +import ( + "context" + "fmt" + "net/url" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/terraform" + "github.com/DataDog/iceberg-go/go-cloud/postgres" +) + +func TestURLOpener(t *testing.T) { + // This test will be skipped unless the project is set up with Terraform. + // Before running go test, run in this directory: + // + // terraform init + // terraform apply + + tfOut, err := terraform.ReadOutput(".") + if err != nil || len(tfOut) == 0 { + t.Skipf("Could not obtain harness info: %v", err) + } + project, _ := tfOut["project"].Value.(string) + region, _ := tfOut["region"].Value.(string) + instance, _ := tfOut["instance"].Value.(string) + username, _ := tfOut["username"].Value.(string) + password, _ := tfOut["password"].Value.(string) + databaseName, _ := tfOut["database"].Value.(string) + userEmail, _ := tfOut["user_email"].Value.(string) + if project == "" || region == "" || instance == "" || username == "" || databaseName == "" || userEmail == "" { + t.Fatalf("Missing one or more required Terraform outputs; got project=%q region=%q instance=%q username=%q database=%q userEmail=%q", project, region, instance, username, databaseName, userEmail) + } + tests := []struct { + name string + urlstr string + wantErr bool + }{ + { + name: "SuccessIam", + urlstr: fmt.Sprintf("gcppostgres://%s@%s/%s/%s/%s", userEmail, project, region, instance, databaseName), + }, + { + name: "SuccessBuiltin", + urlstr: fmt.Sprintf("gcppostgres://%s:%s@%s/%s/%s/%s", username, password, project, region, instance, databaseName), + }, + { + name: "SSLModeForbidden", + urlstr: fmt.Sprintf("gcppostgres://%s:%s@%s/%s/%s/%s?sslmode=require", username, password, project, region, instance, databaseName), + wantErr: true, + }, + } + + ctx := context.Background() + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + db, err := postgres.Open(ctx, test.urlstr) + if err != nil { + t.Log(err) + if !test.wantErr { + t.Fail() + } + return + } + if test.wantErr { + db.Close() + t.Fatal("Open succeeded; want error") + } + if err := db.Ping(); err != nil { + t.Error("Ping:", err) + } + if err := db.Close(); err != nil { + t.Error("Close:", err) + } + }) + } +} + +func TestInstanceFromURL(t *testing.T) { + tests := []struct { + name string + urlString string + wantInstance string + wantDatabase string + wantErr bool + }{ + { + name: "AllValuesSpecified", + urlString: "gcppostgres://username:password@my-project-id/us-central1/my-instance-id/my-db?foo=bar&baz=quux", + wantInstance: "my-project-id:us-central1:my-instance-id", + wantDatabase: "my-db", + }, + { + name: "OptionalValuesOmitted", + urlString: "gcppostgres://my-project-id/us-central1/my-instance-id/my-db", + wantInstance: "my-project-id:us-central1:my-instance-id", + wantDatabase: "my-db", + }, + { + name: "DatabaseNameEmpty", + urlString: "gcppostgres://my-project-id/us-central1/my-instance-id/", + wantErr: true, + }, + { + name: "InstanceEmpty", + urlString: "gcppostgres://my-project-id/us-central1//my-db", + wantErr: true, + }, + { + name: "RegionEmpty", + urlString: "gcppostgres://my-project-id//my-instance-id/my-db", + wantErr: true, + }, + { + name: "ProjectEmpty", + urlString: "gcppostgres:///us-central1/my-instance-id/my-db", + wantErr: true, + }, + { + name: "DatabaseNameWithSlashes", + urlString: "gcppostgres://my-project-id/us-central1/my-instance-id/foo/bar/baz", + wantInstance: "my-project-id:us-central1:my-instance-id", + wantDatabase: "foo/bar/baz", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + u, err := url.Parse(test.urlString) + if err != nil { + t.Fatalf("failed to parse URL %q: %v", test.urlString, err) + } + instance, database, err := instanceFromURL(u) + if err != nil { + t.Logf("instanceFromURL(url.Parse(%q)): %v", u, err) + if !test.wantErr { + t.Fail() + } + return + } + if test.wantErr { + t.Fatalf("instanceFromURL(url.Parse(%q)) = %q, %q, ; want error", test.urlString, instance, database) + } + if instance != test.wantInstance || database != test.wantDatabase { + t.Errorf("instanceFromURL(url.Parse(%q)) = %q, %q, ; want %q, %q, ", test.urlString, instance, database, test.wantInstance, test.wantDatabase) + } + }) + } +} diff --git a/go-cloud/postgres/gcppostgres/main.tf b/go-cloud/postgres/gcppostgres/main.tf new file mode 100644 index 000000000..b57aa5274 --- /dev/null +++ b/go-cloud/postgres/gcppostgres/main.tf @@ -0,0 +1,169 @@ +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +# Harness for Cloud SQL Postgres tests. + +terraform { + required_version = ">= 1.1.0" + required_providers { + google = { + version = "4.40.0" + } + random = { + version = "3.4.3" + } + } +} + +provider "google" { + project = var.project + region = var.region +} + +variable "project" { + type = string + description = "Project ID - Google Cloud project ID in which to create resources." +} + +variable "user_email" { + type = string + description = "User email address - Google identity to be used for testing IAM authentication." +} + +variable "region" { + default = "us-central1" + description = "GCP region to create database and storage in, for example 'us-central1'. See https://cloud.google.com/compute/docs/regions-zones/ for valid values." +} + +locals { + sql_instance = "go-cloud-test-${random_id.sql_instance.hex}" +} + +resource "google_project_service" "sql" { + service = "sql-component.googleapis.com" + disable_on_destroy = false +} + +resource "google_project_service" "sqladmin" { + service = "sqladmin.googleapis.com" + disable_on_destroy = false +} + +resource "random_id" "sql_instance" { + keepers = { + project = var.project + region = var.region + } + + byte_length = 12 +} + +resource "google_project_iam_member" "cloudsql_client" { + project = var.project + role = "roles/cloudsql.client" + member = "user:${var.user_email}" +} + +resource "google_project_iam_member" "cloudsql_instanceUser" { + project = var.project + role = "roles/cloudsql.instanceUser" + member = "user:${var.user_email}" +} + +resource "google_sql_database_instance" "main" { + name = local.sql_instance + database_version = "POSTGRES_9_6" + region = var.region + project = var.project + + settings { + tier = "db-f1-micro" + disk_size = 10 # GiB + database_flags { + name = "cloudsql.iam_authentication" + value = "on" + } + } + + depends_on = [ + google_project_service.sql, + google_project_service.sqladmin, + ] +} + +resource "google_sql_database" "main" { + project = var.project + name = "testdb" + instance = google_sql_database_instance.main.name +} + +resource "random_string" "db_password" { + keepers = { + project = var.project + db_name = local.sql_instance + region = var.region + } + + special = false + length = 20 +} + +resource "google_sql_user" "root" { + type = "BUILT_IN" + name = "root" + instance = google_sql_database_instance.main.name + password = random_string.db_password.result +} + +resource "google_sql_user" "user_account" { + type = "CLOUD_IAM_USER" + name = var.user_email + instance = google_sql_database_instance.main.name +} + +output "project" { + value = var.project + description = "The GCP project ID." +} + +output "region" { + value = var.region + description = "The Cloud SQL instance region." +} + +output "instance" { + value = local.sql_instance + description = "The Cloud SQL instance region." +} + +output "username" { + value = "root" + description = "The Cloud SQL username to connect with." +} + +output "password" { + value = random_string.db_password.result + sensitive = true + description = "The Cloud SQL instance password for the user." +} + +output "database" { + value = "testdb" + description = "The name of the database inside the Cloud SQL instance." +} + +output "user_email" { + value = var.user_email + description = "The email of a GCP service account used for testing connections." +} diff --git a/go-cloud/postgres/postgres.go b/go-cloud/postgres/postgres.go new file mode 100644 index 000000000..1b15d4677 --- /dev/null +++ b/go-cloud/postgres/postgres.go @@ -0,0 +1,126 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 postgres provides functions to open PostgreSQL databases with OpenTelemetry instrumentation. +package postgres + +import ( + "context" + "database/sql" + "database/sql/driver" + "net/url" + + "github.com/XSAM/otelsql" + "github.com/lib/pq" + "github.com/DataDog/iceberg-go/go-cloud/internal/openurl" +) + +// Scheme is the URL scheme this package registers its URLOpener under on +// DefaultMux. +const Scheme = "postgres" + +func init() { + DefaultURLMux().RegisterPostgres(Scheme, &URLOpener{}) +} + +// URLOpener opens URLs like "postgres://" by using the underlying PostgreSQL driver. +// See https://godoc.org/github.com/lib/pq#hdr-Connection_String_Parameters for details. +type URLOpener struct { + TraceOpts []otelsql.Option +} + +// OpenPostgresURL opens a new database connection wrapped with OpenTelemetry instrumentation. +func (uo *URLOpener) OpenPostgresURL(ctx context.Context, u *url.URL) (*sql.DB, error) { + u2 := new(url.URL) + *u2 = *u + u2.Scheme = "postgres" + return sql.OpenDB(connector{dsn: u2.String(), traceOpts: append([]otelsql.Option(nil), uo.TraceOpts...)}), nil +} + +type connector struct { + dsn string + traceOpts []otelsql.Option +} + +func (c connector) Connect(ctx context.Context) (driver.Conn, error) { + return c.Driver().Open(c.dsn) +} + +func (c connector) Driver() driver.Driver { + return otelsql.WrapDriver(&pq.Driver{}, c.traceOpts...) +} + +// PostgresURLOpener can open Postgres connections based on a URL. +// The opener must not modify the URL argument. OpenPostgresURL must be safe to +// call from multiple goroutines. +// +// This interface is generally implemented by types in driver packages. +type PostgresURLOpener interface { + // OpenPostgresURL opens a Postgres connection based on the URL. + OpenPostgresURL(ctx context.Context, u *url.URL) (*sql.DB, error) +} + +// URLMux is a URL opener multiplexer. It matches the scheme of the URLs +// against a set of registered schemes and calls the opener that matches the +// URL's scheme. +// +// The zero value is a multiplexer with no registered schemes. +type URLMux struct { + schemes openurl.SchemeMap +} + +// RegisterPostgres registers the opener with the given scheme. If an opener +// already exists for the scheme, RegisterPostgres panics. +func (mux *URLMux) RegisterPostgres(scheme string, opener PostgresURLOpener) { + mux.schemes.Register("postgres", "DB", scheme, opener) +} + +// OpenPostgres calls OpenPostgresURL with the URL parsed from urlstr. +// OpenPostgres is safe to call from multiple goroutines. +func (mux *URLMux) OpenPostgres(ctx context.Context, urlstr string) (*sql.DB, error) { + opener, u, err := mux.schemes.FromString("DB", urlstr) + if err != nil { + return nil, err + } + return opener.(PostgresURLOpener).OpenPostgresURL(ctx, u) +} + +// OpenPostgresURL dispatches the URL to the opener that is registered with the +// URL's scheme. OpenPostgresURL is safe to call from multiple goroutines. +func (mux *URLMux) OpenPostgresURL(ctx context.Context, u *url.URL) (*sql.DB, error) { + opener, err := mux.schemes.FromURL("DB", u) + if err != nil { + return nil, err + } + return opener.(PostgresURLOpener).OpenPostgresURL(ctx, u) +} + +var defaultURLMux = new(URLMux) + +// DefaultURLMux returns the URLMux used by OpenPostgres. +// +// Driver packages can use this to register their PostgresURLOpener on the mux. +func DefaultURLMux() *URLMux { + return defaultURLMux +} + +// Open opens the bucket identified by the URL given. URL openers must be +// registered in the DefaultURLMux, which is typically done in driver +// packages' initialization. +// +// See the URLOpener documentation in driver subpackages for more +// details on supported scheme(s) and URL parameter(s). +func Open(ctx context.Context, urlstr string) (*sql.DB, error) { + return defaultURLMux.OpenPostgres(ctx, urlstr) +} diff --git a/go-cloud/postgres/postgres_test.go b/go-cloud/postgres/postgres_test.go new file mode 100644 index 000000000..1a17d196a --- /dev/null +++ b/go-cloud/postgres/postgres_test.go @@ -0,0 +1,132 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 postgres + +import ( + "bytes" + "context" + "fmt" + "net/url" + "os" + "os/exec" + "os/user" + "path/filepath" + "runtime" + "testing" + "time" +) + +func TestOpen(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Can't use Unix sockets on Windows") + } + postgresPath, err := exec.LookPath("postgres") + if err != nil { + t.Skip("Can't find postgres:", err) + } + initdbPath, err := exec.LookPath("initdb") + if err != nil { + t.Skip("Can't find initdb:", err) + } + + // Create a temporary database data directory. + currUser, err := user.Current() + if err != nil { + t.Fatal(err) + } + + dir := t.TempDir() + + dataDir := filepath.Join(dir, "data") + initdbCmd := exec.Command(initdbPath, "-U", currUser.Username, "-D", dataDir) + initdbOutput := new(bytes.Buffer) + initdbCmd.Stdout = initdbOutput + initdbCmd.Stderr = initdbOutput + err = initdbCmd.Run() + if err != nil { + t.Log(initdbOutput) + t.Fatal(err) + } + + // Configure the database server to listen on a Unix socket located in the temporary directory. + socketDir, err := filepath.Abs(filepath.Join(dir, "socket")) + if err != nil { + t.Fatal(err) + } + if err := os.Mkdir(socketDir, 0o777); err != nil { + t.Fatal(err) + } + confData := new(bytes.Buffer) + fmt.Fprintf(confData, "unix_socket_directories = '%s'\n", socketDir) + err = os.WriteFile(filepath.Join(dataDir, "postgresql.conf"), confData.Bytes(), 0o666) + if err != nil { + t.Fatal(err) + } + + // Start the database server (and arrange for it to be stopped at test end). + server := exec.Command(postgresPath, "-D", dataDir) + serverOutput := new(bytes.Buffer) + server.Stdout = serverOutput + server.Stderr = serverOutput + if err := server.Start(); err != nil { + t.Fatal(err) + } + serverSignaled := false + defer func() { + if !serverSignaled { + if err := server.Process.Kill(); err != nil { + t.Error("Stopping server:", err) + } + } + // Wait for server to exit, but ignore the expected failure error code. + server.Wait() + if t.Failed() { + t.Log(serverOutput) + } + }() + + // Now the actual test: can we connect to the database via URL opener? + ctx := context.Background() + dbURL := &url.URL{ + Scheme: "blablabla", // Intentionally not "postgres" to ensure any scheme works. + User: url.User(currUser.Username), + Path: "/postgres", + // Use the query parameter to avoid https://github.com/lib/pq/issues/796 + RawQuery: url.Values{"host": {socketDir}}.Encode(), + } + t.Logf("PostgreSQL URL: %s", dbURL) + db, err := new(URLOpener).OpenPostgresURL(ctx, dbURL) + if err != nil { + t.Fatal(err) + } + // Developing a realistic query would be hard, so instead we trust that the + // PostgreSQL library reports healthy correctly. Since there's no way to + // synchronize the server start and the ping, we might have to ping a few + // times before it is healthy. (The overall test runner timeout will interrupt + // if this takes too long.) + for { + err := db.Ping() + if err == nil { + break + } + t.Log("Ping:", err) + time.Sleep(100 * time.Millisecond) + } + if err := db.Close(); err != nil { + t.Error("Close:", err) + } + server.Process.Signal(os.Interrupt) + serverSignaled = true +} diff --git a/go-cloud/pubsub/acks_test.go b/go-cloud/pubsub/acks_test.go new file mode 100644 index 000000000..3c3e71ef1 --- /dev/null +++ b/go-cloud/pubsub/acks_test.go @@ -0,0 +1,446 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 pubsub_test + +import ( + "context" + "errors" + "math/rand" + "sync" + "testing" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" +) + +type ackingDriverSub struct { + driver.Subscription + q []*driver.Message + sendAcks func(context.Context, []driver.AckID) error +} + +func (s *ackingDriverSub) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + if len(s.q) <= maxMessages { + ms := s.q + s.q = nil + return ms, nil + } + ms := s.q[:maxMessages] + s.q = s.q[maxMessages:] + return ms, nil +} + +func (s *ackingDriverSub) SendAcks(ctx context.Context, ackIDs []driver.AckID) error { + return s.sendAcks(ctx, ackIDs) +} + +func (*ackingDriverSub) IsRetryable(error) bool { return false } +func (*ackingDriverSub) ErrorCode(error) gcerrors.ErrorCode { return gcerrors.Internal } +func (*ackingDriverSub) CanNack() bool { return false } +func (*ackingDriverSub) Close() error { return nil } + +func TestAckTriggersDriverSendAcksForOneMessage(t *testing.T) { + ctx := context.Background() + var mu sync.Mutex + var sentAcks []driver.AckID + id := rand.Int() + m := &driver.Message{AckID: id} + ackChan := make(chan struct{}) + ds := &ackingDriverSub{ + q: []*driver.Message{m}, + sendAcks: func(_ context.Context, ackIDs []driver.AckID) error { + mu.Lock() + defer mu.Unlock() + sentAcks = ackIDs + ackChan <- struct{}{} + return nil + }, + } + sub := pubsub.NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + m2, err := sub.Receive(ctx) + if err != nil { + t.Fatal(err) + } + m2.Ack() + <-ackChan + if len(sentAcks) != 1 { + t.Fatalf("len(sentAcks) = %d, want exactly 1", len(sentAcks)) + } + if sentAcks[0] != id { + t.Errorf("sentAcks[0] = %d, want %d", sentAcks[0], id) + } +} + +func TestMultipleAcksCanGoIntoASingleBatch(t *testing.T) { + ctx := context.Background() + var wg sync.WaitGroup + var mu sync.Mutex + sentAcks := make(map[driver.AckID]int) + ids := []int{1, 2} + ds := &ackingDriverSub{ + q: []*driver.Message{{AckID: ids[0]}, {AckID: ids[1]}}, + sendAcks: func(_ context.Context, ackIDs []driver.AckID) error { + mu.Lock() + defer mu.Unlock() + for _, id := range ackIDs { + sentAcks[id]++ + wg.Done() + } + return nil + }, + } + sub := pubsub.NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + + // Receive and ack the messages concurrently. + for i := 0; i < 2; i++ { + wg.Add(1) + go func() { + mr, err := sub.Receive(ctx) + if err != nil { + t.Error(err) + return + } + mr.Ack() + }() + } + wg.Wait() + + if len(sentAcks) != 2 { + t.Errorf("len(sentAcks) = %d, want exactly 2", len(sentAcks)) + } + for _, id := range ids { + if sentAcks[id] != 1 { + t.Errorf("sentAcks[%v] = %d, want 1", id, sentAcks[id]) + } + } +} + +func TestTooManyAcksForASingleBatchGoIntoMultipleBatches(t *testing.T) { + ctx := context.Background() + var mu sync.Mutex + var wg sync.WaitGroup + var sentAckBatches [][]driver.AckID + // This value of n is chosen large enough that it should create more + // than one batch. Admittedly, there is currently no explicit guarantee + // of this. + n := 1000 + var ms []*driver.Message + for i := 0; i < n; i++ { + ms = append(ms, &driver.Message{AckID: i}) + } + ds := &ackingDriverSub{ + q: ms, + sendAcks: func(_ context.Context, ackIDs []driver.AckID) error { + mu.Lock() + defer mu.Unlock() + sentAckBatches = append(sentAckBatches, ackIDs) + for i := 0; i < len(ackIDs); i++ { + wg.Done() + } + return nil + }, + } + sub := pubsub.NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + + errs := make(chan error, n) + // Receive and ack the messages concurrently. + recv := func() { + mr, err := sub.Receive(ctx) + if err != nil { + errs <- err + } + mr.Ack() + } + wg.Add(n) + for i := 0; i < n; i++ { + go recv() + } + wg.Wait() + + close(errs) + + if len(sentAckBatches) < 2 { + t.Errorf("got %d batches, want at least 2", len(sentAckBatches)) + } + + for err := range errs { + t.Fatalf("got error from goroutine: %v", err) + } +} + +func TestAckDoesNotBlock(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + m := &driver.Message{AckID: 0} // the batcher doesn't like nil interfaces + ds := &ackingDriverSub{ + q: []*driver.Message{m}, + sendAcks: func(_ context.Context, ackIDs []driver.AckID) error { + <-ctx.Done() + return nil + }, + } + sub := pubsub.NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + defer cancel() + mr, err := sub.Receive(ctx) + if err != nil { + t.Fatal(err) + } + // If Ack blocks here, waiting for sendAcks to finish, then the + // deferred cancel() will never run, so sendAcks can never finish. That + // would cause the test to hang. Thus hanging is how this test signals + // failure. + mr.Ack() +} + +func TestDoubleAckCausesPanic(t *testing.T) { + ctx := context.Background() + m := &driver.Message{AckID: 0} // the batcher doesn't like nil interfaces + ds := &ackingDriverSub{ + q: []*driver.Message{m}, + sendAcks: func(_ context.Context, ackIDs []driver.AckID) error { + return nil + }, + } + sub := pubsub.NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + mr, err := sub.Receive(ctx) + if err != nil { + t.Fatal(err) + } + mr.Ack() + defer func() { + if r := recover(); r != nil { + // ok, panic was expected. + return + } + t.Errorf("second ack failed to panic") + }() + mr.Ack() +} + +// For best results, run this test with -race. +func TestConcurrentDoubleAckCausesPanic(t *testing.T) { + ctx := context.Background() + m := &driver.Message{AckID: 0} // the batcher doesn't like nil interfaces + ds := &ackingDriverSub{ + q: []*driver.Message{m}, + sendAcks: func(_ context.Context, ackIDs []driver.AckID) error { + return nil + }, + } + sub := pubsub.NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + mr, err := sub.Receive(ctx) + if err != nil { + t.Fatal(err) + } + + // Spin up some goroutines to ack the message. + var mu sync.Mutex + panics := 0 + var wg sync.WaitGroup + for i := 0; i < 2; i++ { + wg.Add(1) + go func() { + defer wg.Done() + defer func() { + if r := recover(); r != nil { + mu.Lock() + defer mu.Unlock() + panics++ + } + }() + mr.Ack() + }() + } + wg.Wait() + + // Check that one of the goroutines panicked. + if panics != 1 { + t.Errorf("panics = %d, want %d", panics, 1) + } +} + +func TestSubShutdownCanBeCanceledEvenWithHangingSendAcks(t *testing.T) { + ctx := context.Background() + m := &driver.Message{AckID: 0} // the batcher doesn't like nil interfaces + ds := &ackingDriverSub{ + q: []*driver.Message{m}, + sendAcks: func(ctx context.Context, ackIDs []driver.AckID) error { + <-ctx.Done() + return ctx.Err() + }, + } + sub := pubsub.NewSubscription(ds, nil, nil) + mr, err := sub.Receive(ctx) + if err != nil { + t.Fatal(err) + } + mr.Ack() + + done := make(chan struct{}) + go func() { + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) + defer cancel() + sub.Shutdown(ctx) + close(done) + }() + tooLong := 5 * time.Second + select { + case <-done: + case <-time.After(tooLong): + t.Fatalf("waited too long (%v) for Shutdown to run", tooLong) + } +} + +func TestReceiveReturnsErrorFromSendAcks(t *testing.T) { + // If SendAcks fails, the error is returned via receive. + ctx := context.Background() + serr := errors.New("SendAcks failed") + ackChan := make(chan struct{}) + ds := &ackingDriverSub{ + q: []*driver.Message{ + {AckID: 0}, + {AckID: 1}, + {AckID: 2}, + {AckID: 3}, + }, + sendAcks: func(context.Context, []driver.AckID) error { + close(ackChan) + return serr + }, + } + sub := pubsub.NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + m, err := sub.Receive(ctx) + if err != nil { + t.Fatal(err) + } + m.Ack() + // Wait for the ack to be sent. + <-ackChan + // It might take a bit longer for the logic after SendAcks returns to happen, so + // keep calling Receive. + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + for { + _, err = sub.Receive(ctx) + if gcerrors.Code(err) == gcerrors.Internal && err.(*gcerr.Error).Unwrap() == serr { + break // success + } + if err != nil { + t.Fatalf("got %v, want %v", err, serr) + } + } +} + +// callbackDriverSub implements driver.Subscription and allows something like +// monkey patching of both its ReceiveBatch and SendAcks methods. +type callbackDriverSub struct { + driver.Subscription + mu sync.Mutex + receiveBatch func(context.Context) ([]*driver.Message, error) + sendAcks func(context.Context, []driver.AckID) error +} + +func (s *callbackDriverSub) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + return s.receiveBatch(ctx) +} + +func (s *callbackDriverSub) SendAcks(ctx context.Context, acks []driver.AckID) error { + return s.sendAcks(ctx, acks) +} + +func (*callbackDriverSub) IsRetryable(error) bool { return false } +func (*callbackDriverSub) ErrorCode(error) gcerrors.ErrorCode { return gcerrors.Internal } +func (*callbackDriverSub) CanNack() bool { return false } +func (*callbackDriverSub) Close() error { return nil } + +// This test detects the root cause of +// https://github.com/google/go-cloud/issues/1238. +// If the issue is present, this test times out. The problem was that when +// there were no messages available from the driver, +// pubsub.Subscription.Receive would spin trying to get more messages without +// checking to see if an unrecoverable error had occurred while sending a batch +// of acks to the driver. +func TestReceiveReturnsAckErrorOnNoMoreMessages(t *testing.T) { + // If SendAcks fails, the error is returned via receive. + ctx := context.Background() + serr := errors.New("unrecoverable error") + receiveHappened := make(chan struct{}) + ackHappened := make(chan struct{}) + ds := &callbackDriverSub{ + // First call to receiveBatch will return a single message. + receiveBatch: func(context.Context) ([]*driver.Message, error) { + ms := []*driver.Message{{AckID: 1}} + return ms, nil + }, + sendAcks: func(context.Context, []driver.AckID) error { + ackHappened <- struct{}{} + return serr + }, + } + sub := pubsub.NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + m, err := sub.Receive(ctx) + if err != nil { + t.Fatal(err) + } + m.Ack() + + // Second call to receiveBatch will wait for the pull from the + // receiveHappened channel below, and return a nil slice of messages. + ds.mu.Lock() + ds.receiveBatch = func(context.Context) ([]*driver.Message, error) { + ds.mu.Lock() + // Subsequent calls to receiveBatch won't wait on receiveHappened, + // and will also return nil slices of messages. + ds.receiveBatch = func(context.Context) ([]*driver.Message, error) { + return nil, nil + } + ds.mu.Unlock() + receiveHappened <- struct{}{} + return nil, nil + } + ds.mu.Unlock() + + errc := make(chan error) + go func() { + _, err := sub.Receive(ctx) + errc <- err + }() + + // sub.Receive has to start running first and then we need to trigger the unrecoverable error. + <-receiveHappened + + // Trigger the unrecoverable error. + <-ackHappened + + // Wait for sub.Receive to return so we can check the error it returns against serr. + err = <-errc + + // Check the error returned from sub.Receive. + if got := gcerrors.Code(err); got != gcerrors.Internal { + t.Fatalf("error code = %v; want %v", got, gcerrors.Internal) + } + if got := errors.Unwrap(err); got != serr { + t.Errorf("error = %v; want %v", got, serr) + } +} diff --git a/go-cloud/pubsub/awssnssqs/awssnssqs.go b/go-cloud/pubsub/awssnssqs/awssnssqs.go new file mode 100644 index 000000000..36d05f1db --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/awssnssqs.go @@ -0,0 +1,1012 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awssnssqs provides two implementations of pubsub.Topic, one that +// sends messages to AWS SNS (Simple Notification Service), and one that sends +// messages to SQS (Simple Queuing Service). It also provides an implementation +// of pubsub.Subscription that receives messages from SQS. +// +// # URLs +// +// For pubsub.OpenTopic, awssnssqs registers for the scheme "awssns" for +// an SNS topic, and "awssqs" for an SQS topic. For pubsub.OpenSubscription, +// it registers for the scheme "awssqs". +// +// The default URL opener will use an AWS session with the default credentials +// and configuration. +// +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # Message Delivery Semantics +// +// AWS SQS supports at-least-once semantics; applications must call Message.Ack +// after processing a message, or it will be redelivered. +// See https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery +// for more background. +// +// # Escaping +// +// Go CDK supports all UTF-8 strings; to make this work with services lacking +// full UTF-8 support, strings must be escaped (during writes) and unescaped +// (during reads). The following escapes are required for awssnssqs: +// - Metadata keys: Characters other than "a-zA-z0-9_-.", and additionally "." +// when it's at the start of the key or the previous character was ".", +// are escaped using "__0x__". These characters were determined by +// experimentation. +// - Metadata values: Escaped using URL encoding. +// - Message body: AWS SNS/SQS only supports UTF-8 strings. See the +// BodyBase64Encoding enum in TopicOptions for strategies on how to send +// non-UTF-8 message bodies. By default, non-UTF-8 message bodies are base64 +// encoded. +// +// # As +// +// awssnssqs exposes the following types for As: +// - Topic: *sns.Client for OpenSNSTopic, *sqs.Client for OpenSQSTopic +// - Subscription: *sqs.Client +// - Message: sqstypes.Message +// - Message.BeforeSend: *sns.PublishBatchRequestEntry or *sns.PublishInput (deprecated) for OpenSNSTopic, *sqstypes.SendMessageBatchRequestEntry for OpenSQSTopic +// - Message.AfterSend: snstypes.PublishBatchResultEntry or *sns.PublishOutput (deprecated) for OpenSNSTopic, sqstypes.SendMessageBatchResultEntry for OpenSQSTopic +// - Error: any error type returned by the service, notably smithy.APIError +package awssnssqs // import "gocloud.dev/pubsub/awssnssqs" + +import ( + "context" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "net/url" + "path" + "strconv" + "strings" + "sync" + "time" + "unicode/utf8" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/sns" + snstypes "github.com/aws/aws-sdk-go-v2/service/sns/types" + "github.com/aws/aws-sdk-go-v2/service/sqs" + sqstypes "github.com/aws/aws-sdk-go-v2/service/sqs/types" + "github.com/aws/smithy-go" + "github.com/google/wire" + gcaws "github.com/DataDog/iceberg-go/go-cloud/aws" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/escape" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/batcher" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" +) + +const ( + // base64EncodedKey is the Message Attribute key used to flag that the + // message body is base64 encoded. + base64EncodedKey = "base64encoded" + // How long ReceiveBatch should wait if no messages are available; controls + // the poll interval of requests to SQS. + noMessagesPollDuration = 250 * time.Millisecond +) + +var sendBatcherOptsSNS = &batcher.Options{ + MaxBatchSize: 10, // SNS SendBatch supports 10 message at a time + MaxHandlers: 100, // max concurrency for sends +} + +var sendBatcherOptsSQS = &batcher.Options{ + MaxBatchSize: 10, // SQS SendBatch supports 10 messages at a time + MaxHandlers: 100, // max concurrency for sends +} + +var recvBatcherOpts = &batcher.Options{ + // SQS supports receiving at most 10 messages at a time: + // https://godoc.org/github.com/aws/aws-sdk-go/service/sqs#SQS.ReceiveMessage + MaxBatchSize: 10, + MaxHandlers: 100, // max concurrency for receives +} + +var ackBatcherOpts = &batcher.Options{ + // SQS supports deleting/updating at most 10 messages at a time: + // https://godoc.org/github.com/aws/aws-sdk-go/service/sqs#SQS.DeleteMessageBatch + // https://godoc.org/github.com/aws/aws-sdk-go/service/sqs#SQS.ChangeMessageVisibilityBatch + MaxBatchSize: 10, + MaxHandlers: 100, // max concurrency for acks +} + +func init() { + lazy := new(lazySessionOpener) + pubsub.DefaultURLMux().RegisterTopic(SNSScheme, lazy) + pubsub.DefaultURLMux().RegisterTopic(SQSScheme, lazy) + pubsub.DefaultURLMux().RegisterSubscription(SQSScheme, lazy) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + DialSNS, + DialSQS, +) + +// DialSNS gets an AWS SNS service client using the AWS SDK V2. +func DialSNS(cfg aws.Config) *sns.Client { + return sns.NewFromConfig(cfg) +} + +// DialSQS gets an AWS SQS service client using the AWS SDK V2. +func DialSQS(cfg aws.Config) *sqs.Client { + return sqs.NewFromConfig(cfg) +} + +// lazySessionOpener obtains the AWS session from the environment on the first +// call to OpenXXXURL. +type lazySessionOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazySessionOpener) defaultOpener(u *url.URL) (*URLOpener, error) { + return &URLOpener{}, nil +} + +func (o *lazySessionOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + opener, err := o.defaultOpener(u) + if err != nil { + return nil, fmt.Errorf("open topic %v: failed to open default session: %v", u, err) + } + return opener.OpenTopicURL(ctx, u) +} + +func (o *lazySessionOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + opener, err := o.defaultOpener(u) + if err != nil { + return nil, fmt.Errorf("open subscription %v: failed to open default session: %v", u, err) + } + return opener.OpenSubscriptionURL(ctx, u) +} + +// SNSScheme is the URL scheme for pubsub.OpenTopic (for an SNS topic) that +// awssnssqs registers its URLOpeners under on pubsub.DefaultMux. +const SNSScheme = "awssns" + +// SQSScheme is the URL scheme for pubsub.OpenTopic (for an SQS topic) and for +// pubsub.OpenSubscription that awssnssqs registers its URLOpeners under on +// pubsub.DefaultMux. +const SQSScheme = "awssqs" + +// URLOpener opens AWS SNS/SQS URLs like "awssns:///sns-topic-arn" for +// SNS topics or "awssqs://sqs-queue-url" for SQS topics and subscriptions. +// +// For SNS topics, the URL's host+path is used as the topic Amazon Resource Name +// (ARN). Since ARNs have ":" in them, and ":" precedes a port in URL +// hostnames, leave the host blank and put the ARN in the path +// (e.g., "awssns:///arn:aws:service:region:accountid:resourceType/resourcePath"). +// +// For SQS topics and subscriptions, the URL's host+path is prefixed with +// "https://" to create the queue URL. +// +// See https://pkg.go.dev/gocloud.dev/aws#V2ConfigFromURLParams. +// +// In addition, the following query parameters are supported: +// +// - raw (for "awssqs" Subscriptions only): sets SubscriberOptions.Raw. The +// value must be parseable by `strconv.ParseBool`. +// - nacklazy (for "awssqs" Subscriptions only): sets SubscriberOptions.NackLazy. The +// value must be parseable by `strconv.ParseBool`. +// - waittime: sets SubscriberOptions.WaitTime, in time.ParseDuration formats. +// +// See gocloud.dev/aws/ConfigFromURLParams for other query parameters +// that affect the default AWS session. +type URLOpener struct { + // TopicOptions specifies the options to pass to OpenTopic. + TopicOptions TopicOptions + // SubscriptionOptions specifies the options to pass to OpenSubscription. + SubscriptionOptions SubscriptionOptions +} + +// OpenTopicURL opens a pubsub.Topic based on u. +func (o *URLOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + // Trim leading "/" if host is empty, so that + // awssns:///arn:aws:service:region:accountid:resourceType/resourcePath + // gives "arn:..." instead of "/arn:...". + topicARN := strings.TrimPrefix(path.Join(u.Host, u.Path), "/") + qURL := "https://" + path.Join(u.Host, u.Path) + cfg, err := gcaws.V2ConfigFromURLParams(ctx, u.Query()) + if err != nil { + return nil, fmt.Errorf("open topic %v: %v", u, err) + } + switch u.Scheme { + case SNSScheme: + return OpenSNSTopic(ctx, sns.NewFromConfig(cfg), topicARN, &o.TopicOptions), nil + case SQSScheme: + return OpenSQSTopic(ctx, sqs.NewFromConfig(cfg), qURL, &o.TopicOptions), nil + default: + return nil, fmt.Errorf("open topic %v: unsupported scheme", u) + } +} + +// OpenSubscriptionURL opens a pubsub.Subscription based on u. +func (o *URLOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + // Clone the options since we might override Raw. + opts := o.SubscriptionOptions + q := u.Query() + if rawStr := q.Get("raw"); rawStr != "" { + var err error + opts.Raw, err = strconv.ParseBool(rawStr) + if err != nil { + return nil, fmt.Errorf("invalid value %q for raw: %v", rawStr, err) + } + q.Del("raw") + } + if nackLazyStr := q.Get("nacklazy"); nackLazyStr != "" { + var err error + opts.NackLazy, err = strconv.ParseBool(nackLazyStr) + if err != nil { + return nil, fmt.Errorf("invalid value %q for nacklazy: %v", nackLazyStr, err) + } + q.Del("nacklazy") + } + if waitTimeStr := q.Get("waittime"); waitTimeStr != "" { + var err error + opts.WaitTime, err = time.ParseDuration(waitTimeStr) + if err != nil { + return nil, fmt.Errorf("invalid value %q for waittime: %v", waitTimeStr, err) + } + q.Del("waittime") + } + qURL := "https://" + path.Join(u.Host, u.Path) + cfg, err := gcaws.V2ConfigFromURLParams(ctx, q) + if err != nil { + return nil, fmt.Errorf("open subscription %v: %v", u, err) + } + return OpenSubscription(ctx, sqs.NewFromConfig(cfg), qURL, &opts), nil +} + +type snsTopic struct { + client *sns.Client + arn string + opts *TopicOptions +} + +// BodyBase64Encoding is an enum of strategies for when to base64 message +// bodies. +type BodyBase64Encoding int + +const ( + // NonUTF8Only means that message bodies that are valid UTF-8 encodings are + // sent as-is. Invalid UTF-8 message bodies are base64 encoded, and a + // MessageAttribute with key "base64encoded" is added to the message. + // When receiving messages, the "base64encoded" attribute is used to determine + // whether to base64 decode, and is then filtered out. + NonUTF8Only BodyBase64Encoding = 0 + // Always means that all message bodies are base64 encoded. + // A MessageAttribute with key "base64encoded" is added to the message. + // When receiving messages, the "base64encoded" attribute is used to determine + // whether to base64 decode, and is then filtered out. + Always BodyBase64Encoding = 1 + // Never means that message bodies are never base64 encoded. Non-UTF-8 + // bytes in message bodies may be modified by SNS/SQS. + Never BodyBase64Encoding = 2 +) + +func (e BodyBase64Encoding) wantEncode(b []byte) bool { + switch e { + case Always: + return true + case Never: + return false + case NonUTF8Only: + return !utf8.Valid(b) + } + panic("unreachable") +} + +// TopicOptions contains configuration options for topics. +type TopicOptions struct { + // BodyBase64Encoding determines when message bodies are base64 encoded. + // The default is NonUTF8Only. + BodyBase64Encoding BodyBase64Encoding + + // BatcherOptions adds constraints to the default batching done for sends. + BatcherOptions batcher.Options +} + +// OpenSNSTopic opens a topic that sends to the SNS topic with the given Amazon +// Resource Name (ARN), using AWS SDK V2. +func OpenSNSTopic(ctx context.Context, client *sns.Client, topicARN string, opts *TopicOptions) *pubsub.Topic { + if opts == nil { + opts = &TopicOptions{} + } + bo := sendBatcherOptsSNS.NewMergedOptions(&opts.BatcherOptions) + return pubsub.NewTopic(openSNSTopic(ctx, client, topicARN, opts), bo) +} + +var OpenSNSTopicV2 = OpenSNSTopic + +// openSNSTopic returns the driver for OpenSNSTopic. This function exists so the test +// harness can get the driver interface implementation if it needs to. +func openSNSTopic(ctx context.Context, client *sns.Client, topicARN string, opts *TopicOptions) driver.Topic { + return &snsTopic{ + client: client, + arn: topicARN, + opts: opts, + } +} + +var stringDataType = aws.String("String") + +// encodeMetadata encodes the keys and values of md as needed. +func encodeMetadata(md map[string]string) map[string]string { + retval := map[string]string{} + for k, v := range md { + // See the package comments for more details on escaping of metadata + // keys & values. + k = escape.HexEscape(k, func(runes []rune, i int) bool { + c := runes[i] + switch { + case escape.IsASCIIAlphanumeric(c): + return false + case c == '_' || c == '-': + return false + case c == '.' && i != 0 && runes[i-1] != '.': + return false + } + return true + }) + retval[k] = escape.URLEscape(v) + } + return retval +} + +// maybeEncodeBody decides whether body should base64-encoded based on opt, and +// returns the (possibly encoded) body as a string, along with a boolean +// indicating whether encoding occurred. +func maybeEncodeBody(body []byte, opt BodyBase64Encoding) (string, bool) { + if opt.wantEncode(body) { + return base64.StdEncoding.EncodeToString(body), true + } + return string(body), false +} + +// Defines values for Metadata keys used by the driver for setting message +// attributes on SNS ([sns.PublishBatchRequestEntry]/[snstypes.PublishBatchRequestEntry]) +// and SQS ([sqs.SendMessageBatchRequestEntry]/[sqstypes.SendMessageBatchRequestEntry]) +// messages. +// +// For example, to set a deduplication ID and message group ID on a message: +// +// import ( +// "gocloud.dev/pubsub" +// "gocloud.dev/pubsub/awssnssqs" +// ) +// +// message := pubsub.Message{ +// Body: []byte("Hello, World!"), +// Metadata: map[string]string{ +// awssnssqs.MetadataKeyDeduplicationID: "my-dedup-id", +// awssnssqs.MetadataKeyMessageGroupID: "my-group-id", +// }, +// } +const ( + MetadataKeyDeduplicationID = "DeduplicationId" + MetadataKeyMessageGroupID = "MessageGroupId" +) + +// reviseSnsEntryAttributes sets attributes on a [snstypes.PublishBatchRequestEntry] based on [driver.Message.Metadata]. +func reviseSnsEntryAttributes(dm *driver.Message, entry *snstypes.PublishBatchRequestEntry) { + if dedupID, ok := dm.Metadata[MetadataKeyDeduplicationID]; ok { + entry.MessageDeduplicationId = aws.String(dedupID) + } + if groupID, ok := dm.Metadata[MetadataKeyMessageGroupID]; ok { + entry.MessageGroupId = aws.String(groupID) + } +} + +// SendBatch implements driver.Topic.SendBatch. +func (t *snsTopic) SendBatch(ctx context.Context, dms []*driver.Message) error { + req := &sns.PublishBatchInput{ + TopicArn: &t.arn, + } + for _, dm := range dms { + attrs := map[string]snstypes.MessageAttributeValue{} + for k, v := range encodeMetadata(dm.Metadata) { + attrs[k] = snstypes.MessageAttributeValue{ + DataType: stringDataType, + StringValue: aws.String(v), + } + } + body, didEncode := maybeEncodeBody(dm.Body, t.opts.BodyBase64Encoding) + if didEncode { + attrs[base64EncodedKey] = snstypes.MessageAttributeValue{ + DataType: stringDataType, + StringValue: aws.String("true"), + } + } + if len(attrs) == 0 { + attrs = nil + } + entry := &snstypes.PublishBatchRequestEntry{ + Id: aws.String(strconv.Itoa(len(req.PublishBatchRequestEntries))), + MessageAttributes: attrs, + Message: aws.String(body), + } + reviseSnsEntryAttributes(dm, entry) + if dm.BeforeSend != nil { + // A previous revision used the non-batch API PublishInput, which takes + // a *sns.PublishInput. For backwards compatibility for As, continue + // to support that type. If it is requested, create a PublishInput + // with the fields from PublishBatchRequestEntry that were set, and + // then copy all of the matching fields back after calling dm.BeforeSend. + var pi *sns.PublishInput + asFunc := func(i any) bool { + if p, ok := i.(**sns.PublishInput); ok { + pi = &sns.PublishInput{ + // Id does not exist on PublishInput. + MessageAttributes: entry.MessageAttributes, + Message: entry.Message, + } + *p = pi + return true + } + if p, ok := i.(**snstypes.PublishBatchRequestEntry); ok { + *p = entry + return true + } + return false + } + if err := dm.BeforeSend(asFunc); err != nil { + return err + } + if pi != nil { + // Copy all of the fields that may have been modified back to the entry. + entry.MessageAttributes = pi.MessageAttributes + entry.Message = pi.Message + entry.MessageDeduplicationId = pi.MessageDeduplicationId + entry.MessageGroupId = pi.MessageGroupId + entry.MessageStructure = pi.MessageStructure + entry.Subject = pi.Subject + } + } + req.PublishBatchRequestEntries = append(req.PublishBatchRequestEntries, *entry) + } + resp, err := t.client.PublishBatch(ctx, req) + if err != nil { + return err + } + if numFailed := len(resp.Failed); numFailed > 0 { + first := resp.Failed[0] + return fmt.Errorf("sns.PublishBatch failed for %d message(s): %s, %s", numFailed, aws.ToString(first.Code), aws.ToString(first.Message)) + } + if len(resp.Successful) == len(dms) { + for n, dm := range dms { + if dm.AfterSend != nil { + asFunc := func(i any) bool { + if p, ok := i.(*snstypes.PublishBatchResultEntry); ok { + *p = resp.Successful[n] + return true + } + if p, ok := i.(**sns.PublishOutput); ok { + // For backwards compability. + *p = &sns.PublishOutput{ + MessageId: resp.Successful[n].MessageId, + SequenceNumber: resp.Successful[n].SequenceNumber, + } + return true + } + return false + } + if err := dm.AfterSend(asFunc); err != nil { + return err + } + } + } + } + return nil +} + +// IsRetryable implements driver.Topic.IsRetryable. +func (t *snsTopic) IsRetryable(error) bool { + // The client handles retries. + return false +} + +// As implements driver.Topic.As. +func (t *snsTopic) As(i any) bool { + c, ok := i.(**sns.Client) + if !ok { + return false + } + *c = t.client + return true +} + +// ErrorAs implements driver.Topic.ErrorAs. +func (t *snsTopic) ErrorAs(err error, i any) bool { + return errorAs(err, i) +} + +// ErrorCode implements driver.Topic.ErrorCode. +func (t *snsTopic) ErrorCode(err error) gcerrors.ErrorCode { + return errorCode(err) +} + +// Close implements driver.Topic.Close. +func (*snsTopic) Close() error { return nil } + +type sqsTopic struct { + client *sqs.Client + qURL string + opts *TopicOptions +} + +// OpenSQSTopic opens a topic that sends to the SQS topic with the given SQS +// queue URL, using AWS SDK V2. +func OpenSQSTopic(ctx context.Context, client *sqs.Client, qURL string, opts *TopicOptions) *pubsub.Topic { + if opts == nil { + opts = &TopicOptions{} + } + bo := sendBatcherOptsSQS.NewMergedOptions(&opts.BatcherOptions) + return pubsub.NewTopic(openSQSTopic(ctx, client, qURL, opts), bo) +} + +var OpenSQSTopicV2 = OpenSQSTopic + +// openSQSTopic returns the driver for OpenSQSTopic. This function exists so the test +// harness can get the driver interface implementation if it needs to. +func openSQSTopic(ctx context.Context, client *sqs.Client, qURL string, opts *TopicOptions) driver.Topic { + return &sqsTopic{ + client: client, + qURL: qURL, + opts: opts, + } +} + +// reviseSqsEntryAttributes sets attributes on a [sqstypes.SendMessageBatchRequestEntry] based on [driver.Message.Metadata]. +func reviseSqsEntryAttributes(dm *driver.Message, entry *sqstypes.SendMessageBatchRequestEntry) { + if dedupID, ok := dm.Metadata[MetadataKeyDeduplicationID]; ok { + entry.MessageDeduplicationId = aws.String(dedupID) + } + if groupID, ok := dm.Metadata[MetadataKeyMessageGroupID]; ok { + entry.MessageGroupId = aws.String(groupID) + } +} + +// SendBatch implements driver.Topic.SendBatch. +func (t *sqsTopic) SendBatch(ctx context.Context, dms []*driver.Message) error { + req := &sqs.SendMessageBatchInput{ + QueueUrl: aws.String(t.qURL), + } + for _, dm := range dms { + attrs := map[string]sqstypes.MessageAttributeValue{} + for k, v := range encodeMetadata(dm.Metadata) { + attrs[k] = sqstypes.MessageAttributeValue{ + DataType: stringDataType, + StringValue: aws.String(v), + } + } + body, didEncode := maybeEncodeBody(dm.Body, t.opts.BodyBase64Encoding) + if didEncode { + attrs[base64EncodedKey] = sqstypes.MessageAttributeValue{ + DataType: stringDataType, + StringValue: aws.String("true"), + } + } + if len(attrs) == 0 { + attrs = nil + } + entry := &sqstypes.SendMessageBatchRequestEntry{ + Id: aws.String(strconv.Itoa(len(req.Entries))), + MessageAttributes: attrs, + MessageBody: aws.String(body), + } + reviseSqsEntryAttributes(dm, entry) + if dm.BeforeSend != nil { + asFunc := func(i any) bool { + if p, ok := i.(**sqstypes.SendMessageBatchRequestEntry); ok { + *p = entry + return true + } + return false + } + if err := dm.BeforeSend(asFunc); err != nil { + return err + } + } + req.Entries = append(req.Entries, *entry) + } + resp, err := t.client.SendMessageBatch(ctx, req) + if err != nil { + return err + } + if numFailed := len(resp.Failed); numFailed > 0 { + first := resp.Failed[0] + return fmt.Errorf("sqs.SendMessageBatch failed for %d message(s): %s, %s", numFailed, aws.ToString(first.Code), aws.ToString(first.Message)) + } + if len(resp.Successful) == len(dms) { + for n, dm := range dms { + if dm.AfterSend != nil { + asFunc := func(i any) bool { + if p, ok := i.(*sqstypes.SendMessageBatchResultEntry); ok { + *p = resp.Successful[n] + return true + } + return false + } + if err := dm.AfterSend(asFunc); err != nil { + return err + } + } + } + } + return nil +} + +// IsRetryable implements driver.Topic.IsRetryable. +func (t *sqsTopic) IsRetryable(error) bool { + // The client handles retries. + return false +} + +// As implements driver.Topic.As. +func (t *sqsTopic) As(i any) bool { + c, ok := i.(**sqs.Client) + if !ok { + return false + } + *c = t.client + return true +} + +// ErrorAs implements driver.Topic.ErrorAs. +func (t *sqsTopic) ErrorAs(err error, i any) bool { + return errorAs(err, i) +} + +// ErrorCode implements driver.Topic.ErrorCode. +func (t *sqsTopic) ErrorCode(err error) gcerrors.ErrorCode { + return errorCode(err) +} + +// Close implements driver.Topic.Close. +func (*sqsTopic) Close() error { return nil } + +func errorCode(err error) gcerrors.ErrorCode { + var code string + var ae smithy.APIError + if errors.As(err, &ae) { + code = ae.ErrorCode() + } else { + return gcerrors.Unknown + } + ec, ok := errorCodeMap[code] + if !ok { + return gcerrors.Unknown + } + return ec +} + +var errorCodeMap = map[string]gcerrors.ErrorCode{ + (&snstypes.AuthorizationErrorException{}).ErrorCode(): gcerrors.PermissionDenied, + (&snstypes.KMSAccessDeniedException{}).ErrorCode(): gcerrors.PermissionDenied, + (&snstypes.KMSDisabledException{}).ErrorCode(): gcerrors.FailedPrecondition, + (&snstypes.KMSInvalidStateException{}).ErrorCode(): gcerrors.FailedPrecondition, + (&snstypes.KMSOptInRequired{}).ErrorCode(): gcerrors.FailedPrecondition, + (&sqstypes.MessageNotInflight{}).ErrorCode(): gcerrors.FailedPrecondition, + (&sqstypes.PurgeQueueInProgress{}).ErrorCode(): gcerrors.FailedPrecondition, + (&sqstypes.QueueDeletedRecently{}).ErrorCode(): gcerrors.FailedPrecondition, + (&sqstypes.QueueNameExists{}).ErrorCode(): gcerrors.FailedPrecondition, + (&snstypes.InternalErrorException{}).ErrorCode(): gcerrors.Internal, + (&snstypes.InvalidParameterException{}).ErrorCode(): gcerrors.InvalidArgument, + (&snstypes.InvalidParameterValueException{}).ErrorCode(): gcerrors.InvalidArgument, + (&sqstypes.BatchEntryIdsNotDistinct{}).ErrorCode(): gcerrors.InvalidArgument, + (&sqstypes.BatchRequestTooLong{}).ErrorCode(): gcerrors.InvalidArgument, + (&sqstypes.EmptyBatchRequest{}).ErrorCode(): gcerrors.InvalidArgument, + (&sqstypes.InvalidAttributeName{}).ErrorCode(): gcerrors.InvalidArgument, + (&sqstypes.InvalidBatchEntryId{}).ErrorCode(): gcerrors.InvalidArgument, + (&sqstypes.InvalidIdFormat{}).ErrorCode(): gcerrors.InvalidArgument, + (&sqstypes.InvalidMessageContents{}).ErrorCode(): gcerrors.InvalidArgument, + (&sqstypes.ReceiptHandleIsInvalid{}).ErrorCode(): gcerrors.InvalidArgument, + (&sqstypes.TooManyEntriesInBatchRequest{}).ErrorCode(): gcerrors.InvalidArgument, + (&sqstypes.UnsupportedOperation{}).ErrorCode(): gcerrors.InvalidArgument, + (&snstypes.InvalidSecurityException{}).ErrorCode(): gcerrors.PermissionDenied, + (&snstypes.KMSNotFoundException{}).ErrorCode(): gcerrors.NotFound, + (&snstypes.NotFoundException{}).ErrorCode(): gcerrors.NotFound, + (&sqstypes.QueueDoesNotExist{}).ErrorCode(): gcerrors.NotFound, + "AWS.SimpleQueueService.NonExistentQueue": gcerrors.NotFound, + (&snstypes.FilterPolicyLimitExceededException{}).ErrorCode(): gcerrors.ResourceExhausted, + (&snstypes.SubscriptionLimitExceededException{}).ErrorCode(): gcerrors.ResourceExhausted, + (&snstypes.TopicLimitExceededException{}).ErrorCode(): gcerrors.ResourceExhausted, + (&sqstypes.OverLimit{}).ErrorCode(): gcerrors.ResourceExhausted, + (&snstypes.KMSThrottlingException{}).ErrorCode(): gcerrors.ResourceExhausted, + (&snstypes.ThrottledException{}).ErrorCode(): gcerrors.ResourceExhausted, + "RequestCanceled": gcerrors.Canceled, + (&snstypes.EndpointDisabledException{}).ErrorCode(): gcerrors.Unknown, + (&snstypes.PlatformApplicationDisabledException{}).ErrorCode(): gcerrors.Unknown, +} + +type subscription struct { + client *sqs.Client + qURL string + opts *SubscriptionOptions +} + +// SubscriptionOptions will contain configuration for subscriptions. +type SubscriptionOptions struct { + // Raw determines how the Subscription will process message bodies. + // + // If the subscription is expected to process messages sent directly to + // SQS, or messages from SNS topics configured to use "raw" delivery, + // set this to true. Message bodies will be passed through untouched. + // + // If false, the Subscription will use best-effort heuristics to + // identify whether message bodies are raw or SNS JSON; this may be + // inefficient for raw messages. + // + // See https://aws.amazon.com/sns/faqs/#Raw_message_delivery. + Raw bool + + // NackLazy determines what Nack does. + // + // By default, Nack uses ChangeMessageVisibility to set the VisibilityTimeout + // for the nacked message to 0, so that it will be redelivered immediately. + // Set NackLazy to true to bypass this behavior; Nack will do nothing, + // and the message will be redelivered after the existing VisibilityTimeout + // expires (defaults to 30s, but can be configured per queue). + // + // See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html. + NackLazy bool + + // WaitTime passed to ReceiveMessage to enable long polling. + // https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html#sqs-long-polling. + // Note that a non-zero WaitTime can delay delivery of messages + // by up to that duration. + WaitTime time.Duration + + // ReceiveBatcherOptions adds constraints to the default batching done for receives. + ReceiveBatcherOptions batcher.Options + + // AckBatcherOptions adds constraints to the default batching done for acks. + AckBatcherOptions batcher.Options +} + +// OpenSubscription opens a subscription based on AWS SQS for the given SQS +// queue URL, using AWS SDK V2. The queue is assumed to be subscribed to some SNS topic, though +// there is no check for this. +func OpenSubscription(ctx context.Context, client *sqs.Client, qURL string, opts *SubscriptionOptions) *pubsub.Subscription { + if opts == nil { + opts = &SubscriptionOptions{} + } + rbo := recvBatcherOpts.NewMergedOptions(&opts.ReceiveBatcherOptions) + abo := ackBatcherOpts.NewMergedOptions(&opts.AckBatcherOptions) + return pubsub.NewSubscription(openSubscription(ctx, client, qURL, opts), rbo, abo) +} + +var OpenSubscriptionV2 = OpenSubscription + +// openSubscription returns a driver.Subscription. +func openSubscription(ctx context.Context, client *sqs.Client, qURL string, opts *SubscriptionOptions) driver.Subscription { + return &subscription{ + client: client, + qURL: qURL, + opts: opts, + } +} + +// ReceiveBatch implements driver.Subscription.ReceiveBatch. +func (s *subscription) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + var ms []*driver.Message + req := &sqs.ReceiveMessageInput{ + QueueUrl: aws.String(s.qURL), + MaxNumberOfMessages: int32(maxMessages), + MessageAttributeNames: []string{"All"}, + AttributeNames: []sqstypes.QueueAttributeName{"All"}, + } + if s.opts.WaitTime != 0 { + req.WaitTimeSeconds = int32(s.opts.WaitTime.Seconds()) + } + output, err := s.client.ReceiveMessage(ctx, req) + if err != nil { + return nil, err + } + for _, m := range output.Messages { + m := m + bodyStr := aws.ToString(m.Body) + rawAttrs := map[string]string{} + for k, v := range m.MessageAttributes { + rawAttrs[k] = aws.ToString(v.StringValue) + } + bodyStr, rawAttrs = extractBody(bodyStr, rawAttrs, s.opts.Raw) + + decodeIt := false + attrs := map[string]string{} + for k, v := range rawAttrs { + // See BodyBase64Encoding for details on when we base64 decode message bodies. + if k == base64EncodedKey { + decodeIt = true + continue + } + // See the package comments for more details on escaping of metadata + // keys & values. + attrs[escape.HexUnescape(k)] = escape.URLUnescape(v) + } + + var b []byte + if decodeIt { + var err error + b, err = base64.StdEncoding.DecodeString(bodyStr) + if err != nil { + // Fall back to using the raw message. + b = []byte(bodyStr) + } + } else { + b = []byte(bodyStr) + } + + m2 := &driver.Message{ + LoggableID: aws.ToString(m.MessageId), + Body: b, + Metadata: attrs, + AckID: m.ReceiptHandle, + AsFunc: func(i any) bool { + p, ok := i.(*sqstypes.Message) + if !ok { + return false + } + *p = m + return true + }, + } + ms = append(ms, m2) + } + if len(ms) == 0 { + // When we return no messages and no error, the portable type will call + // ReceiveBatch again immediately. Sleep for a bit to avoid hammering SQS + // with RPCs. + time.Sleep(noMessagesPollDuration) + } + return ms, nil +} + +func extractBody(bodyStr string, rawAttrs map[string]string, raw bool) (body string, attributes map[string]string) { + // If the user told us that message bodies are raw, or if there are + // top-level MessageAttributes, then it's raw. + // (SNS JSON message can have attributes, but they are encoded in + // the JSON instead of being at the top level). + raw = raw || len(rawAttrs) > 0 + if raw { + // For raw messages, the attributes are at the top level + // and we leave bodyStr alone. + return bodyStr, rawAttrs + } + + // It might be SNS JSON; try to parse the raw body as such. + // https://aws.amazon.com/sns/faqs/#Raw_message_delivery + // If it parses as JSON and has a TopicArn field, assume it's SNS JSON. + var bodyJSON struct { + TopicArn string + Message string + MessageAttributes map[string]struct{ Value string } + } + if err := json.Unmarshal([]byte(bodyStr), &bodyJSON); err == nil && bodyJSON.TopicArn != "" { + // It looks like SNS JSON. Get attributes from the decoded struct, + // and update the body to be the JSON Message field. + for k, v := range bodyJSON.MessageAttributes { + rawAttrs[k] = v.Value + } + return bodyJSON.Message, rawAttrs + } + // It doesn't look like SNS JSON, either because it + // isn't JSON or because the JSON doesn't have a TopicArn + // field. Treat it as raw. + // + // As above in the other "raw" case, we leave bodyStr + // alone. There can't be any top-level attributes (because + // then we would have known it was raw earlier). + return bodyStr, rawAttrs +} + +// SendAcks implements driver.Subscription.SendAcks. +func (s *subscription) SendAcks(ctx context.Context, ids []driver.AckID) error { + req := &sqs.DeleteMessageBatchInput{QueueUrl: aws.String(s.qURL)} + for _, id := range ids { + req.Entries = append(req.Entries, sqstypes.DeleteMessageBatchRequestEntry{ + Id: aws.String(strconv.Itoa(len(req.Entries))), + ReceiptHandle: id.(*string), + }) + } + resp, err := s.client.DeleteMessageBatch(ctx, req) + if err != nil { + return err + } + // Note: DeleteMessageBatch doesn't return failures when you try + // to Delete an id that isn't found. + if numFailed := len(resp.Failed); numFailed > 0 { + first := resp.Failed[0] + return fmt.Errorf("sqs.DeleteMessageBatch failed for %d message(s): %s, %s", numFailed, aws.ToString(first.Code), aws.ToString(first.Message)) + } + return nil +} + +// CanNack implements driver.CanNack. +func (s *subscription) CanNack() bool { return true } + +// SendNacks implements driver.Subscription.SendNacks. +func (s *subscription) SendNacks(ctx context.Context, ids []driver.AckID) error { + if s.opts.NackLazy { + return nil + } + req := &sqs.ChangeMessageVisibilityBatchInput{QueueUrl: aws.String(s.qURL)} + for _, id := range ids { + req.Entries = append(req.Entries, sqstypes.ChangeMessageVisibilityBatchRequestEntry{ + Id: aws.String(strconv.Itoa(len(req.Entries))), + ReceiptHandle: id.(*string), + VisibilityTimeout: 1, + }) + } + resp, err := s.client.ChangeMessageVisibilityBatch(ctx, req) + if err != nil { + return err + } + // Note: ChangeMessageVisibilityBatch returns failures when you try to + // modify an id that isn't found; drop those. + var firstFail sqstypes.BatchResultErrorEntry + numFailed := 0 + for _, fail := range resp.Failed { + if aws.ToString(fail.Code) == (&sqstypes.ReceiptHandleIsInvalid{}).ErrorCode() { + continue + } + if numFailed == 0 { + firstFail = fail + } + numFailed++ + } + if numFailed > 0 { + return fmt.Errorf("sqs.ChangeMessageVisibilityBatch failed for %d message(s): %s, %s", numFailed, aws.ToString(firstFail.Code), aws.ToString(firstFail.Message)) + } + return nil +} + +// IsRetryable implements driver.Subscription.IsRetryable. +func (*subscription) IsRetryable(error) bool { + // The client handles retries. + return false +} + +// As implements driver.Subscription.As. +func (s *subscription) As(i any) bool { + c, ok := i.(**sqs.Client) + if !ok { + return false + } + *c = s.client + return true +} + +// ErrorAs implements driver.Subscription.ErrorAs. +func (s *subscription) ErrorAs(err error, i any) bool { + return errorAs(err, i) +} + +// ErrorCode implements driver.Subscription.ErrorCode. +func (s *subscription) ErrorCode(err error) gcerrors.ErrorCode { + return errorCode(err) +} + +func errorAs(err error, i any) bool { + return errors.As(err, i) +} + +// Close implements driver.Subscription.Close. +func (*subscription) Close() error { return nil } diff --git a/go-cloud/pubsub/awssnssqs/awssnssqs_test.go b/go-cloud/pubsub/awssnssqs/awssnssqs_test.go new file mode 100644 index 000000000..d68d88d1d --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/awssnssqs_test.go @@ -0,0 +1,683 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awssnssqs + +import ( + "context" + "errors" + "fmt" + "net/http" + "strings" + "sync/atomic" + "testing" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/sns" + snstypes "github.com/aws/aws-sdk-go-v2/service/sns/types" + "github.com/aws/aws-sdk-go-v2/service/sqs" + sqstypes "github.com/aws/aws-sdk-go-v2/service/sqs/types" + "github.com/aws/smithy-go" + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/drivertest" +) + +const ( + region = "us-east-2" + accountNumber = "456752665576" +) + +// We run conformance tests against multiple kinds of topics; this enum +// represents which one we're doing. +type topicKind string + +const ( + topicKindSNS = topicKind("SNS") // send through an SNS topic + topicKindSNSRaw = topicKind("SNSRaw") // send through an SNS topic using RawMessageDelivery=true + topicKindSQS = topicKind("SQS") // send directly to an SQS queue +) + +type harness struct { + snsClient *sns.Client + sqsClient *sqs.Client + topicKind topicKind + rt http.RoundTripper + closer func() + numTopics uint32 + numSubs uint32 + useFIFO bool + topicAttributes map[string]string +} + +type harnessOption func(h *harness) + +func newHarness(ctx context.Context, t *testing.T, topicKind topicKind) (drivertest.Harness, error) { + t.Helper() + + cfg, rt, closer, _ := setup.NewAWSv2Config(context.Background(), t, region, false) + return &harness{snsClient: sns.NewFromConfig(cfg), sqsClient: sqs.NewFromConfig(cfg), rt: rt, topicKind: topicKind, closer: closer}, nil +} + +func (h *harness) CreateTopic(ctx context.Context, testName string) (dt driver.Topic, cleanup func(), err error) { + topicName := sanitize(fmt.Sprintf("%s-top-%d", testName, atomic.AddUint32(&h.numTopics, 1))) + if h.useFIFO { + topicName += ".fifo" + } + return createTopic(ctx, topicName, h.snsClient, h.sqsClient, h.topicKind, h.topicAttributes) +} + +func convertStringToPtrMap(m map[string]string) map[string]*string { + if m == nil { + return nil + } + out := make(map[string]*string, len(m)) + for k, v := range m { + out[k] = aws.String(v) + } + return out +} + +func createTopic(ctx context.Context, topicName string, snsClient *sns.Client, sqsClient *sqs.Client, topicKind topicKind, attributes map[string]string) (dt driver.Topic, cleanup func(), err error) { + switch topicKind { + case topicKindSNS, topicKindSNSRaw: + // Create an SNS topic. + input := &sns.CreateTopicInput{Name: aws.String(topicName), Attributes: attributes} + out, err := snsClient.CreateTopic(ctx, input) + if err != nil { + return nil, nil, fmt.Errorf("creating SNS topic %q: %v", topicName, err) + } + dt = openSNSTopic(ctx, snsClient, *out.TopicArn, &TopicOptions{}) + cleanup = func() { + snsClient.DeleteTopic(ctx, &sns.DeleteTopicInput{TopicArn: out.TopicArn}) + } + return dt, cleanup, nil + case topicKindSQS: + // Create an SQS queue. + qURL, _, err := createSQSQueue(ctx, sqsClient, topicName, attributes) + if err != nil { + return nil, nil, fmt.Errorf("creating SQS queue %q: %v", topicName, err) + } + dt = openSQSTopic(ctx, sqsClient, qURL, &TopicOptions{}) + cleanup = func() { + sqsClient.DeleteQueue(ctx, &sqs.DeleteQueueInput{QueueUrl: aws.String(qURL)}) + } + return dt, cleanup, nil + default: + panic("unreachable") + } +} + +func (h *harness) MakeNonexistentTopic(ctx context.Context) (driver.Topic, error) { + switch h.topicKind { + case topicKindSNS, topicKindSNSRaw: + const fakeTopicARN = "arn:aws:sns:" + region + ":" + accountNumber + ":nonexistenttopic" + return openSNSTopic(ctx, h.snsClient, fakeTopicARN, &TopicOptions{}), nil + case topicKindSQS: + const fakeQueueURL = "https://" + region + ".amazonaws.com/" + accountNumber + "/nonexistent-queue" + return openSQSTopic(ctx, h.sqsClient, fakeQueueURL, &TopicOptions{}), nil + default: + panic("unreachable") + } +} + +func (h *harness) CreateSubscription(ctx context.Context, dt driver.Topic, testName string) (ds driver.Subscription, cleanup func(), err error) { + subName := sanitize(fmt.Sprintf("%s-sub-%d", testName, atomic.AddUint32(&h.numSubs, 1))) + return createSubscription(ctx, dt, subName, h.snsClient, h.sqsClient, h.topicKind) +} + +func createSubscription(ctx context.Context, dt driver.Topic, subName string, snsClient *sns.Client, sqsClient *sqs.Client, topicKind topicKind) (ds driver.Subscription, cleanup func(), err error) { + switch topicKind { + case topicKindSNS, topicKindSNSRaw: + // Create an SQS queue, and subscribe it to the SNS topic. + qURL, qARN, err := createSQSQueue(ctx, sqsClient, subName, nil) + if err != nil { + return nil, nil, fmt.Errorf("creating SQS queue %q: %v", subName, err) + } + ds = openSubscription(ctx, sqsClient, qURL, &SubscriptionOptions{}) + + snsTopicARN := dt.(*snsTopic).arn + var cleanup func() + req := &sns.SubscribeInput{ + TopicArn: aws.String(snsTopicARN), + Endpoint: aws.String(qARN), + Protocol: aws.String("sqs"), + } + // Enable RawMessageDelivery on the subscription if needed. + if topicKind == topicKindSNSRaw { + req.Attributes = map[string]string{"RawMessageDelivery": "true"} + } + out, err := snsClient.Subscribe(ctx, req) + if err != nil { + return nil, nil, fmt.Errorf("subscribing: %v", err) + } + cleanup = func() { + snsClient.Unsubscribe(ctx, &sns.UnsubscribeInput{SubscriptionArn: out.SubscriptionArn}) + sqsClient.DeleteQueue(ctx, &sqs.DeleteQueueInput{QueueUrl: aws.String(qURL)}) + } + return ds, cleanup, nil + case topicKindSQS: + // The SQS queue already exists; we created it for the topic. Re-use it + // for the subscription. + qURL := dt.(*sqsTopic).qURL + return openSubscription(ctx, sqsClient, qURL, &SubscriptionOptions{}), func() {}, nil + default: + panic("unreachable") + } +} + +func createSQSQueue(ctx context.Context, sqsClient *sqs.Client, topicName string, attributes map[string]string) (string, string, error) { + out, err := sqsClient.CreateQueue(ctx, &sqs.CreateQueueInput{QueueName: aws.String(topicName), Attributes: attributes}) + if err != nil { + return "", "", fmt.Errorf("creating SQS queue %q: %v", topicName, err) + } + qURL := aws.ToString(out.QueueUrl) + + // Get the ARN. + out2, err := sqsClient.GetQueueAttributes(ctx, &sqs.GetQueueAttributesInput{ + QueueUrl: aws.String(qURL), + AttributeNames: []sqstypes.QueueAttributeName{"QueueArn"}, + }) + if err != nil { + return "", "", fmt.Errorf("getting queue ARN for %s: %v", qURL, err) + } + qARN := out2.Attributes["QueueArn"] + + queuePolicy := `{ + "Version": "2012-10-17", + "Id": "AllowQueue", + "Statement": [ + { + "Sid": "MySQSPolicy001", + "Effect": "Allow", + "Principal": { + "AWS": "*" + }, + "Action": "sqs:SendMessage", + "Resource": "` + qARN + `" + } + ] + }` + if _, err := sqsClient.SetQueueAttributes(ctx, &sqs.SetQueueAttributesInput{ + Attributes: map[string]string{"Policy": queuePolicy}, + QueueUrl: aws.String(qURL), + }); err != nil { + return "", "", fmt.Errorf("setting policy: %v", err) + } + return qURL, qARN, nil +} + +func (h *harness) MakeNonexistentSubscription(ctx context.Context) (driver.Subscription, func(), error) { + const fakeSubscriptionQueueURL = "https://" + region + ".amazonaws.com/" + accountNumber + "/nonexistent-subscription" + return openSubscription(ctx, h.sqsClient, fakeSubscriptionQueueURL, &SubscriptionOptions{}), func() {}, nil +} + +func (h *harness) Close() { + h.closer() +} + +func (h *harness) MaxBatchSizes() (int, int) { + if h.topicKind == topicKindSQS { + return sendBatcherOptsSQS.MaxBatchSize, ackBatcherOpts.MaxBatchSize + } + return sendBatcherOptsSNS.MaxBatchSize, ackBatcherOpts.MaxBatchSize +} + +func (h *harness) SupportsMultipleSubscriptions() bool { + // If we're publishing to an SQS topic, we're reading from the same topic, + // so there's no way to get multiple subscriptions. + return h.topicKind != topicKindSQS +} + +func TestConformanceSNSTopic(t *testing.T) { + asTests := []drivertest.AsTest{awsAsTest{topicKind: topicKindSNS}} + newSNSHarness := func(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return newHarness(ctx, t, topicKindSNS) + } + drivertest.RunConformanceTests(t, newSNSHarness, asTests) +} + +func TestConformanceSNSTopicRaw(t *testing.T) { + asTests := []drivertest.AsTest{awsAsTest{topicKind: topicKindSNSRaw}} + newSNSHarness := func(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return newHarness(ctx, t, topicKindSNSRaw) + } + drivertest.RunConformanceTests(t, newSNSHarness, asTests) +} + +func TestConformanceSQSTopic(t *testing.T) { + asTests := []drivertest.AsTest{awsAsTest{topicKind: topicKindSQS}} + newSQSHarness := func(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return newHarness(ctx, t, topicKindSQS) + } + drivertest.RunConformanceTests(t, newSQSHarness, asTests) +} + +type awsAsTest struct { + topicKind topicKind +} + +func (awsAsTest) Name() string { + return "aws test" +} + +func (t awsAsTest) TopicCheck(topic *pubsub.Topic) error { + switch t.topicKind { + case topicKindSNS, topicKindSNSRaw: + var s *sns.Client + if !topic.As(&s) { + return fmt.Errorf("cast failed for %T", s) + } + case topicKindSQS: + var s *sqs.Client + if !topic.As(&s) { + return fmt.Errorf("cast failed for %T", s) + } + default: + panic("unreachable") + } + return nil +} + +func (t awsAsTest) SubscriptionCheck(sub *pubsub.Subscription) error { + var s *sqs.Client + if !sub.As(&s) { + return fmt.Errorf("cast failed for %T", s) + } + return nil +} + +func (t awsAsTest) TopicErrorCheck(topic *pubsub.Topic, err error) error { + var e smithy.APIError + if !topic.ErrorAs(err, &e) { + return errors.New("Topic.ErrorAs failed") + } + switch t.topicKind { + case topicKindSNS, topicKindSNSRaw: + if got, want := e.ErrorCode(), (&snstypes.NotFoundException{}).ErrorCode(); want != got { + return fmt.Errorf("got %q, want %q", got, want) + } + case topicKindSQS: + if got, want := e.ErrorCode(), "AWS.SimpleQueueService.NonExistentQueue"; got != want { + return fmt.Errorf("got %q, want %q", got, want) + } + default: + panic("unreachable") + } + return nil +} + +func (t awsAsTest) SubscriptionErrorCheck(s *pubsub.Subscription, err error) error { + var e smithy.APIError + if !s.ErrorAs(err, &e) { + return errors.New("Subscription.ErrorAs failed") + } + if got, want := e.ErrorCode(), "AWS.SimpleQueueService.NonExistentQueue"; got != want { + return fmt.Errorf("got %q, want %q", got, want) + } + return nil +} + +func (t awsAsTest) MessageCheck(m *pubsub.Message) error { + var sm sqstypes.Message + if !m.As(&sm) { + return fmt.Errorf("cast failed for %T", &sm) + } + return nil +} + +func (t awsAsTest) BeforeSend(as func(any) bool) error { + switch t.topicKind { + case topicKindSNS, topicKindSNSRaw: + var pub *sns.PublishInput + if !as(&pub) { + return fmt.Errorf("cast failed for %T", &pub) + } + var entry *snstypes.PublishBatchRequestEntry + if !as(&entry) { + return fmt.Errorf("cast failed for %T", &entry) + } + case topicKindSQS: + var entry *sqstypes.SendMessageBatchRequestEntry + if !as(&entry) { + return fmt.Errorf("cast failed for %T", &entry) + } + default: + panic("unreachable") + } + return nil +} + +func (t awsAsTest) AfterSend(as func(any) bool) error { + switch t.topicKind { + case topicKindSNS, topicKindSNSRaw: + var pub *sns.PublishOutput + if !as(&pub) { + return fmt.Errorf("cast failed for %T", &pub) + } + var entry snstypes.PublishBatchResultEntry + if !as(&entry) { + return fmt.Errorf("cast failed for %T", &entry) + } + case topicKindSQS: + var entry sqstypes.SendMessageBatchResultEntry + if !as(&entry) { + return fmt.Errorf("cast failed for %T", &entry) + } + default: + panic("unreachable") + } + return nil +} + +func sanitize(s string) string { + // AWS doesn't like names that are too long; trim some not-so-useful stuff. + const maxNameLen = 80 + s = strings.Replace(s, "TestConformance", "", 1) + s = strings.Replace(s, "/Test", "", 1) + s = strings.Replace(s, "/", "_", -1) + if len(s) > maxNameLen { + // Drop prefix, not suffix, because suffix includes something to make + // entities unique within a test. + s = s[len(s)-maxNameLen:] + } + return s +} + +func BenchmarkSNSSQS(b *testing.B) { + benchmark(b, topicKindSNS) +} + +func BenchmarkSQS(b *testing.B) { + benchmark(b, topicKindSQS) +} + +func benchmark(b *testing.B, topicKind topicKind) { + b.Helper() + + ctx := context.Background() + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + b.Fatal(err) + } + topicName := fmt.Sprintf("%s-topic", b.Name()) + snsClient := sns.NewFromConfig(cfg) + sqsClient := sqs.NewFromConfig(cfg) + dt, cleanup1, err := createTopic(ctx, topicName, snsClient, sqsClient, topicKind, nil) + if err != nil { + b.Fatal(err) + } + defer cleanup1() + sendBatcherOpts := sendBatcherOptsSNS + if topicKind == topicKindSQS { + sendBatcherOpts = sendBatcherOptsSQS + } + topic := pubsub.NewTopic(dt, sendBatcherOpts) + defer topic.Shutdown(ctx) + subName := fmt.Sprintf("%s-subscription", b.Name()) + ds, cleanup2, err := createSubscription(ctx, dt, subName, snsClient, sqsClient, topicKind) + if err != nil { + b.Fatal(err) + } + defer cleanup2() + sub := pubsub.NewSubscription(ds, recvBatcherOpts, ackBatcherOpts) + defer sub.Shutdown(ctx) + drivertest.RunBenchmarks(b, topic, sub) +} + +func TestOpenTopicFromURL(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // SNS... + + // OK. + {"awssns:///arn:aws:service:region:accountid:resourceType/resourcePath", false}, + // OK, setting region. + {"awssns:///arn:aws:service:region:accountid:resourceType/resourcePath?region=us-east-2", false}, + // Invalid parameter. + {"awssns:///arn:aws:service:region:accountid:resourceType/resourcePath?param=value", true}, + + // SQS... + // OK. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue", false}, + // OK, setting region. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue?region=us-east-2", false}, + // Invalid parameter. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + topic, err := pubsub.OpenTopic(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if topic != nil { + topic.Shutdown(ctx) + } + } +} + +func TestOpenSubscriptionFromURL(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue", false}, + // OK, setting region. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue?region=us-east-2", false}, + // OK, setting raw. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue?raw=true", false}, + // OK, setting raw. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue?raw=1", false}, + // Invalid raw. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue?raw=foo", true}, + // OK, setting nacklazy. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue?nacklazy=1", false}, + // Invalid nacklazy. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue?nacklazy=foo", true}, + // OK, setting waittime. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue?waittime=5s", false}, + // Invalid waittime. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue?waittime=foo", true}, + // Invalid parameter. + {"awssqs://sqs.us-east-2.amazonaws.com/99999/my-queue?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + sub, err := pubsub.OpenSubscription(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if sub != nil { + sub.Shutdown(ctx) + } + } +} + +func TestFIFO(t *testing.T) { + for _, tt := range []struct { + name string + kind topicKind + }{ + { + name: "TestSNSTopic", + kind: topicKindSNS, + }, + // This test is flaky because it sets 2 attributes for CreateTopic, + // and the HTTP record/replay randomly re-sorts them. I'm not sure how + // to fix that, so disabling the test. It's also unclear why only + // this test appears affected, maybe the AWS code iterates over the + // map here and doesn't in other cases? + /* + { + name: "TestSQSTopic", + kind: topicKindSQS, + }, + */ + } { + t.Run(tt.name, func(t *testing.T) { + testFIFOTopic(t, tt.kind) + }) + } +} + +// testFIFOTopic tests FIFO topics. +// +// FIFO topics require a message group ID to be set on the message. +// +// The content-based deduplication attribute must be set to true on the topic. +// - If set to true, the message deduplication ID is generated using the message body (sha256 hash). +// - If not set, then the DeduplicationID must be set on the message. +// +// For more information see: +// - https://pkg.go.dev/github.com/aws/aws-sdk-go/service/sns#CreateTopicInput.Attributes +// - https://pkg.go.dev/github.com/aws/aws-sdk-go/service/sqs#CreateQueueInput.Attributes +func testFIFOTopic(t *testing.T, kind topicKind) { + t.Helper() + type harnessArgs struct { + attributes map[string]string + } + + const ( + attributeKeyContentBasedDeduplication = "ContentBasedDeduplication" + attributeKeyFifoTopic = "FifoTopic" + attributeKeyFifoQueue = "FifoQueue" + ) + + tests := []struct { + name string + harness harnessArgs + message *pubsub.Message + wantErr bool + }{ + { + name: "TestSendReceiveValid", + harness: harnessArgs{ + attributes: map[string]string{ + attributeKeyContentBasedDeduplication: "true", + }, + }, + message: &pubsub.Message{ + Body: []byte("hello world"), + Metadata: map[string]string{ + MetadataKeyMessageGroupID: "1", + }, + }, + wantErr: false, + }, + { + name: "TestSendReceiveInvalidNoMessageGroupID", + harness: harnessArgs{ + attributes: map[string]string{ + attributeKeyContentBasedDeduplication: "true", + }, + }, + message: &pubsub.Message{ + Body: []byte("hello world"), + Metadata: map[string]string{ + MetadataKeyDeduplicationID: "1", + }, + }, + wantErr: true, + }, + { + name: "TestSendReceiveInvalidNoDeduplicationID", + // We dont set the ContentBasedDeduplication attribute to trigger the error. + harness: harnessArgs{}, + message: &pubsub.Message{ + Body: []byte("hello world"), + Metadata: map[string]string{}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create the harness. + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + h, err := newHarness(ctx, t, kind) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + // Set the FIFO attributes. + attributes := make(map[string]string) + for k, v := range tt.harness.attributes { + attributes[k] = v + } + switch kind { + case topicKindSNS: + attributes[attributeKeyFifoTopic] = "true" + case topicKindSQS: + attributes[attributeKeyFifoQueue] = "true" + } + h.(*harness).topicAttributes = attributes + h.(*harness).useFIFO = true + + // Create the topic and subscription. + dt, cleanup, err := h.CreateTopic(ctx, t.Name()) + if err != nil { + t.Errorf("harness.CreateTopic() error = %v", err) + return + } + defer cleanup() + topic := pubsub.NewTopic(dt, sendBatcherOptsSNS) + defer topic.Shutdown(ctx) + ds, cleanup, err := h.CreateSubscription(ctx, dt, t.Name()) + if err != nil { + t.Errorf("harness.CreateSubscription() error = %v", err) + return + } + defer cleanup() + sub := pubsub.NewSubscription(ds, recvBatcherOpts, ackBatcherOpts) + defer sub.Shutdown(ctx) + + // Send and receive the message. + err = topic.Send(ctx, tt.message) + if (err != nil) != tt.wantErr { + t.Errorf("Topic.Send() error = %v, wantErr %v", err, tt.wantErr) + return + } + if tt.wantErr { + return + } + m, err := sub.Receive(ctx) + if err != nil { + t.Errorf("Subscription.Receive() error = %v", err) + return + } + if diff := cmp.Diff(tt.message.Body, m.Body); diff != "" { + t.Errorf("Received message body: -got, +want: %s", diff) + } + m.Ack() + }) + } +} diff --git a/go-cloud/pubsub/awssnssqs/example_test.go b/go-cloud/pubsub/awssnssqs/example_test.go new file mode 100644 index 000000000..e92ae65a4 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/example_test.go @@ -0,0 +1,133 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awssnssqs_test + +import ( + "context" + "log" + + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/sns" + "github.com/aws/aws-sdk-go-v2/service/sqs" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/awssnssqs" +) + +func ExampleOpenSNSTopic() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Establish a AWS V2 Config. + // See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info. + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + log.Fatal(err) + } + + // Create a *pubsub.Topic. + const topicARN = "arn:aws:sns:us-east-2:123456789012:mytopic" + client := sns.NewFromConfig(cfg) + topic := awssnssqs.OpenSNSTopic(ctx, client, topicARN, nil) + defer topic.Shutdown(ctx) +} + +func ExampleOpenSQSTopic() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Establish a AWS V2 Config. + // See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info. + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + log.Fatal(err) + } + + // Create a *pubsub.Topic. + const queueURL = "https://sqs.us-east-2.amazonaws.com/123456789012/myqueue" + client := sqs.NewFromConfig(cfg) + topic := awssnssqs.OpenSQSTopic(ctx, client, queueURL, nil) + defer topic.Shutdown(ctx) +} + +func Example_openSNSTopicFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/awssnssqs" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + const topicARN = "arn:aws:sns:us-east-2:123456789012:mytopic" + // Note the 3 slashes; ARNs have multiple colons and therefore aren't valid + // as hostnames in the URL. + topic, err := pubsub.OpenTopic(ctx, "awssns:///"+topicARN+"?region=us-east-2") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func Example_openSQSTopicFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/awssnssqs" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // https://docs.aws.amazon.com/sdk-for-net/v2/developer-guide/QueueURL.html + const queueURL = "sqs.us-east-2.amazonaws.com/123456789012/myqueue" + topic, err := pubsub.OpenTopic(ctx, "awssqs://"+queueURL+"?region=us-east-2") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func ExampleOpenSubscription() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Establish a AWS V2 Config. + // See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info. + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + log.Fatal(err) + } + + // Construct a *pubsub.Subscription. + // https://docs.aws.amazon.com/sdk-for-net/v2/developer-guide/QueueURL.html + const queueURL = "https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue" + client := sqs.NewFromConfig(cfg) + subscription := awssnssqs.OpenSubscription(ctx, client, queueURL, nil) + defer subscription.Shutdown(ctx) +} + +func Example_openSubscriptionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/awssnssqs" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenSubscription creates a *pubsub.Subscription from a URL. + // This URL will open the subscription with the URL + // "https://sqs.us-east-2.amazonaws.com/123456789012/myqueue". + subscription, err := pubsub.OpenSubscription(ctx, + "awssqs://sqs.us-east-2.amazonaws.com/123456789012/"+ + "myqueue?region=us-east-2") + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestAs/aws_test.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestAs/aws_test.replay new file mode 100644 index 000000000..a8f34721c --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestAs/aws_test.replay @@ -0,0 +1,768 @@ +{ + "Initial": "AQAAAA7gDLWPKFoYVgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "85b7d0b19a399857", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNBc19hd3NfdGVzdC10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "332" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:19 GMT" + ], + "X-Amzn-Requestid": [ + "a0a84223-b90a-572f-b33c-22d779c5b100" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQXNfYXdzX3Rlc3QtdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmEwYTg0MjIzLWI5MGEtNTcyZi1iMzNjLTIyZDc3OWM1YjEwMDwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "dcdddd50fdd7bd00", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "41" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "89" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:20 GMT" + ], + "X-Amzn-Requestid": [ + "8f0e2720-372e-5f35-8806-47d4f7fe6961" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0FzX2F3c190ZXN0LXN1Yi0xIn0=" + } + }, + { + "ID": "ea0299cb4f69d6cd", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "119" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "90" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:20 GMT" + ], + "X-Amzn-Requestid": [ + "2f34d250-04de-5798-9ce7-b2a4c40e11cc" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0FzX2F3c190ZXN0LXN1Yi0xIn19" + } + }, + { + "ID": "c4e6aa1370e6470a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "464" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQXNfYXdzX3Rlc3Qtc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:20 GMT" + ], + "X-Amzn-Requestid": [ + "f6bff3ca-2a9d-5d3d-b830-933eea4d2b69" + ] + }, + "Body": "" + } + }, + { + "ID": "d8dfe23dbee89d28", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "208" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0FzX2F3c190ZXN0LXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0FzX2F3c190ZXN0LXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "375" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:20 GMT" + ], + "X-Amzn-Requestid": [ + "84990eac-745d-54c7-afba-6e58b48dd2e8" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQXNfYXdzX3Rlc3QtdG9wLTE6NDNhYmE0OTQtZjE4Ni00ZGY4LThlYmEtMGZkOWJhNmM5MzFlPC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjg0OTkwZWFjLTc0NWQtNTRjNy1hZmJhLTZlNThiNDhkZDJlODwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "230125c18c27ecd8", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "205" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9eCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0FzX2F3c190ZXN0LXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:20 GMT" + ], + "X-Amzn-Requestid": [ + "666132d3-914e-567c-a0ac-5227519eb053" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjA2MDgyNTNiLWNlZDMtNTVlYi1iYzExLTQ1Y2YwZTAzYjNjNDwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjY2NjEzMmQzLTkxNGUtNTY3Yy1hMGFjLTUyMjc1MTllYjA1MzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "8fa1a37171123b56", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1720" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:20 GMT" + ], + "X-Amzn-Requestid": [ + "9f4a3c29-874d-5ebc-af5f-5cdd479d18e8" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY0MDc0OCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjQwNjgzIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiMDYwODI1M2ItY2VkMy01NWViLWJjMTEtNDVjZjBlMDNiM2M0XCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0FzX2F3c190ZXN0LXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJ4XCIsXG4gIFwiVGltZXN0YW1wXCIgOiBcIjIwMjUtMDctMThUMjE6Mzc6MjAuNjUwWlwiLFxuICBcIlNpZ25hdHVyZVZlcnNpb25cIiA6IFwiMVwiLFxuICBcIlNpZ25hdHVyZVwiIDogXCJoY0c0M3M1TGZmZUhlUE50SmgzbkcwMGkwRzlCTWliQTQvZ3JCZm9ySjVnOFc1a3BUcnlwdUlRL3Nud1liaWxlWTdyUGlEaDFmU1NjT2taMTM0RlhwTjgzTlpraXBscmlkSGZ0TkxYYlAxRVhVYTlPVXpycjhEb2tTSnFXY3R1QlR3UjRrWU9rblNNdklmNXVJWUhLWVg0VW5MbTlNYXNqcVVTd0tFNWZwa3pwdS9zWktyMzJONThnTHc2QTg3YTNKbE1HREpsL3FRZTZud2FKWEY4Z2k0SHNBSFlOR0NtUVIweEM1Vnl4OHlOeFpPbkpKWVJCK2xMVm1HZitxTC9PWGdCQko5YXkzWkRXd0FpNmVHMDE5b0JTTVFzOUV0TVhKNEgrY1dVVThjTHRVSWZsZ1JqVkhreTdySWNIdkxLbzBwQytYdzhZSHNaeHlDUVNsYmlyVXc9PVwiLFxuICBcIlNpZ25pbmdDZXJ0VVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL1NpbXBsZU5vdGlmaWNhdGlvblNlcnZpY2UtOWM2NDY1ZmE3ZjQ4ZjVjYWNkMjMwMTQ2MzFlYzExMzYucGVtXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0FzX2F3c190ZXN0LXRvcC0xOjQzYWJhNDk0LWYxODYtNGRmOC04ZWJhLTBmZDliYTZjOTMxZVwiXG59IiwiTUQ1T2ZCb2R5IjoiZTQwOTkwMGNkNjM2ZDY5NTYyYmIzZmYwYTNmZjg0NzEiLCJNZXNzYWdlSWQiOiIxOTk4MDQxMy0wYzY0LTQ5NjgtODY1Yi1mZTU0YzhjNjIzYWQiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQklYWkJQRFdFK0gxSStDN3k0K0FyWmh6MzhiMm9XWnN6MWc2YUl2ZjFVdmZBRjRkNXJsNE9HVWQ0Z0I0RU5qMVR2VWF6UmY4U2VGNEFPR1hsZVpZUkFKQlJyOG9EYmVZWWNmRVNEUThhTVlhM3ZSUEFNVTNCN2x4dHNmbFhOVDdha1loUE9ZTExaaE8wbms0L2MvTU5wT0NXUG5ZaGNWbGttczJ1cGVPL0szNnVBaHYvM3ZQYTREdXR3Q1ovWHZvMEpvQ0ZxbzdpcW91Z1l2UzdabTIraFJUeEhoNlp3M1dQOXZhYlZyQXdyRkRoR21icHpPRlZCY3ZyUmNGU2xZREVPdld0YVlKS2wyOWFXZlAxaVFKTXNUZzRMRDdvV0lSaEsvcFVwMnp3V1VuZW52Q0JoMmJVc3pJekptOExEL3FzeC9pMGdaMXprekZPN2M4azhJRlJBZ1B3RDNTZWR2M3ZSSUM3VlZwOFRnTFh5L3pMVllUUVlBWHlUb2ZZTG9BdmdBTnpXVE9hOURoOW12VkdnTDY3Z2t3bjlTbUdVcnppelp4dmp0VDNxRGM9In1dfQ==" + } + }, + { + "ID": "e2192a21c588e74c", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "195" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9JlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQW5vbmV4aXN0ZW50dG9waWMmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "259" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:20 GMT" + ], + "X-Amzn-Requestid": [ + "6d065021-8a9f-5208-b42b-30d54a4f6427" + ] + }, + "Body": "PEVycm9yUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxFcnJvcj4KICAgIDxUeXBlPlNlbmRlcjwvVHlwZT4KICAgIDxDb2RlPk5vdEZvdW5kPC9Db2RlPgogICAgPE1lc3NhZ2U+VG9waWMgZG9lcyBub3QgZXhpc3Q8L01lc3NhZ2U+CiAgPC9FcnJvcj4KICA8UmVxdWVzdElkPjZkMDY1MDIxLThhOWYtNTIwOC1iNDJiLTMwZDU0YTRmNjQyNzwvUmVxdWVzdElkPgo8L0Vycm9yUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "c9f72870aa5f8849", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "563" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQklYWkJQRFdFK0gxSStDN3k0K0FyWmh6MzhiMm9XWnN6MWc2YUl2ZjFVdmZBRjRkNXJsNE9HVWQ0Z0I0RU5qMVR2VWF6UmY4U2VGNEFPR1hsZVpZUkFKQlJyOG9EYmVZWWNmRVNEUThhTVlhM3ZSUEFNVTNCN2x4dHNmbFhOVDdha1loUE9ZTExaaE8wbms0L2MvTU5wT0NXUG5ZaGNWbGttczJ1cGVPL0szNnVBaHYvM3ZQYTREdXR3Q1ovWHZvMEpvQ0ZxbzdpcW91Z1l2UzdabTIraFJUeEhoNlp3M1dQOXZhYlZyQXdyRkRoR21icHpPRlZCY3ZyUmNGU2xZREVPdld0YVlKS2wyOWFXZlAxaVFKTXNUZzRMRDdvV0lSaEsvcFVwMnp3V1VuZW52Q0JoMmJVc3pJekptOExEL3FzeC9pMGdaMXprekZPN2M4azhJRlJBZ1B3RDNTZWR2M3ZSSUM3VlZwOFRnTFh5L3pMVllUUVlBWHlUb2ZZTG9BdmdBTnpXVE9hOURoOW12VkdnTDY3Z2t3bjlTbUdVcnppelp4dmp0VDNxRGM9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:20 GMT" + ], + "X-Amzn-Requestid": [ + "51bc8bb5-2e15-5ec4-9f5f-eb41eec5b890" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "c01febad5faeba88", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "165" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vdXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L25vbmV4aXN0ZW50LXN1YnNjcmlwdGlvbiJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:20 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "653a8469-8bd1-56f1-8427-e49d4b0130a5" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + }, + { + "ID": "ce42877d6d0052d0", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0FzX2F3c190ZXN0LXRvcC0xJTNBNDNhYmE0OTQtZjE4Ni00ZGY4LThlYmEtMGZkOWJhNmM5MzFlJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:21 GMT" + ], + "X-Amzn-Requestid": [ + "d8c0f9a0-0217-583d-994a-9954c2c7ae12" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5kOGMwZjlhMC0wMjE3LTU4M2QtOTk0YS05OTU0YzJjN2FlMTI8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "d8b4e4083d084430", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "89" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:21 GMT" + ], + "X-Amzn-Requestid": [ + "3c301ef1-689a-5c1e-9273-7e05a84b9a4a" + ] + }, + "Body": "" + } + }, + { + "ID": "40b9b7b64d9094cc", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "117" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljQXNfYXdzX3Rlc3QtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:21 GMT" + ], + "X-Amzn-Requestid": [ + "ae22cf73-d9f0-50f0-9a75-af87192146df" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5hZTIyY2Y3My1kOWYwLTUwZjAtOWE3NS1hZjg3MTkyMTQ2ZGY8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..756b6579f --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,768 @@ +{ + "Initial": "AQAAAA7gDLWRD1ThsAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "98b482a69c135cd6", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "99" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNBc192ZXJpZnlfQXNfcmV0dXJuc19mYWxzZV93aGVuX3Bhc3NlZF9uaWwtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "363" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:21 GMT" + ], + "X-Amzn-Requestid": [ + "536ed9a5-51a0-5b5f-80e2-b9519171b836" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD41MzZlZDlhNS01MWEwLTViNWYtODBlMi1iOTUxOTE3MWI4MzY8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "d74f77c26f1fedc4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:21 GMT" + ], + "X-Amzn-Requestid": [ + "7aa2f6c6-0f44-5175-8827-9632cf95240d" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9" + } + }, + { + "ID": "1125761b722868c9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "150" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "121" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:22 GMT" + ], + "X-Amzn-Requestid": [ + "6fb5a16c-f5f6-59b3-bbdb-c1983524accb" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9fQ==" + } + }, + { + "ID": "0f58aaff864e1615", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "526" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXN1Yi0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNBc192ZXJpZnlfQXNfcmV0dXJuc19mYWxzZV93aGVuX3Bhc3NlZF9uaWwtc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:22 GMT" + ], + "X-Amzn-Requestid": [ + "f47c81ef-3280-5aab-987c-e11bf2528fd3" + ] + }, + "Body": "" + } + }, + { + "ID": "4e102a723749a324", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "270" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSZQcm90b2NvbD1zcXMmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBU05TVG9waWNBc192ZXJpZnlfQXNfcmV0dXJuc19mYWxzZV93aGVuX3Bhc3NlZF9uaWwtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "406" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:22 GMT" + ], + "X-Amzn-Requestid": [ + "d60b2d2c-fe95-5639-a8e5-4dd83e47e550" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXRvcC0xOjQ3MDMxMDE0LWEwMzYtNGQ5Mi05NWE1LTJkOWYxNmJjM2U1ZjwvU3Vic2NyaXB0aW9uQXJuPgogIDwvU3Vic2NyaWJlUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5kNjBiMmQyYy1mZTk1LTU2MzktYThlNS00ZGQ4M2U0N2U1NTA8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvU3Vic2NyaWJlUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "7f30355207cb5f0f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "236" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9eCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:22 GMT" + ], + "X-Amzn-Requestid": [ + "153d602a-68fe-5166-b03e-00dea82ca20f" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjljY2Q5ODViLTlkNzctNTYzOC1hMjI0LWY4YWY1ZGE1NDU1MTwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjE1M2Q2MDJhLTY4ZmUtNTE2Ni1iMDNlLTAwZGVhODJjYTIwZjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "8cae5dddf774a356", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "201" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1802" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:22 GMT" + ], + "X-Amzn-Requestid": [ + "d4942838-59bb-5866-b3f2-48cc99693d1e" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY0MjQ1MiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjQyNDIwIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiOWNjZDk4NWItOWQ3Ny01NjM4LWEyMjQtZjhhZjVkYTU0NTUxXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC10b3AtMVwiLFxuICBcIk1lc3NhZ2VcIiA6IFwieFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjIyLjM4OFpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiYk4zMW5zajZpZHBKOXdYNHA1NTlYaWQ0U1hoVkNJZTI4V1FLR0M4TXowSk9yTWkrR3NnaHc2R0ROaGNUU2Q1cDZzRUZORG8wc2JxK1FOQjcxK3FRSStvelcvR0ZUWm1KVHFhQ3NVSWR4MTBIK3VQUW9GQUM1dTdPQTJwL0tVbVd0SnVBalhFUGlLY2E4KytYNTA2MFE5RGFOZVYveU1CYWx0SVQyRG9yUFpDTlRZL1ByYkZLTlpYUUExbU1kWE45N3VpYWFZM29MWFM0WXVtcnpuNjkxcGdac2lxdEZYVE1OWXN2ZW9UWTYvZWhERnBpbVdYL1B2T3E0SjFpc3ZqZ3ViY3JtYU9UY1hYUFhlem9YUHRjWjJ4djJ6dVdGd01VbmVJVW1wcUlCSlRTaHBTTVJVb25DcUdKd0FxWWp5K1ZOcDAyb0VWeWFOUit5U005eDZBMXNBPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNBc192ZXJpZnlfQXNfcmV0dXJuc19mYWxzZV93aGVuX3Bhc3NlZF9uaWwtdG9wLTE6NDcwMzEwMTQtYTAzNi00ZDkyLTk1YTUtMmQ5ZjE2YmMzZTVmXCJcbn0iLCJNRDVPZkJvZHkiOiJkOTZiYTU0MGIyZWQ1N2I4YjlmMTAwZDQ0YTNjNTYyYSIsIk1lc3NhZ2VJZCI6IjMxMjZlNzc4LTJiNDEtNDczYS1iNTQzLTRlYzAxNWRlZmVhZCIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCOGlsVzhMemhHSVo4aWxGL3VSMXFPRElOMGMyMXBUcGUzRlpGYXZlTmc5NU5HampWOFZxUUUzY040RzhPSjdHcDRldGxwVW5QZmpOcHN6RHZCcllhWjR3MjNpTmVURWFORmNLL3Z3U0h2U1RkLys5a1pNOGQzdGNzc1U3d0ZLd3VKZm91VnQ3MDYzMzVxb25VSGJBc09nbEZqZW02VVpFeWcwTzhrS3RvM3FkQ1J5WW1Yc0tyYTdBYUFoSkRHeE1ZVStiTTRTTHRiUkcvZHFSRHBRd3B2MEpyT3IvQzdPblh4UEt0Y0Q0dUoxb2pJVEplVDNRTCtSTHlsWmJyZW9XZCt6TXJvbVhUeEV2NDk3Q0pVSnRhWkZPU0pGOExyQ1NOZmtyQlhpQTNRc2F5R29mbkRVbU50NThLZWdudVhjVHlUZkZjK0IvTStHR2ZCd2orR2RqQXdMSTdRWko1Z1RwR1FFUnNDUkpXQmpmTEdjVndhOWZUTTlOc1F6NWdNRFFwVFNadVhCOTk2Q1RBUzNEeFBEd1d3SFRGelRUelB3UWtEOGRKVi9WclM4VklpanJoa05YWG83Qks1cC91bXAwVCJ9XX0=" + } + }, + { + "ID": "1eb6ca75063fa68c", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "195" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9JlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQW5vbmV4aXN0ZW50dG9waWMmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "259" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:22 GMT" + ], + "X-Amzn-Requestid": [ + "e7d495ac-8987-5a1d-abfb-f55849556974" + ] + }, + "Body": "PEVycm9yUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxFcnJvcj4KICAgIDxUeXBlPlNlbmRlcjwvVHlwZT4KICAgIDxDb2RlPk5vdEZvdW5kPC9Db2RlPgogICAgPE1lc3NhZ2U+VG9waWMgZG9lcyBub3QgZXhpc3Q8L01lc3NhZ2U+CiAgPC9FcnJvcj4KICA8UmVxdWVzdElkPmU3ZDQ5NWFjLTg5ODctNWExZC1hYmZiLWY1NTg0OTU1Njk3NDwvUmVxdWVzdElkPgo8L0Vycm9yUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "9f61fcf604da9c77", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "614" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjhpbFc4THpoR0laOGlsRi91UjFxT0RJTjBjMjFwVHBlM0ZaRmF2ZU5nOTVOR2pqVjhWcVFFM2NONEc4T0o3R3A0ZXRscFVuUGZqTnBzekR2QnJZYVo0dzIzaU5lVEVhTkZjSy92d1NIdlNUZC8rOWtaTThkM3Rjc3NVN3dGS3d1SmZvdVZ0NzA2MzM1cW9uVUhiQXNPZ2xGamVtNlVaRXlnME84a0t0bzNxZENSeVltWHNLcmE3QWFBaEpER3hNWVUrYk00U0x0YlJHL2RxUkRwUXdwdjBKck9yL0M3T25YeFBLdGNENHVKMW9qSVRKZVQzUUwrUkx5bFpicmVvV2Qrek1yb21YVHhFdjQ5N0NKVUp0YVpGT1NKRjhMckNTTmZrckJYaUEzUXNheUdvZm5EVW1OdDU4S2VnbnVYY1R5VGZGYytCL00rR0dmQndqK0dkakF3TEk3UVpKNWdUcEdRRVJzQ1JKV0JqZkxHY1Z3YTlmVE05TnNRejVnTURRcFRTWnVYQjk5NkNUQVMzRHhQRHdXd0hURnpUVHpQd1FrRDhkSlYvVnJTOFZJaWpyaGtOWFhvN0JLNXAvdW1wMFQifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NOU1RvcGljQXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:22 GMT" + ], + "X-Amzn-Requestid": [ + "ba5cfef4-701e-53aa-a1c0-9e00b0cc16d2" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "0ac19277c1689688", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "165" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vdXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L25vbmV4aXN0ZW50LXN1YnNjcmlwdGlvbiJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:22 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "e36aece0-bd9e-5b63-b1d6-8c147d4c6e1b" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + }, + { + "ID": "113752c7798da32d", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "194" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC10b3AtMSUzQTQ3MDMxMDE0LWEwMzYtNGQ5Mi05NWE1LTJkOWYxNmJjM2U1ZiZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:22 GMT" + ], + "X-Amzn-Requestid": [ + "e6fbd309-52fd-529f-a4e2-b3fd922f21f6" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5lNmZiZDMwOS01MmZkLTUyOWYtYTRlMi1iM2ZkOTIyZjIxZjY8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "f27a683faa95d85e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "120" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:22 GMT" + ], + "X-Amzn-Requestid": [ + "4c7beddf-b52a-5eb3-8431-8d2b75f8cbcb" + ] + }, + "Body": "" + } + }, + { + "ID": "e0d27707cad6c040", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "148" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljQXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:22 GMT" + ], + "X-Amzn-Requestid": [ + "7eed2a9e-4df9-5934-aeb6-4a6a8d2b0a5d" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD43ZWVkMmE5ZS00ZGY5LTU5MzQtYWViNi00YTZhOGQyYjBhNWQ8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestBatching.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestBatching.replay new file mode 100644 index 000000000..69327cce2 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestBatching.replay @@ -0,0 +1,1403 @@ +{ + "Initial": "AQAAAA7gDLWEI7sRogAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "39d7915f54c1da60", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNCYXRjaGluZy10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "329" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:08 GMT" + ], + "X-Amzn-Requestid": [ + "75cbeae8-eb72-5e70-b193-8a1c2bb694d9" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQmF0Y2hpbmctdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjc1Y2JlYWU4LWViNzItNWU3MC1iMTkzLThhMWMyYmI2OTRkOTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "de3b7e7a422c6e0f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "38" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "86" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:09 GMT" + ], + "X-Amzn-Requestid": [ + "ce8ad752-ce04-5f84-8596-b7a60ec18c94" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + } + }, + { + "ID": "f27c7ec6cc7c1cc7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "116" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "87" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:09 GMT" + ], + "X-Amzn-Requestid": [ + "5847bc65-177b-5a3b-a9f1-dc91d7bea92b" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn19" + } + }, + { + "ID": "8a59b823ca1c91c4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "458" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQmF0Y2hpbmctc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:09 GMT" + ], + "X-Amzn-Requestid": [ + "32ed15b5-62b6-577c-aee8-7541a273f46c" + ] + }, + "Body": "" + } + }, + { + "ID": "700597a99e688049", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "202" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0JhdGNoaW5nLXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0JhdGNoaW5nLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "372" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:09 GMT" + ], + "X-Amzn-Requestid": [ + "da06f938-6a19-53ba-a70b-99ccaadcd913" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQmF0Y2hpbmctdG9wLTE6MmIzNGY2MmEtZDM3YS00Y2VhLThmZjEtNDliZDMxZGY3ZjA0PC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmRhMDZmOTM4LTZhMTktNTNiYS1hNzBiLTk5Y2NhYWRjZDkxMzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "e24f9426f199f792", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "697" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjIuSWQ9MSZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMi5NZXNzYWdlPWhlbGxvK3dvcmxkJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4zLklkPTImUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjMuTWVzc2FnZT1oZWxsbyt3b3JsZCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuNC5JZD0zJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci40Lk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjUuSWQ9NCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuNS5NZXNzYWdlPWhlbGxvK3dvcmxkJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci42LklkPTUmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjYuTWVzc2FnZT1oZWxsbyt3b3JsZCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0JhdGNoaW5nLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1007" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:09 GMT" + ], + "X-Amzn-Requestid": [ + "ccd33417-97ce-5afe-8839-54e3570ba057" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjA2YWJiNzEyLWIyMDItNTIzZC05MDMzLWQ3ZTY3MmM3NTg5NDwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICAgIDxtZW1iZXI+CiAgICAgICAgPE1lc3NhZ2VJZD5lMWU3OWI1ZS0zMzY3LTU3ZjYtYTU5Mi1mYmFhZjNhMjVkNWY8L01lc3NhZ2VJZD4KICAgICAgICA8SWQ+MTwvSWQ+CiAgICAgIDwvbWVtYmVyPgogICAgICA8bWVtYmVyPgogICAgICAgIDxNZXNzYWdlSWQ+YzY0NzRlMzYtMGUzMS01MTQ0LWJjNTgtMmVjMmNlZjQ1YmVkPC9NZXNzYWdlSWQ+CiAgICAgICAgPElkPjI8L0lkPgogICAgICA8L21lbWJlcj4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjQ0ZTNjNTQyLTY1ZDMtNTY5YS1hNWM3LWE1YjZhNTE2OGMzMzwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4zPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICAgIDxtZW1iZXI+CiAgICAgICAgPE1lc3NhZ2VJZD45NmJhNDE3Yy05MmM0LTViNTMtYTVjYy0yMTg4NTIwMTMxZmE8L01lc3NhZ2VJZD4KICAgICAgICA8SWQ+NDwvSWQ+CiAgICAgIDwvbWVtYmVyPgogICAgICA8bWVtYmVyPgogICAgICAgIDxNZXNzYWdlSWQ+ODNhMmY4MjQtYjI3ZC01Mzk3LTg3OTItOThkMDcyYjhmOTNlPC9NZXNzYWdlSWQ+CiAgICAgICAgPElkPjU8L0lkPgogICAgICA8L21lbWJlcj4KICAgIDwvU3VjY2Vzc2Z1bD4KICA8L1B1Ymxpc2hCYXRjaFJlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+Y2NkMzM0MTctOTdjZS01YWZlLTg4MzktNTRlMzU3MGJhMDU3PC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L1B1Ymxpc2hCYXRjaFJlc3BvbnNlPgo=" + } + }, + { + "ID": "61edf3737ce7f4cc", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "697" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjIuSWQ9MSZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMi5NZXNzYWdlPWhlbGxvK3dvcmxkJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4zLklkPTImUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjMuTWVzc2FnZT1oZWxsbyt3b3JsZCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuNC5JZD0zJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci40Lk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjUuSWQ9NCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuNS5NZXNzYWdlPWhlbGxvK3dvcmxkJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci42LklkPTUmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjYuTWVzc2FnZT1oZWxsbyt3b3JsZCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0JhdGNoaW5nLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1007" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:09 GMT" + ], + "X-Amzn-Requestid": [ + "a2265122-6b96-5b6b-ae24-31d6ab53b1c2" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjAxZjcyNTMxLWZhZDctNTljOS05MmM5LTQ1YzUzYTEyMzM2MDwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICAgIDxtZW1iZXI+CiAgICAgICAgPE1lc3NhZ2VJZD43ODc3Y2EwMS02ZTJjLTVjNTktYWIzZi1hYWY1YWVlOTk2ZjA8L01lc3NhZ2VJZD4KICAgICAgICA8SWQ+MTwvSWQ+CiAgICAgIDwvbWVtYmVyPgogICAgICA8bWVtYmVyPgogICAgICAgIDxNZXNzYWdlSWQ+M2U0MThmNzAtZjQxMi01Y2EzLTgxYTYtZWY4NDM0ZDc3NjBhPC9NZXNzYWdlSWQ+CiAgICAgICAgPElkPjI8L0lkPgogICAgICA8L21lbWJlcj4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmQ0YWUzMzYxLTFkOWMtNTkwZS05MTUzLTUzOTVkZDU5NTNhNzwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4zPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICAgIDxtZW1iZXI+CiAgICAgICAgPE1lc3NhZ2VJZD5kNzJlMWI2MS0xZDFlLTUxMTMtYThlYy03Yjk1ZGRkYjliYmE8L01lc3NhZ2VJZD4KICAgICAgICA8SWQ+NDwvSWQ+CiAgICAgIDwvbWVtYmVyPgogICAgICA8bWVtYmVyPgogICAgICAgIDxNZXNzYWdlSWQ+ZmYwMzA3YjItNDRmZC01NDExLWJlODAtNjc0Njg0MzhjZWI4PC9NZXNzYWdlSWQ+CiAgICAgICAgPElkPjU8L0lkPgogICAgICA8L21lbWJlcj4KICAgIDwvU3VjY2Vzc2Z1bD4KICA8L1B1Ymxpc2hCYXRjaFJlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+YTIyNjUxMjItNmI5Ni01YjZiLWFlMjQtMzFkNmFiNTNiMWMyPC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L1B1Ymxpc2hCYXRjaFJlc3BvbnNlPgo=" + } + }, + { + "ID": "5d7197aac2b0e675", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:09 GMT" + ], + "X-Amzn-Requestid": [ + "b6f234e2-b925-5078-8f37-541679e0b368" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyOTcxMSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5NjczIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiNzg3N2NhMDEtNmUyYy01YzU5LWFiM2YtYWFmNWFlZTk5NmYwXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjYzN1pcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiTGpUSzdoNWY2VVo1UElPdWkyNHdrT2k3WXNNd01OemNqQUFTRll4UHZaY0VIT243dURsdDRjc1drRjFTcmlEaWFxUEhyU0M2MW5Yd3A2a0xCdEtpVXFwQjhWNUdzSHFoZ0J0MW5FRm5vVTRsNHhKNWthc1ArcmhJOE0wdEViRkRadWxWYmhtcVRuZDVHVHBnUDNidmhVN3FLNHlxa2p3aE16NlN5a2JmSGxHbGZlbEFxNUhIdTAyMVR5emFkZndVMFI1YlFMNnZ4cUdOa3pKUlBGeGJiSEdCNG9nNDA4NVpPTHJ4M3BYbkw1dGdNRGJISGlmVW5HZzVJRmNIdDFZbGJWNjBRajI2SHFVWHhpTGp0a2VyWERBYjNjSEhBb25KNGxZOEhKMm1SaFpldmtYbTBYNnphemw2R1lGcVBoUXpKR3RFSnNMWnJldkhxQmxyU0h6WXV3PT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6Ijk0ZjI2ODk0ZDVjMTgxNmNkYzk3ZjNmMjk4NDU5YjMxIiwiTWVzc2FnZUlkIjoiODkyMzk1ZDYtNTVkYy00OWEwLWE1NTAtNDQ0MTQyYjkyNzMzIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJTSHltS2IwQk1JYVVhWXl0NmFQOXU2Z0tIUmgvdU9xTXFPTFhOdzREZUhWK1BNbGJoM25vL1V6Zzgranp6Qlh2VExwSG4veWZFWU1KK2JHdU84OWlpeUZTUFpNK1Q0U05DRHlwNk1Uc3dIOTFZdGRCUSs5MG1tRWZzSmQ5OHRjNmxOZjBjWTFzdmVRc1RaQW9oRWxGR3U3ZkYvenNUUVh0M3FlRTd0bWpWVk96Wm5IWWpPUDlVMDFMTG9jNUUwVVN4YUV1eW9yUndkU1UreUVZaExpWThiZUYrL05CZGtScytOT1R6NFVvZHN1czg5SHRkZkZHT0xEaElIaHJNNktqSldWdHp3eUltZ3dJUEJkbitFc1FYYXhhVTVvUURmVzk4NjkrY3FPTlVvRDNzK0tYUkI2YTlLWHBDZ0RObnhEV2ZyRVRDTEZjd0c4UVdyQnlSOWc1cEhCci9UbFFrU3Q4LzFhODlOWlVRaVpYcGI0Z3loRXVieFdxcERNOEsvRk8rNnhsWkE2dHUwbmovRHlFRFhsVEhRPT0ifV19" + } + }, + { + "ID": "921aa318f3b4e585", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:09 GMT" + ], + "X-Amzn-Requestid": [ + "c315afd9-63b8-56a9-97df-cf2da37d35b9" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyOTc3MCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5NjAwIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiNDRlM2M1NDItNjVkMy01NjlhLWE1YzctYTViNmE1MTY4YzMzXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjU2NVpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwickowQlp0NW5CL1Bsc2p1U0huU0FqbnlqSWVna1hjVU9OWXNMbGlUMkxjVGZDOFFjY2VOeWMxTUpyUmI4dFBDTjE3OHMwNDZpOVFGNTlyM0Mvb0t6K29yd1JaVms4UU4vWHdEanlKN3Q0WU5QL2l4Y053WXFxWUwrZEQwbTMyaHZ5R0ZFM2p3Qm5nWGgzWGZVR05mZllUNG1MbXcvUTZMbVhRYnIyelhCeXhleWlnQnhZbVV2YmJZZkJtWk9rVlo1aGNoaU5QS2w4QmlxaGVTM0xNWk1FaU5iWG1IUkcySUFBS01HVklSZ2gyT1ZHd3pLTHp5TFZpR25remVmYjhueGFydGhJR3grMzBNSFhCUnBTL1h5bTJ0ODZyQkFEUUJDVXpSck1wRGUzdGRBYllyM084ekRac0k3cm54L1h0bkp6S3lsTHYxUTNvWWwvUVlsNFpqc25RPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6ImQ1NTExYTg3NWRkZTlkYzhlNDBiMzFlZWYwZjhmYzY4IiwiTWVzc2FnZUlkIjoiYzczZjJiNzQtODZmOC00YjAwLThlODMtNGNjNmNmMDk1ZjY4IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJ3VUpHMzZmZnBUK2oyMU1ZcWpmMVc4M3BBVHdjRTNoZ1EyQTFsNTVCOGdQUC9zK1kwbzllZGhTbTFzYW9IeW45cU1GRXRTTVVYR1pYbW5ZTkdlVUx5cGlMVGNxcmhTM3E0Q0E5Y0ZrMkU4SWQ1Lzl1c0NCZTZqMnRwQUtsZzJUY3RvODM4WDNUcG53aDBqYUN2Nkt2R203UGttRng1RnUvZm1qdjBGVjMzZWNJaUxxdWJsWjJ4WlIrOGw3clZLNk9zMWM0S09EUkVKb1lpcUoyT0lOYmJDMnh2ZmdsZVBVbWpUWExCK1dpNUhVTGNQa3JWaFR3ankvaWZ3c09jeVhvb29keVNFd3AwOC92K2pqa29qYkxHUXlIaUd5VVVLVS9QeHh2RlJRV3Fmd0toWk5KSUtjT3VJUWkvQ085dWdRN3JvL1dNRkhPNXFzdFMvTTVqbFZlQ2dhbjFiM1JiVk9KVGN2VXZEZE0rbHhHM2JIT2ZuQjBGS3RQMXoxSGdyOEhML1NNc0x6U1pDWjVDQjJndnlsUFhRPT0ifV19" + } + }, + { + "ID": "1d87d39948155a35", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:09 GMT" + ], + "X-Amzn-Requestid": [ + "a057070a-e598-598a-bb7b-67fe255d8a9a" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyOTgzMSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5NjAwIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiOTZiYTQxN2MtOTJjNC01YjUzLWE1Y2MtMjE4ODUyMDEzMWZhXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjU2NVpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwicXg1TjBLY0Q5eFZrcFVmM0FZaU9kTjFna1dwVUZtQkptM3JFY2svK3BtV1F1aTRaWTI3MERSMUc0cnhXV3FTcVF1V1Z4L0NKZllXaWE0b25zb09QRzI5TjZvaWxpQUd4S000eXR0dnB4bXZ5bmZIb3J0bkhyYU5jZkZiRjJpdW11ejBHeW1rc2d6L3puSkFSTmVyK0RXWlR4N3dsQjdMV3NrckpHVXJxdVNsL3hZbUVLVGhna0JwM0ZTOEFpMkw2bnNySEFmbzE4NkhXWWQ4c25IbTFaQ0N6OXdEYW9zMFplQkpLY3FNT3hjVkVNODQ5RDgwR09yc3dncFFQK252c0szeFhzSVNuZXRocjltRnV5SEZkK1hwZDQxNWt3SzJWWXh0dHUxcDlSK0x4Rnk4aUVIVlJnUDFYd0RTYzFOVDdteUJ6NC9DeVNSOTJnNW03WjVkcGJ3PT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6IjFkMTViNDAzZmI1NjRiNjAwYzJkZDBjYTIyZjFiZDY5IiwiTWVzc2FnZUlkIjoiYjVlYTBhMTktNDAyYy00MTkxLTg0NzktNTM1ZDc3OTQ3NmIzIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJUeWs3cUZ5MWF2TlFISm8xaHN5Q0V3VFpnY3RMcFdGTjBYbGZuZWZNR1RXY2NrS2dJOWJGUUt1b3FhVURpTkMxeTNrS01FY2szOXBWbGh1cDM4ZDVZc3VqaVZ6YWRDdy8yRXl5SWNNQmxoaVY0NWRRamZwckwzdk0yQytkcVk4OEVHNk81czZmRHN1RW5wdktaZVlVRXIzajVzWU9ZZkhTV2tlOURmZ0hPc1lpT3ZGVUpNMC80bHR3V1o1M0c3VStsNnZZbWpvQkVsTzNqTzBRT2xLbjFZRW1VeEIxUnpya28zK1FQMHBWdlNhZ2loYUQ2Yk13NFJnbUpuLytxanBCOTRqTW9XaENkclBtU2pqWnRXcmZBTE9sZUNDTFREYlhTZGM5WlVQYXhLT2N6UE9EcnZVQWNmck9GMXBNOElLSG5ZRThFa2s4aXRaaTE3bWdEUm9jdjI4NUxwem55dnVRMFlOUDExRWxXUnlyS05wMDFnWHp1cWc2M0JZazVWLzFjQTJLekFWVnVpeGQ2NzRzc053WllnPT0ifV19" + } + }, + { + "ID": "cf2fe0f0a7b3b835", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:09 GMT" + ], + "X-Amzn-Requestid": [ + "fab33090-a004-5879-bdee-506460c18b69" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyOTg5MSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5NjAwIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiYzY0NzRlMzYtMGUzMS01MTQ0LWJjNTgtMmVjMmNlZjQ1YmVkXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjU2NVpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiaEFwR29KaWJvdmpvMjM4ZHZLZTdvdlVCUmJHZ1RxSlQ2T2lBeTVOcEJjemhYamxnb0tTSk5uWGFBMlgrT3V6OTRtaUprZmc1a05qRGNMNmVwQTdVU3lvODF1NFo2ZklUU2l0L0haWXlVWTJLRTJNZHlNd01tNGJYdXY0WGVrS2IwYWhnbWNCZEpjcFE5QThlOGpqRXFhbEJBUVM4K2dqaTdtYlBkRTRJVmdUVjNPMnlwVmI5N084ZlVQS3g3cUtWblJ6ZllFOStacEpxS0pHN0NwRlRlYlA4cmxMQjg5K2VSTXFZVTRZZ1VWbitPeG9QdHd6MzZvQkpZQTFJc0Fmcy9IUlNSbUhuY1QyV3YrTllkUVlodnU2R1FqaThhQkUrZ3NsLzhnT3pCYUZkS3hJbDh4UnpINU9CeHQ2SzRiQmZ3V0c5ZzJSNDRkajZ4aDZtSW55eCtRPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6IjliOWNiZDdkY2Q5MzVmZDEwMDljY2ViZGNhNjRhNTdkIiwiTWVzc2FnZUlkIjoiM2QyNDM5YWQtZmRiZC00MmUyLTgzNzktYTExMDI5Y2E0NDc4IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJETmNhTVVGSlhncEhGenIxdXZIV1gyVVliOXZUT2lnZGxNYWhpZVVaSTRjcFVvcE4yTC94Y3lPbVlZdllpQlFpVUluemM0cWx1KzFkUkhSOG1Rbm1OR1d6VWxuaXFTdjIzU0c0VEJZNUJEVVFFUmNGcGgrOUswMTlKdGpnM25WUGFURjYzT1Y5YnZxRk1jdWlzVDE2dEZnbDRpZENDQUxheVpFQ2sxelk1S0cwT1cwSi9WeVJwSHJXaW41dDhsc1ZESHd3ZmU5RGVxSDNQT3pRbVNZR1JuRllIblBRb1ZIQW9wMUZTQ2dTcHJhcUxVaEMxdGdIcldsck5HVU9GTmNJaFpiMUFtL0pPQnNTVmVjMlQyN2I4VHFkYlJHcWRweC8wWEswUzN1M3FWZ25tRzlGL0ZvMTJRZWdaTHVlM2FHMkNOc0I4Zkw3RUlLOEdhZ1lxQmhPdHFHZmVrbUthd3VTYWtVY3ZIVFdwL0VlSUY1dUorTzNmc3FmSXNVTWN5cnErV2hOMzlIY21DNjk3YzdBeFNmRllRPT0ifV19" + } + }, + { + "ID": "7238bea9b4c0fcc3", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:09 GMT" + ], + "X-Amzn-Requestid": [ + "b12d7be1-bab1-500b-ad52-1b157a74031b" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyOTk0OSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5NjA0In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiZTFlNzliNWUtMzM2Ny01N2Y2LWE1OTItZmJhYWYzYTI1ZDVmXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjU2NVpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiVGhKR0VkNUo5RVV1VTZCZnhxdDFZNWJ0OWczL2VCOG51MWdQRjFQeDZGR3hzRGxqMEZSajVYaFBRT2NKenVPQzVsYmxISlFlOXNiWXh1UFY5d2JUbmsyOGlzZlJFM2t3MXowU2k4MnBjSlVNbEwvTU9kY1pPc0YrWG56TlVHZG5BUzNQalZPdUFpaUQwS1ljS3V6UTVUY0xOUmlXY0VrUVVRU1Q0blhiUFZJdE1IRXJ0bFVmWXJMSFdXZzRkWElFY1dUT0NMOGF6MGVnenAxMHB3WUJjOGJDTDY4ZTFJUUpjeDY2LzJKYmhWUkF2Q0FsbkNkTGtEQnVNOFlJUmgrTkVwTWNManAxRG5PbEI4S3haQ2ZzZEw5YUJiREcwL3pEVHppZTEzV1lMNWtRbFo4S3pLcmc1czJxWm5FaXVvcjIwM21ELzlLdlYyUk1VY0pGN1NxT05nPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6IjgzMGE3MDNmNDg4MDc4YzlkNmFkMWJlYWY3Y2U3Mzg4IiwiTWVzc2FnZUlkIjoiZDMzMzhlZmItMmZkMi00Njk0LWJiYzItNGU5ZjI1ZWJjZDhhIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJ4UC9vcFBMWTlhejZHdFFMZ25BWGFIblM1WFFPNmVKeWg2bzRGUGdjRFdaaHVodStlTFRGWTJpRjBVdFJBUmdNdi9OY29tK1p3ZXlQaXRhVjZsbzcvQWpDM0ZyNUk4VUxpMTFnVC9uOGFINW9RNEFUdXFuWGhibVg3QXFNbkVKMTcrWkxoTXBEWHhWT3ovVWliTklsMTRTR1d5SW5vdHVGdjJ6WFF2NXY0b3pmalYzdHlOd1ZxYXpLaVk5V3BtUDdCejVaRVZlTWg4N0wwTm1DbUZLU0lTMzlyR2F5TzhOdm9xd3RCZUVURlhNeURPd3VvVTkxaExVVjFNOWFobjN4S1lIc093Nlh6VVoybndmZ09ibjJ2ZGl5UHJLZjNJaHhqUzRxM05RKytWZGw3c3FHdTBQN25WUGZxWE1FRDZCSGRsc2dSZEFIMW9IZk95cU16eWNDVm5rbG1oWndYdU5adWR3MVFxWGVkcEN5UWkyQjdZK25TbVFXQzltK1lFdVRtS08zeHBGRGE3MVRUOU5TMW0xNHp3PT0ifV19" + } + }, + { + "ID": "27df92ff1fb5e131", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "71fa4221-c5eb-5070-b070-22d5052de360" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzMDAwOCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5Njc1In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiZDcyZTFiNjEtMWQxZS01MTEzLWE4ZWMtN2I5NWRkZGI5YmJhXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjYzN1pcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiajJ3WlZ1bnltbGRibGJPTVE0Smw4Y01TWm5VRXZSS1JpZjZCT2JUb1RKL3kxYXBqekxIQjgvTC9kSlBjenJHR1h2SFJveEdIa3h6OVV4eFNlS0ZpcHpZM2lncWtReXptS1JONzBXOFNmcUMzL21jOGN2S0owdFpFVjFXaVkvMUpxMG56SFVoVUJ5eDE2NU8wYjlEM2lxbXo4eSt0VWFTRHV2TW5VRU1uaGdBUjZwZ1dMcUp3VVNlK1RhZ09YYWdkSDRJalVkdWluY251TFlrRHArdFJvWHJXellsUC9ZbTlwOXp5L2JTemc5SldNczJxYlVKa3NXUnBoL2RiRnNyWjBMOGZpSlgxb1g5eTRkaEdUcWp2bzUvSEJSQS9YQ2hlREhqK0VSSmtneUlGcEw0eU9IQ1V1QldKZWtkaTNXSUYwai9XTzlXZVJ6WTk3RmNJVzluek1nPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6IjI5MjNkODViZTcyYjgwNGQ2MzQ4MDY3ZjYyZDExMDE4IiwiTWVzc2FnZUlkIjoiYjFhMjdhMDItZmFhNi00Mzk1LThjMTgtM2Y3NTI5M2YwNjgxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJUNWkrVVJNem5YUCtteEk2NkR3d1RTaFMxbXNvYXlldHNhM3RCMzdmUXlNWTA0b1JEWGdMZG5MRTAxbHhVaGp5Ky83SGZlNGptUTVzaW1Belg2Q1hMZ2ZMN29WdEVieExidUFYVmp5ZDNwQ3BwMTZzNWM0ZzM1aHdrME1lNkFlTE1ONnpiNEwyTzZ4T3FMSUZHSXlJcVU1anBHMlpyUjlaaU1FL2pyemtFajVvR2ZrMjhoOFdpMlBqMzRIck1LMktZU3UrS3Z6SmNNMzFBTUYwUHcwVEJoVW1JUjUyODVGbkFWZW9jZFVjOGRuU1B3cnY3K2dheEJvQmdteVNWdzIwTTFRYTRNbXdEekZLRFhMY1FtaVh5RER3N0VOVmNUYno1OUdlc2V0NnV6a1V2RzVjNW9sZDRCWDUxZDdMbENENFZmcUZ5blE2L256U2dGVHUwNE1hNElYc1RrMWNsN1gzK0dsK1VpN3owR1RQOUJ5RTc4K3J5eUdaOXhTM3BYMlRMVmJ6QVJTYWhKblAzMDl4cFN0YzV3PT0ifV19" + } + }, + { + "ID": "65c8b7f0c3f3f7b4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2750" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlNIeW1LYjBCTUlhVWFZeXQ2YVA5dTZnS0hSaC91T3FNcU9MWE53NERlSFYrUE1sYmgzbm8vVXpnOCtqenpCWHZUTHBIbi95ZkVZTUorYkd1Tzg5aWl5RlNQWk0rVDRTTkNEeXA2TVRzd0g5MVl0ZEJRKzkwbW1FZnNKZDk4dGM2bE5mMGNZMXN2ZVFzVFpBb2hFbEZHdTdmRi96c1RRWHQzcWVFN3RtalZWT3pabkhZak9QOVUwMUxMb2M1RTBVU3hhRXV5b3JSd2RTVSt5RVloTGlZOGJlRisvTkJka1JzK05PVHo0VW9kc3VzODlIdGRmRkdPTERoSUhock02S2pKV1Z0end5SW1nd0lQQmRuK0VzUVhheGFVNW9RRGZXOTg2OStjcU9OVW9EM3MrS1hSQjZhOUtYcENnRE5ueERXZnJFVENMRmN3RzhRV3JCeVI5ZzVwSEJyL1RsUWtTdDgvMWE4OU5aVVFpWlhwYjRneWhFdWJ4V3FwRE04Sy9GTys2eGxaQTZ0dTBuai9EeUVEWGxUSFE9PSJ9LHsiSWQiOiIxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJ3VUpHMzZmZnBUK2oyMU1ZcWpmMVc4M3BBVHdjRTNoZ1EyQTFsNTVCOGdQUC9zK1kwbzllZGhTbTFzYW9IeW45cU1GRXRTTVVYR1pYbW5ZTkdlVUx5cGlMVGNxcmhTM3E0Q0E5Y0ZrMkU4SWQ1Lzl1c0NCZTZqMnRwQUtsZzJUY3RvODM4WDNUcG53aDBqYUN2Nkt2R203UGttRng1RnUvZm1qdjBGVjMzZWNJaUxxdWJsWjJ4WlIrOGw3clZLNk9zMWM0S09EUkVKb1lpcUoyT0lOYmJDMnh2ZmdsZVBVbWpUWExCK1dpNUhVTGNQa3JWaFR3ankvaWZ3c09jeVhvb29keVNFd3AwOC92K2pqa29qYkxHUXlIaUd5VVVLVS9QeHh2RlJRV3Fmd0toWk5KSUtjT3VJUWkvQ085dWdRN3JvL1dNRkhPNXFzdFMvTTVqbFZlQ2dhbjFiM1JiVk9KVGN2VXZEZE0rbHhHM2JIT2ZuQjBGS3RQMXoxSGdyOEhML1NNc0x6U1pDWjVDQjJndnlsUFhRPT0ifSx7IklkIjoiMiIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCVHlrN3FGeTFhdk5RSEpvMWhzeUNFd1RaZ2N0THBXRk4wWGxmbmVmTUdUV2Nja0tnSTliRlFLdW9xYVVEaU5DMXkza0tNRWNrMzlwVmxodXAzOGQ1WXN1amlWemFkQ3cvMkV5eUljTUJsaGlWNDVkUWpmcHJMM3ZNMkMrZHFZODhFRzZPNXM2ZkRzdUVucHZLWmVZVUVyM2o1c1lPWWZIU1drZTlEZmdIT3NZaU92RlVKTTAvNGx0d1daNTNHN1UrbDZ2WW1qb0JFbE8zak8wUU9sS24xWUVtVXhCMVJ6cmtvMytRUDBwVnZTYWdpaGFENmJNdzRSZ21Kbi8rcWpwQjk0ak1vV2hDZHJQbVNqalp0V3JmQUxPbGVDQ0xURGJYU2RjOVpVUGF4S09jelBPRHJ2VUFjZnJPRjFwTThJS0huWUU4RWtrOGl0WmkxN21nRFJvY3YyODVMcHpueXZ1UTBZTlAxMUVsV1J5cktOcDAxZ1h6dXFnNjNCWWs1Vi8xY0EyS3pBVlZ1aXhkNjc0c3NOd1pZZz09In0seyJJZCI6IjMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkROY2FNVUZKWGdwSEZ6cjF1dkhXWDJVWWI5dlRPaWdkbE1haGllVVpJNGNwVW9wTjJML3hjeU9tWVl2WWlCUWlVSW56YzRxbHUrMWRSSFI4bVFubU5HV3pVbG5pcVN2MjNTRzRUQlk1QkRVUUVSY0ZwaCs5SzAxOUp0amczblZQYVRGNjNPVjlidnFGTWN1aXNUMTZ0RmdsNGlkQ0NBTGF5WkVDazF6WTVLRzBPVzBKL1Z5UnBIcldpbjV0OGxzVkRId3dmZTlEZXFIM1BPelFtU1lHUm5GWUhuUFFvVkhBb3AxRlNDZ1NwcmFxTFVoQzF0Z0hyV2xyTkdVT0ZOY0loWmIxQW0vSk9Cc1NWZWMyVDI3YjhUcWRiUkdxZHB4LzBYSzBTM3UzcVZnbm1HOUYvRm8xMlFlZ1pMdWUzYUcyQ05zQjhmTDdFSUs4R2FnWXFCaE90cUdmZWttS2F3dVNha1VjdkhUV3AvRWVJRjV1SitPM2ZzcWZJc1VNY3lycStXaE4zOUhjbUM2OTdjN0F4U2ZGWVE9PSJ9LHsiSWQiOiI0IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJ4UC9vcFBMWTlhejZHdFFMZ25BWGFIblM1WFFPNmVKeWg2bzRGUGdjRFdaaHVodStlTFRGWTJpRjBVdFJBUmdNdi9OY29tK1p3ZXlQaXRhVjZsbzcvQWpDM0ZyNUk4VUxpMTFnVC9uOGFINW9RNEFUdXFuWGhibVg3QXFNbkVKMTcrWkxoTXBEWHhWT3ovVWliTklsMTRTR1d5SW5vdHVGdjJ6WFF2NXY0b3pmalYzdHlOd1ZxYXpLaVk5V3BtUDdCejVaRVZlTWg4N0wwTm1DbUZLU0lTMzlyR2F5TzhOdm9xd3RCZUVURlhNeURPd3VvVTkxaExVVjFNOWFobjN4S1lIc093Nlh6VVoybndmZ09ibjJ2ZGl5UHJLZjNJaHhqUzRxM05RKytWZGw3c3FHdTBQN25WUGZxWE1FRDZCSGRsc2dSZEFIMW9IZk95cU16eWNDVm5rbG1oWndYdU5adWR3MVFxWGVkcEN5UWkyQjdZK25TbVFXQzltK1lFdVRtS08zeHBGRGE3MVRUOU5TMW0xNHp3PT0ifSx7IklkIjoiNSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCVDVpK1VSTXpuWFArbXhJNjZEd3dUU2hTMW1zb2F5ZXRzYTN0QjM3ZlF5TVkwNG9SRFhnTGRuTEUwMWx4VWhqeSsvN0hmZTRqbVE1c2ltQXpYNkNYTGdmTDdvVnRFYnhMYnVBWFZqeWQzcENwcDE2czVjNGczNWh3azBNZTZBZUxNTjZ6YjRMMk82eE9xTElGR0l5SXFVNWpwRzJaclI5WmlNRS9qcnprRWo1b0dmazI4aDhXaTJQajM0SHJNSzJLWVN1K0t2ekpjTTMxQU1GMFB3MFRCaFVtSVI1Mjg1Rm5BVmVvY2RVYzhkblNQd3J2NytnYXhCb0JnbXlTVncyME0xUWE0TW13RHpGS0RYTGNRbWlYeUREdzdFTlZjVGJ6NTlHZXNldDZ1emtVdkc1YzVvbGQ0Qlg1MWQ3TGxDRDRWZnFGeW5RNi9uelNnRlR1MDRNYTRJWHNUazFjbDdYMytHbCtVaTd6MEdUUDlCeUU3OCtyeXlHWjl4UzNwWDJUTFZiekFSU2FoSm5QMzA5eHBTdGM1dz09In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "82" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "f8ea7cbc-cb42-55de-93a0-1c480b8406ce" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjQifSx7IklkIjoiMCJ9LHsiSWQiOiIxIn0seyJJZCI6IjIifSx7IklkIjoiMyJ9LHsiSWQiOiI1In1dfQ==" + } + }, + { + "ID": "7074cfd8b9b8c637", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "02356621-4629-5db6-88ff-06d586ef2ea6" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzMDEyOSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5NjAzIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiODNhMmY4MjQtYjI3ZC01Mzk3LTg3OTItOThkMDcyYjhmOTNlXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjU2NVpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiaEUwVVYwR1R0d2JGSTJpMUJIVTBBMzVkejhmTVc1bGZXMEhRb0Z2dUo3dnhBVUwxOWtLSVYxSHRpR2FPQUU4MzMyaTkzdmZ4SVZRa2J5SndNU3ZqSlN4dnY1cy9FLzdCTkhPbG40TzZ0MGE1enBsVHRtS2lCT2tTK1Y1Sy9uS2JWZEtyZEJkZ3ZLMUt2ajVQbEtrdEw2Yllncjhxd0ZsM0lTOGc3NXgxOWZGN1VLNGxVUXpTbHo0R3Y1NXBicGI1a0d1MlZ3ay90ZWVWZzFpa2UxSWhyMUdzMnhjUUtPM0J4WlA1L3lPTngyeXRiL3MvVWxZeFZ6TWdoMXIzeWVXenJCcVdjNi8yMDY0elFxdEpZeGpURnJ1OEYwN1JGVy9VQlIzSDUrM3BHVUlyWThjNUtEdTFTNHY5ZEgzbG1LVmNWWklaTUxKN0RtRHBpZEdxYnlmZ1Z3PT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6ImE0NmNmZjY5YjQ3ZWNkY2M1ZjE0OTM3MDBjYWYzNjJlIiwiTWVzc2FnZUlkIjoiZGFlNjQxMmEtZjcxMS00MDkzLWE0MzMtNDBiMzM0M2I0OWE5IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJydW96cGw1ODRGU3dUTHN1dVEzRHUzNy9RYlo5azFGenlJZmJreHJWOXplUkpOTkZ3Vmt1YlJQS2lwM3lHODBkZVRXdEFQNjlvaHRvTDk1OE1XMGVIakFtWXhCL0c3bXczK1ZqbTRxL3lvYkhQNDUxT0V4WkYwVW44TEljVENCMFZoU0xEVkRhZllzanhkcjMxZEw4dnJKU1l3YkllTE56cmZlZWNwcmhia0FWSEhZZ2tLQTFlcFpaOU9pNU1kRnRpSlpQMFBSMklDSSt2UzhVcGRvTTQ5QllmaFVyTjFoUFE3dEJsL0pmb1VPcTVpNVdRMXFGeHUvV3Nnck55UytFbUJuR214Y09yaUJaclYxRzBiUlluRitHM2FJVVh4SjkvOGI0WXcrSllZRFJIcE1UUmZLRXZwZ2F6dkVsYmw1MjJ2SjROeFRRQ1RVZHdPWUZNcVhTOWpYMC9Ybk4vRE15eTNMSEw4Q3J0cmhWUWsvMmJobHh1K21HM1pobHhaTUphditWLzlFTW1uTlNzM21uNFUrazlnPT0ifV19" + } + }, + { + "ID": "6d6e249684bb748d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "e2fb890e-0b8d-5e19-ba54-e9facb4b9d09" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzMDE4OCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5Njc3In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiM2U0MThmNzAtZjQxMi01Y2EzLTgxYTYtZWY4NDM0ZDc3NjBhXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjYzN1pcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwia2l3Skc0MWdhN3lUVGJELzNLOUV2MzhKa2s4WGNubWdsdG90VWR4aFAwdXA1VWpOUjV3dEFjZjgxSTZsR21zTGdHN3plUHNjS2NwS2hxMFdrdU1zdVJ1dVY4dzMrRWZ4RzNEWGRWUWw0dGhRVjR0d0xKOUdlWkU0amU0QmN2YnJJR0lzTTFFaC9wMEJRU3JYVVVhUkdZU1dVdDB2Q3V1eVRCc0ozM3VUMktGbTRzSHJCV09KTkhaRUhkWHFHM1RaWXk4Tzk0d2JaRUhrVEhiMDNtQ2dtRGJOWTc5bHA0dkppNXQ1M0lnTGt1aWZubEpReGtHd05aSzFYR0dDVzFRT25qRy9TRGxLdFVBSjd4VkNjQmdtanYyK3JPdjRrMnJidnR0bWNjNTFzbEFxMXFac2o3TWhQWFhKZmVFand5bUkxdFhkOWFndmFFUTBsUFVrckVvbVNnPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6ImEzYjhjNTYwNDYyMWJkMmQwMzIzMjIzYmM2MWNmNjZmIiwiTWVzc2FnZUlkIjoiZmM2NDUyMGMtODEzNi00MzgzLTg5ODctMTc5ODA3NjFjYjQ4IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJKQmxzRGFFcUxjcmxzWXNtUm9RWHFQR3Z5L3kwVHZGVlRkMitsNlNOZUdiTEV2Qit2MGNTT3pjSmZ4Q3hwSTAvUGFLbGZWM0QxcXlubStnRkNHSGlXTW9lWXl4Q0xRWmFDUkxVMEYvZEFTY2JVL3dUbDZqTlFPMlpYWXAxU3c2dXJhZ1A3TnFJTVlWZjgwTnNMMGR4VWEzaXhYSk9CZWxOTnI0YTdJQnEyakFWNGp3aU1pb2xOWmdIK0NxL0hpRkx2OHU3UitTSkdoVWYvdjhwNGxkWXRZNzdZcFR1cnlHOUo0UjBNL2xLN01kK2FpeWZ1YUREd0dSZjU3K29LQW04b3czVFhaRzlIZEJGeHJWNW5uYmRPSkdHVlJKLzVFa25JTHpvYm1lVXFmYnNRZTUxMFhzaEU5QVNjVUJ2dCtPaG41MFgyUnduaXg4SlZBTEhHbitOQXN6cVV0MHFDcWZMb0haTlhqelNoeFRhN00zN1lzNk0yUUlxSDJ1Ujl2bWFTTVlQb245VnZXZzR6U0JYR1hBcVFnPT0ifV19" + } + }, + { + "ID": "8cb848e0306f8fae", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "86db4586-5781-5b45-b162-25729747d855" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzMDI0NiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5NjA4In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiMDZhYmI3MTItYjIwMi01MjNkLTkwMzMtZDdlNjcyYzc1ODk0XCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjU2NVpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiS0Vwc013U0h6aGtZZVNhRnVBWTM2eDUzSGxrcnhXLzZ6eDhLRkRWdlBxOTU4ZzdIaldIWVB6MGxJRXR6Wm9IWUZjNTR6L21xeGo4Qi9Tak9JK0tXK3ZneHdFMU8vN2czUVVDcUU2enV5a1FYcTJySk9GNkM3SmtnR0gxODVBbHRqZCtRQUJiM2hOWEZpMHQ0ZWgwSGk5enV6N1d3Z2pRQjFkc09ndExESjFCMXVKbTVta1o2ZVRIL21QeW1ZU0VnZ3Nrc041dFBSRmV1emVmYmN4VlFtK0JydkMxU21NKzF6V3MwMDMwTXZ2Sk5CWEhYckhtWGNMZzF0clp1U3l5U1R5R29IT2lTR2QzcFlycmZtTHcwZ2Vua2NCWWRCaHVReFQycnZTcGFYNVdRNTNZdUNWS1F1dUZyNkFEaHptYUpsQ3NURmdxd3pwRjF5cjVhMjd6QVdnPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6Ijk4OGUyOTY3ZTUzZDg0OGU4N2IzZWVlOTNmMzI1MjhmIiwiTWVzc2FnZUlkIjoiMWMyYzFjZTgtNDNiYi00OTIxLWFjNTktOWQ4NGNlNDZiMjRhIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJrejMydkRtU1hiWXZReCtWN3BxMjY0endFaUgydDh0blpoQis1Y1Y5MGVHd3ZTK1FKYmlOR2F2UmRLZ2sxbkN6ZjY3UXN4RktDejdtRHU3M1pXcyt0cjhXZVhFUDFrSXVQLzhZc3YwMHZOd25FbTJTMUY5eHM5cHlZWEdUTk5acnNHOW5TM09mV2FJMzErbTR4aU9SVGFsZVhJZjQ4ako1WnBSencrbXBLYkljcGUxTE4rRW4rVDFHeGo3Y3ZjR29HUmVwY1phNjdEWEw5WU80RGpkNkZCbDExdnpQRkZTZkozNGhyYTEvVGZQb0RGcjVoT2RxMDErMFEzeHd2U1Iyd2s5U3pDMmwwR2ttZE5Xd3JoNGhwMWZ5REIrekRpd1ZiUlAycXpndnBqT0pmalhrYk9aYTRUdUhDKzg3bCtCUW1CVjhiZTV4Y0tzZnVwYTdZREFMQ2Q0SnBSQmdOZElSaGRvUi81VE82MllmOExsQnFiOC9BSlJJRXJPZWtRdlJiWXNBRktMMEowM3NsTU1FTkZza2NBPT0ifV19" + } + }, + { + "ID": "4b586bdefb65a29f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "e7e679e9-a67a-52ac-9fa5-191d66bcb1bc" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzMDMwNSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5NjcyIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiZmYwMzA3YjItNDRmZC01NDExLWJlODAtNjc0Njg0MzhjZWI4XCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjYzN1pcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiVllCZjhaYzZJUnhnejhSK2l1VDAyaDloVDRTVnh2UmFwOEd0ZE1FeU5zOWVnTkpnUVBVWGFLM1V6MzNjTUtzUHJSdjBydFViMkg0YXIvK2ovK1NTZlBpRU9ub0dIRnJGN09WRUl4TlRacmpJd3NxSzlwa0tpWE5MbEkwUGgwSm9WUFFuUmRVSXBFQVhWVitlcWlPbi9yVGRyL2pvR0NwN0xMMy8yTk5VeVFPSXErTTZobXN5bHkxN0p2S1hOUHMvWTRyOSswMzZwZTI1TEh4VlB0SnNBeGdac3ZqZ2VBbk1oS1RCS2o0Qi9LNXR2eWRHd2RCY2tMakZWLzQ3Um1hL05hMkMxL2tvdXNvbWJpN2hDdmdnS1FMK002Qmo5d09UOXFPNVBXQWQ2emc3aDd6YUNMaXZ2QWp5MWdST1ptaEtRQUw3Q210Qjc5aTdkMnRmblNUQ3FBPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6IjUyYjlhZTc4ZWQ1MmRkOTEyM2JjY2UzNDQwZDg4ZTNmIiwiTWVzc2FnZUlkIjoiZjA5NDJlMTctMTlkNS00NDE5LTgyNTItMTViNTUzMTQwMWM1IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJJYjdYb0xmbzArdlRZdTFHY0NpamQrWWIyVlAvMzA5S1RBV1ZJRVU5TW9CRDFocjBPN1h6ejdMaXBKeTR1cU1XUklVMElKRkRlTng3ejdwUUx5M1VydGhPdmhtR3ppME5HK3lxaW9rZVNQeUYrOU5mQXk3UlB1ZGdGL01WdUFLemhwQ01FVi9jNmJCbDBuYXA2RFhEdU5MTG5ZM3pkblNicWY5SGF0dWNLV3JQSndZdXdzRTlyKzNrWXVFYlZvdFhFdnY2NlB1Uis2SFJoUnJabURXMEFWN2ErbWl4U2ZLbDRIdGtySWhWUGVPM21QVDhFRllHU3dlM0QvSStlMWFYQTlDOERyUHZQVC9RQVdMUDRycTlpQmxhRVd1NWJIYTFkUEYyWW1YUHdkY1ZiOHhlYVNSaHFtT05vS3ZpMFVrcURRLzczaUJZUEh6a0hyNWNQQ1JyUGIzNTEyYkdPVEc4KzUySDlpUzlzdWlncUN6SUY3Uy9VZVpYS3RwUzFUSXl3TkVwbW8vNEM1VytMTm1VMXpuTWp3PT0ifV19" + } + }, + { + "ID": "eabd7ca9f1f7daff", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "14eab13f-c4c2-5170-95bc-d1cb0404b260" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzMDM2MyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5NjgyIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiZDRhZTMzNjEtMWQ5Yy01OTBlLTkxNTMtNTM5NWRkNTk1M2E3XCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjYzN1pcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwibDFUTUJYbUhKVUcxOUN0SFQ0dWxSL0lSZkI5dDBta1BiUGduakJrU1A4RXpMSjdwZ3lvV1pydmNQSjBiTGZMTW9jTkNua0pDcTNEaU1iYVNuSFRQQVl3RzVwZWgrSlBOUm1qTERZTGVkMFl5ZW90enB6cEZLcVFHZ1FqU00zNW1YWXdMSXN3THlFcGdtVnVGZ3VkRjRmNWV6enk4bU44a0lpanIvQTVLM04zY09jTmg5UnpLaTBpZmswaHpxc212eDNNdTNGdS9MWmlCVGJvOCs3dmV0UTdEMkdFaEpnOGNqakUwR1JpcUd0UVY4THBndnRpNlk3bU9ZWDlTTjdTN2Z4cVY2WUxLNVhYUzVyUlJIR3hYRmxzWm9HWDR0RTRYOWJlckUzdWN3a2QvUjdNTitlZndLejdPaFVCSGxVYWMzaittNkxCZVFWaldUUGNSR1BMTE9RPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6ImEyMTAyNTczOTMwZmM4MmEyMzg5MDk0Y2RjMWEwM2ZmIiwiTWVzc2FnZUlkIjoiODRiYWIzYTEtNmQxNy00YjM2LTgyODctMTg5MTkxYTBlMjhiIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJ4cDZXSjUzellNSjNHd1FHUlk1OFhZS2YySzNPOFhORVQwZi9UY1JBcWZ4aHBheCtmeVB2aG5DLzJqRXh6SWhNd0FJbXlpWXVjbzJlS1pXYWlpSWxTekc1bFhmTnpBVVI5MlBlOHZZaU03V0prZERzY3MzQ0I2SE9LR2hHUUIxODc3OEtEUWRacjluQ3A5KzJOR1duZDg5dkpEa2V5eTAzRGR1YTByVlpGbG5BSm81NU4zckZCcWt1SXhSdnh0R3UvN2xwOE9oRmVWSExaV1RjVjJVcFFEeng4bVdnaTRmQXpFc21admVoeWFkaTRQRm14ZEZ3T0Z0bFNpV0kxVGI5TWw2U3I2d09EeVpvRnFweUlYUDBqbllqUURJRkJ6cmN4SlNnRW5RbzZ5ck9QNUdDZ2x0ZkFRNzFWR1hZNENwRktVcDk5Mnp3R1pZeGhOQjJoY3JWL3IveVIxVjZOUGxBRmhIQS9ZK0NDMEsrQmdGZHpwU1dROEQxUlNrNXVCZU9nMDMrVlVrbWhKbTNCVytxcG5YeU9nPT0ifV19" + } + }, + { + "ID": "645c34d8f483a32d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1704" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "974bdfd4-d47a-50fe-9375-bf2014bca3ee" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzMDQyMiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI5Njc1In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiMDFmNzI1MzEtZmFkNy01OWM5LTkyYzktNDVjNTNhMTIzMzYwXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0JhdGNoaW5nLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjA5LjYzN1pcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiS05FU01nUTFBcHBFd3R4TENwZDRHZFFoejNRQmJtWkhwMmRoOU5LNlA5QkVYYWl1Q2l2ZVY3TzJ0NlZRNC9sZTBESEJZRFBkenY3MVdzd0paRVY5cE9VZFZ3bkFNVk1oMktmUG9DVlpJVG9zUzEzUVFXVmNXYUVtWC84b1ROL001RkNPVCtHL1BJTWRBVTNENzJYUkpNdVJEV2tNU3IweXVndGxma0pYbjlDYmZTeFRBcE9QNHVIRE0zU0xvM1prUUVxK0N5NTRNMEJ3VGpZZ3FMTGR5T3lsWSsvZzFuN0Q1QnMxZnowa01FK2pzNWtCWEhNVWFIazVyL1U5cG1PUS9ZNzZjbStpdGlGUWtzODU3alVZeGVWTGhBYzBuZXpwaWFXUXhPcUlhckxqUys0TmJDbmxaMTdnRmRYUnlTZDJER3M2RjIrcTFKTmlEWXZkT1owckN3PT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNCYXRjaGluZy10b3AtMToyYjM0ZjYyYS1kMzdhLTRjZWEtOGZmMS00OWJkMzFkZjdmMDRcIlxufSIsIk1ENU9mQm9keSI6Ijk1NGZmZjVlYTU5OTNiZGE2YTkxYjRjYmM1NGE1MWM2IiwiTWVzc2FnZUlkIjoiOTBlMGIzNTUtNmYzNC00MTE3LThlM2ItZTUwNTBlOTRlYjhmIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUI2d2RHemErRWgwYnlIcVlWWm5jK2Q3ZHRjZlVMNmpwUDQ5dkhkRWFNL2lEWnp1QzJxSXcwMkkzT0hNU1l4aEozUGFCazE5OGxmck5jbm9VeE9WekptWFg0WkMyV0lqRzJ0Qzhsc1p3YjQ3eWYyaTd3VUl6clpRaXBKQWRjVUM3a0ljdllHWWE3YlhrOTBoT0M5ekxHUlpGdzlyeG5LdWYrZmRIS21lUHk0M0ZXNG5jc0d4VTIvcVd3dmZXRlRJQ0pnWlFBVW1IbU1DQ0J4cUloRWVFVXh4d0NsOENtZzIvaGZBR3hYcFVLNEV0c0VyeHRYLzVrenBOVEdKYlJxdUxJTGhrV3JMOVA0UFYyZFZNZ2dNSVlTbHgxdFhuNkdOQ3oyTUFmaW83ak1PT2dnUk8rWFpWYi83cWtpU3N3dnhuek9iOHhRMkRnT04xZVF0U1BpbVlDK01RZ0xYL2ZwYmU3WkM3MXNzZEhQdFphU0RraDVJZ29qbnlhNVdZQk10TkdRQXpPSnduUkwrTWZ1RzkyNVpUcTNnPT0ifV19" + } + }, + { + "ID": "cdd29f25ca62d562", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2750" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnJ1b3pwbDU4NEZTd1RMc3V1UTNEdTM3L1FiWjlrMUZ6eUlmYmt4clY5emVSSk5ORndWa3ViUlBLaXAzeUc4MGRlVFd0QVA2OW9odG9MOTU4TVcwZUhqQW1ZeEIvRzdtdzMrVmptNHEveW9iSFA0NTFPRXhaRjBVbjhMSWNUQ0IwVmhTTERWRGFmWXNqeGRyMzFkTDh2ckpTWXdiSWVMTnpyZmVlY3ByaGJrQVZISFlna0tBMWVwWlo5T2k1TWRGdGlKWlAwUFIySUNJK3ZTOFVwZG9NNDlCWWZoVXJOMWhQUTd0QmwvSmZvVU9xNWk1V1ExcUZ4dS9Xc2dyTnlTK0VtQm5HbXhjT3JpQlpyVjFHMGJSWW5GK0czYUlVWHhKOS84YjRZdytKWVlEUkhwTVRSZktFdnBnYXp2RWxibDUyMnZKNE54VFFDVFVkd09ZRk1xWFM5algwL1huTi9ETXl5M0xITDhDcnRyaFZRay8yYmhseHUrbUczWmhseFpNSmF2K1YvOUVNbW5OU3MzbW40VStrOWc9PSJ9LHsiSWQiOiIxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJKQmxzRGFFcUxjcmxzWXNtUm9RWHFQR3Z5L3kwVHZGVlRkMitsNlNOZUdiTEV2Qit2MGNTT3pjSmZ4Q3hwSTAvUGFLbGZWM0QxcXlubStnRkNHSGlXTW9lWXl4Q0xRWmFDUkxVMEYvZEFTY2JVL3dUbDZqTlFPMlpYWXAxU3c2dXJhZ1A3TnFJTVlWZjgwTnNMMGR4VWEzaXhYSk9CZWxOTnI0YTdJQnEyakFWNGp3aU1pb2xOWmdIK0NxL0hpRkx2OHU3UitTSkdoVWYvdjhwNGxkWXRZNzdZcFR1cnlHOUo0UjBNL2xLN01kK2FpeWZ1YUREd0dSZjU3K29LQW04b3czVFhaRzlIZEJGeHJWNW5uYmRPSkdHVlJKLzVFa25JTHpvYm1lVXFmYnNRZTUxMFhzaEU5QVNjVUJ2dCtPaG41MFgyUnduaXg4SlZBTEhHbitOQXN6cVV0MHFDcWZMb0haTlhqelNoeFRhN00zN1lzNk0yUUlxSDJ1Ujl2bWFTTVlQb245VnZXZzR6U0JYR1hBcVFnPT0ifSx7IklkIjoiMiIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCa3ozMnZEbVNYYll2UXgrVjdwcTI2NHp3RWlIMnQ4dG5aaEIrNWNWOTBlR3d2UytRSmJpTkdhdlJkS2drMW5DemY2N1FzeEZLQ3o3bUR1NzNaV3MrdHI4V2VYRVAxa0l1UC84WXN2MDB2TnduRW0yUzFGOXhzOXB5WVhHVE5OWnJzRzluUzNPZldhSTMxK200eGlPUlRhbGVYSWY0OGpKNVpwUnp3K21wS2JJY3BlMUxOK0VuK1QxR3hqN2N2Y0dvR1JlcGNaYTY3RFhMOVlPNERqZDZGQmwxMXZ6UEZGU2ZKMzRocmExL1RmUG9ERnI1aE9kcTAxKzBRM3h3dlNSMndrOVN6QzJsMEdrbWROV3dyaDRocDFmeURCK3pEaXdWYlJQMnF6Z3Zwak9KZmpYa2JPWmE0VHVIQys4N2wrQlFtQlY4YmU1eGNLc2Z1cGE3WURBTENkNEpwUkJnTmRJUmhkb1IvNVRPNjJZZjhMbEJxYjgvQUpSSUVyT2VrUXZSYllzQUZLTDBKMDNzbE1NRU5Gc2tjQT09In0seyJJZCI6IjMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkliN1hvTGZvMCt2VFl1MUdjQ2lqZCtZYjJWUC8zMDlLVEFXVklFVTlNb0JEMWhyME83WHp6N0xpcEp5NHVxTVdSSVUwSUpGRGVOeDd6N3BRTHkzVXJ0aE92aG1HemkwTkcreXFpb2tlU1B5Ris5TmZBeTdSUHVkZ0YvTVZ1QUt6aHBDTUVWL2M2YkJsMG5hcDZEWER1TkxMblkzemRuU2JxZjlIYXR1Y0tXclBKd1l1d3NFOXIrM2tZdUViVm90WEV2djY2UHVSKzZIUmhSclptRFcwQVY3YSttaXhTZktsNEh0a3JJaFZQZU8zbVBUOEVGWUdTd2UzRC9JK2UxYVhBOUM4RHJQdlBUL1FBV0xQNHJxOWlCbGFFV3U1YkhhMWRQRjJZbVhQd2RjVmI4eGVhU1JocW1PTm9LdmkwVWtxRFEvNzNpQllQSHprSHI1Y1BDUnJQYjM1MTJiR09URzgrNTJIOWlTOXN1aWdxQ3pJRjdTL1VlWlhLdHBTMVRJeXdORXBtby80QzVXK0xObVUxem5Nanc9PSJ9LHsiSWQiOiI0IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJ4cDZXSjUzellNSjNHd1FHUlk1OFhZS2YySzNPOFhORVQwZi9UY1JBcWZ4aHBheCtmeVB2aG5DLzJqRXh6SWhNd0FJbXlpWXVjbzJlS1pXYWlpSWxTekc1bFhmTnpBVVI5MlBlOHZZaU03V0prZERzY3MzQ0I2SE9LR2hHUUIxODc3OEtEUWRacjluQ3A5KzJOR1duZDg5dkpEa2V5eTAzRGR1YTByVlpGbG5BSm81NU4zckZCcWt1SXhSdnh0R3UvN2xwOE9oRmVWSExaV1RjVjJVcFFEeng4bVdnaTRmQXpFc21admVoeWFkaTRQRm14ZEZ3T0Z0bFNpV0kxVGI5TWw2U3I2d09EeVpvRnFweUlYUDBqbllqUURJRkJ6cmN4SlNnRW5RbzZ5ck9QNUdDZ2x0ZkFRNzFWR1hZNENwRktVcDk5Mnp3R1pZeGhOQjJoY3JWL3IveVIxVjZOUGxBRmhIQS9ZK0NDMEsrQmdGZHpwU1dROEQxUlNrNXVCZU9nMDMrVlVrbWhKbTNCVytxcG5YeU9nPT0ifSx7IklkIjoiNSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCNndkR3phK0VoMGJ5SHFZVlpuYytkN2R0Y2ZVTDZqcFA0OXZIZEVhTS9pRFp6dUMycUl3MDJJM09ITVNZeGhKM1BhQmsxOThsZnJOY25vVXhPVnpKbVhYNFpDMldJakcydEM4bHNad2I0N3lmMmk3d1VJenJaUWlwSkFkY1VDN2tJY3ZZR1lhN2JYazkwaE9DOXpMR1JaRnc5cnhuS3VmK2ZkSEttZVB5NDNGVzRuY3NHeFUyL3FXd3ZmV0ZUSUNKZ1pRQVVtSG1NQ0NCeHFJaEVlRVV4eHdDbDhDbWcyL2hmQUd4WHBVSzRFdHNFcnh0WC81a3pwTlRHSmJScXVMSUxoa1dyTDlQNFBWMmRWTWdnTUlZU2x4MXRYbjZHTkN6Mk1BZmlvN2pNT09nZ1JPK1haVmIvN3FraVNzd3Z4bnpPYjh4UTJEZ09OMWVRdFNQaW1ZQytNUWdMWC9mcGJlN1pDNzFzc2RIUHRaYVNEa2g1SWdvam55YTVXWUJNdE5HUUF6T0p3blJMK01mdUc5MjVaVHEzZz09In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "82" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "4a8d434e-1fa2-512b-b473-23badf64d23b" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjMifSx7IklkIjoiNSJ9LHsiSWQiOiIwIn0seyJJZCI6IjIifSx7IklkIjoiMSJ9LHsiSWQiOiI0In1dfQ==" + } + }, + { + "ID": "0dd3e87e1aad6777", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "160" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0JhdGNoaW5nLXRvcC0xJTNBMmIzNGY2MmEtZDM3YS00Y2VhLThmZjEtNDliZDMxZGY3ZjA0JlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "d96ea855-2acd-53e2-9a51-c8a1ea0b994b" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5kOTZlYTg1NS0yYWNkLTUzZTItOWE1MS1jOGExZWEwYjk5NGI8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "aaa8e70f52a46837", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "86" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "3207f5b9-3037-5d41-b094-954df0f19e51" + ] + }, + "Body": "" + } + }, + { + "ID": "2a2b5f906aa71d7e", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "114" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljQmF0Y2hpbmctdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:10 GMT" + ], + "X-Amzn-Requestid": [ + "02605619-bd44-5962-8661-36ed7d8263cb" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4wMjYwNTYxOS1iZDQ0LTU5NjItODY2MS0zNmVkN2Q4MjYzY2I8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestCancelSendReceive.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestCancelSendReceive.replay new file mode 100644 index 000000000..5d6fd375c --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestCancelSendReceive.replay @@ -0,0 +1,487 @@ +{ + "Initial": "AQAAAA7gDLV7Ogv6KgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "32765377f88a6b0e", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "74" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNDYW5jZWxTZW5kUmVjZWl2ZS10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "338" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:00 GMT" + ], + "X-Amzn-Requestid": [ + "63c60cc1-27f6-581f-b0ef-6c35e74a0177" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQ2FuY2VsU2VuZFJlY2VpdmUtdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjYzYzYwY2MxLTI3ZjYtNTgxZi1iMGVmLTZjMzVlNzRhMDE3NzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "d5e934fe7cc26594", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "47" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "95" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:00 GMT" + ], + "X-Amzn-Requestid": [ + "e4ff29aa-9e93-5416-aed7-495e5e2fa0a3" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn0=" + } + }, + { + "ID": "b9b19de1837f5cbe", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "125" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:00 GMT" + ], + "X-Amzn-Requestid": [ + "a70a00cd-0df1-5b5d-ac0f-6039cd4dcfe8" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn19" + } + }, + { + "ID": "3b4df2119556b02c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "476" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQ2FuY2VsU2VuZFJlY2VpdmUtc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:00 GMT" + ], + "X-Amzn-Requestid": [ + "49b61687-61f9-5fb2-81d4-7673a145eb07" + ] + }, + "Body": "" + } + }, + { + "ID": "300f2533eb628382", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "220" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "381" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:00 GMT" + ], + "X-Amzn-Requestid": [ + "2061b7cf-b21a-5aa9-9ab5-d73b72a663c1" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljQ2FuY2VsU2VuZFJlY2VpdmUtdG9wLTE6M2FhOGM5MGEtMzdhMS00NDY2LTk4MWEtMTkwMDdjMTY1ZTg3PC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjIwNjFiN2NmLWIyMWEtNWFhOS05YWI1LWQ3M2I3MmE2NjNjMTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "d1708fed05191cae", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "169" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXRvcC0xJTNBM2FhOGM5MGEtMzdhMS00NDY2LTk4MWEtMTkwMDdjMTY1ZTg3JlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:01 GMT" + ], + "X-Amzn-Requestid": [ + "fa5ec458-b77f-590a-8e21-a4ac77c3f062" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5mYTVlYzQ1OC1iNzdmLTU5MGEtOGUyMS1hNGFjNzdjM2YwNjI8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "348581572b5588a4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:01 GMT" + ], + "X-Amzn-Requestid": [ + "d7057153-183d-5f17-8331-11a7d8802ba2" + ] + }, + "Body": "" + } + }, + { + "ID": "d47f082e95f4be8f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljQ2FuY2VsU2VuZFJlY2VpdmUtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:01 GMT" + ], + "X-Amzn-Requestid": [ + "171fb6fe-a2c3-57fe-8985-d60a627e2e96" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4xNzFmYjZmZS1hMmMzLTU3ZmUtODk4NS1kNjBhNjI3ZTJlOTY8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestDoubleAck.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestDoubleAck.replay new file mode 100644 index 000000000..42fc035a3 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestDoubleAck.replay @@ -0,0 +1,1165 @@ +{ + "Initial": "AQAAAA7gDLWMHMjdlQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "3832090e5633b3a1", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "66" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNEb3VibGVBY2stdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "330" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:16 GMT" + ], + "X-Amzn-Requestid": [ + "191afc64-cb4f-52ab-b9d0-9c900b83f965" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljRG91YmxlQWNrLXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4xOTFhZmM2NC1jYjRmLTUyYWItYjlkMC05YzkwMGI4M2Y5NjU8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "60d088df1debac44", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "39" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "87" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:17 GMT" + ], + "X-Amzn-Requestid": [ + "1a494c42-2a51-542e-8042-2cb6ea9c53e0" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9" + } + }, + { + "ID": "ba7115bd3eafb2f3", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "117" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "88" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:17 GMT" + ], + "X-Amzn-Requestid": [ + "5fb1d49c-7ef0-587c-8e6f-b468be3d7fb2" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9fQ==" + } + }, + { + "ID": "31355d4b23a06dbf", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "460" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljRG91YmxlQWNrLXN1Yi0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNEb3VibGVBY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:17 GMT" + ], + "X-Amzn-Requestid": [ + "4aabc7ad-fc7c-51b5-9fef-a7593cb1a67b" + ] + }, + "Body": "" + } + }, + { + "ID": "d4a66a5da0c02d8a", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "204" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0RvdWJsZUFjay1zdWItMSZQcm90b2NvbD1zcXMmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBU05TVG9waWNEb3VibGVBY2stdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "373" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:17 GMT" + ], + "X-Amzn-Requestid": [ + "65ed9177-1841-55dc-a00e-f183d88c1e12" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljRG91YmxlQWNrLXRvcC0xOjIyMWZlZTUwLWNmNWQtNGJmOS05Yjc1LTE5YTA4OTIxYTkwZjwvU3Vic2NyaXB0aW9uQXJuPgogIDwvU3Vic2NyaWJlUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD42NWVkOTE3Ny0xODQxLTU1ZGMtYTAwZS1mMTgzZDg4YzFlMTI8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvU3Vic2NyaWJlUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "97d0034948af4ec6", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "203" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0RvdWJsZUFjay10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:17 GMT" + ], + "X-Amzn-Requestid": [ + "dead2204-d025-56d0-9bc2-42f010e8dd1e" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjcwN2ViMzVmLWY5MTUtNTY2Yi1hNDAxLWQzYWIzOWQ4ZmRhNTwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmRlYWQyMjA0LWQwMjUtNTZkMC05YmMyLTQyZjAxMGU4ZGQxZTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "b27fef9120dd94d3", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "203" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MSZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0RvdWJsZUFjay10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:17 GMT" + ], + "X-Amzn-Requestid": [ + "50ef1d5f-869b-5abb-99cc-7dab4656d175" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjkxYzI3Y2M5LTdkYjktNWVlMi1iMjQ3LTFjM2RiZDc0NDUyYzwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjUwZWYxZDVmLTg2OWItNWFiYi05OWNjLTdkYWI0NjU2ZDE3NTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "89235504b85975a9", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "203" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MiZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0RvdWJsZUFjay10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:17 GMT" + ], + "X-Amzn-Requestid": [ + "fc37bcb2-2f68-557b-814a-dc46efa51eb5" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmIzNmU0ZmViLTVlYmItNTcxMS04Yzc1LTJmMWY5ZTc2N2NkZjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmZjMzdiY2IyLTJmNjgtNTU3Yi04MTRhLWRjNDZlZmE1MWViNTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "5b999f495066dfb0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MywiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "3378" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:17 GMT" + ], + "X-Amzn-Requestid": [ + "2617922c-42c6-525e-b963-f2d8820b2590" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzNzg5NSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjM3NzM0In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiNzA3ZWIzNWYtZjkxNS01NjZiLWE0MDEtZDNhYjM5ZDhmZGE1XCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0RvdWJsZUFjay10b3AtMVwiLFxuICBcIk1lc3NhZ2VcIiA6IFwiMFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjE3LjcwMFpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwibUdUZlRaTWFna1VNWjRaUFlwb1RiZkNIdmp0SmswczRyeHYxOUNURUZ1TkJvay81WDF0VDVsYmhSWUN5a0Mrd0FyTjM0VzRPWlo5VTRvb3cvUGpTZENkMmJEb1pWL0lIQmRWUDI0YllYQlZ4bDhPeFJDRXliUmk1a0ZoMSs1S1FUOGcybE5SbW1maGxjN2hBVkdGMVUzZVBhUnlGaitmSlNjeHFFdlArZThxMzR3SU94L1kySEVYdEs5Yk50TlJibUVZYUlsc2RCTGl5c2hKZzNadWRLRzY2VGJEVVF1VEVycDA5d3lJSWYxS2N2Y2pVVlcyam5ObXUyVjE2Rkdxb0Zvd3ZaUDE5enlnSmxtMlZxN0lZeHRSZ0tWemEzVTBzc0RlZ1kwbGpZeUpwSXRLOVg0eTQwYll3RG90cUdkYTNDQWZ1YkUvOE9lR2hXRnBkcVkxRzd3PT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNEb3VibGVBY2stdG9wLTE6MjIxZmVlNTAtY2Y1ZC00YmY5LTliNzUtMTlhMDg5MjFhOTBmXCJcbn0iLCJNRDVPZkJvZHkiOiJmMTAxNjc3NzAzNDk1MWVjMGFjY2JkMGYyMGE3ZDU2MCIsIk1lc3NhZ2VJZCI6ImMwZTYzMGYxLTA3NjQtNDEwYS04NWNmLTc4ZDBiZjIyZjliOSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCQUtweFU3QjF4aDVDQkQ5a2R2dVlCWFBjUjdXUHlqVFhOanlhVXRSWi8vRFFoSEQ2YThBUjlaUTE0ZUxvQTRRSG9pc095SVlRK3Z0amdKT0lMN3BZcUUwVnNEY0Z1Z2IxaE1XOVFHVmxwZlhway9DV1gzY3lVbzJRTGlCT3dJWkRTelMwL2p1S2RlR2xIcTExV0pSakg4bnhaeVlhaGljODI3M3k3M0NPU00vTUcyeUhJUXYrRm9ha3UyRlBMZkxBVEFEYlJxYzU2aXMvU1ZTaFZiRXNJTE1idzNCMDJPeWlza3cwU3V6Y3l6NU1zOVRybGR6cW4zT0p5NkdXNnlYVHE4cU9adXhlSGp0Z1lNZ3hDeXNvbS9GVUxqTnZkdStjUFljN3ZGLzZPeUJEK1JzSTdNS1Nhc0lLZEVCTytpdVdEa2JYQllEU3lmTHZYVTBXZUtOZzdxSDdTalphc0lvMVZ1c0F3NzkzdjYyWVJPdm5SSlA5cisvNVNFN1NQMlJrTzMrSHJJNW52ZDBISmlSa05JSVZxZz09In0seyJBdHRyaWJ1dGVzIjp7IlNlbmRlcklkIjoiQUlEQUpRUjZRREdRN1BBVE1TWUVZIiwiQXBwcm94aW1hdGVGaXJzdFJlY2VpdmVUaW1lc3RhbXAiOiIxNzUyODc0NjM3ODk1IiwiQXBwcm94aW1hdGVSZWNlaXZlQ291bnQiOiIxIiwiU2VudFRpbWVzdGFtcCI6IjE3NTI4NzQ2Mzc4NTAifSwiQm9keSI6IntcbiAgXCJUeXBlXCIgOiBcIk5vdGlmaWNhdGlvblwiLFxuICBcIk1lc3NhZ2VJZFwiIDogXCJiMzZlNGZlYi01ZWJiLTU3MTEtOGM3NS0yZjFmOWU3NjdjZGZcIixcbiAgXCJUb3BpY0FyblwiIDogXCJhcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljRG91YmxlQWNrLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCIyXCIsXG4gIFwiVGltZXN0YW1wXCIgOiBcIjIwMjUtMDctMThUMjE6Mzc6MTcuODMwWlwiLFxuICBcIlNpZ25hdHVyZVZlcnNpb25cIiA6IFwiMVwiLFxuICBcIlNpZ25hdHVyZVwiIDogXCJoVDh2R3ByQVA5Mm1uazRaOCtBbkoxUDdXZWdaMG1haTBnbkpJWURqb3lkbEhxSWV4c3FWYVZseFRBRFRaWlh1eTZJYzBkeTg5cC9zY2xveitlY3NibjUzU052SUNBQ0dNK25VdXlSZmpKdGVaWjdMVVFRdnFrajZlMk1mRFBYei9VL3FCUjJGRCt5RmdVR09yVWhEY2YvTTBvZTA4S3Zmd2VSWG8xQ3dwcitqdnVra1RvanRtQWZpdmJpbmJEZ0JzdW1oanhRMzRFdVZpL1J1YW45M0s5Y2pvNVI4NEY4WHVscG53amlKdkJQNTRBR3V3RWFmY29Ia0ExY1lIYTlUK1Ivb0VGeVVTVWFtR1hRZXh6T0pqM3pmRDlhTlRCYnFiVmVybk5yelVWZEtjZG1HR3hXMUhySHlhcTJKSkwwNERnSlVJU1p2Q0ZaQ1JZNG1kOWlQTHc9PVwiLFxuICBcIlNpZ25pbmdDZXJ0VVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL1NpbXBsZU5vdGlmaWNhdGlvblNlcnZpY2UtOWM2NDY1ZmE3ZjQ4ZjVjYWNkMjMwMTQ2MzFlYzExMzYucGVtXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0RvdWJsZUFjay10b3AtMToyMjFmZWU1MC1jZjVkLTRiZjktOWI3NS0xOWEwODkyMWE5MGZcIlxufSIsIk1ENU9mQm9keSI6ImQ1MTU4YTJhZTkxZGZmM2E3NTg1ODllYWI5NGE3YmMyIiwiTWVzc2FnZUlkIjoiOGVkYTMxYzUtYjAyYi00NmQ5LWJkODctZTUzNGVmNWIxN2IxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJIV0ZwU04vMVdkdnlSbzhhc2ZhZHFvdzRpQ1ZsckdpRk4ySkZ6RHMvdXJSRExEQVRGcDJ1U1JUbjdKeEx2YjIvblVrNzRhZXpZUmNFS253UmRUaHRHaHI4cTQ3QVcxMVZLamZJZW1SUDd2YTdDcXpCYTdwMDI5S0hvRzdpZGF5UUVhMHZwa2l3V3FtMjRwWFNkSG1mL0NqMGpRVkZBQkZxb3pqMTVrMmgyaG1IbEFhMm8xMXNaemNDdU5USWUyelY0OG9rSXJhbUk4NmpIbm5sa1lCREVSZk02TndwdlpOcDBGMTRFNHFiZk9Ocm1DM043SzlOem9LZnRDM1FTb1VJSk1icGNTckovQmhuWlRBVXpndUlneE1EckZCalZ0amNQbmNvTnNFQ2RXQ05JQVhhYXozcHphNU9sWjhxSmpORE5kM283YjU1SW16emJ1RysrUTB6aVBTU04ybUZkb0s1L0Q5NmNCWU5WUmcxN0FNb3k3dlVGZ1EwTlV6TXVuNGxIYk9tTmJMN2ordmI3bVVWT0VkYkhRPT0ifV19" + } + }, + { + "ID": "39ca539579577d9d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MywiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1696" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:17 GMT" + ], + "X-Amzn-Requestid": [ + "2c30b093-035c-563a-a93b-d067c39181f4" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzNzk1NCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjM3NzkzIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiOTFjMjdjYzktN2RiOS01ZWUyLWIyNDctMWMzZGJkNzQ0NTJjXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0RvdWJsZUFjay10b3AtMVwiLFxuICBcIk1lc3NhZ2VcIiA6IFwiMVwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjE3Ljc2NFpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiSUdNZ1E1c1prWkV4VFBtN0RXUnRvVUtFM21PaWRWbFVlZmJsb0dpMU1DL2tIbXA0NkJsUExqd3Noeng0Wm53dzVZcGF1RGlvTCtnN1VNOExsTFdOS1h5MzBRRUtxRlBUQ0dMdElNRmY3VWxDUDMzSHdMZHJqS2F5cTRnOXRLeGYvZWVDNEM0Ri8rWjJlY0dQeEhlemZqVnBCcG9pZFhEK0JuT2M4UEZLVE11dDVZY0p5YTBKem5NTVhUVCswSlZOYlhJQ0FqS1VBVkxSZFRSRElFaGU4bEo4RTNBOGhvQ3craEFoSnJLSUFUVTFJWDNha25IZ3JIVlRUeHdNL3NaZllrZ1VNMzBZbi94VXdUanpkeTFpaG11YXJOek54SnFWa2VIOXFyR3cvamxpWjZmS0NvNHdtVHZhMkZwb1pHQjNIajZyUHlodXdYYXBtWnN2SlBibVZBPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNEb3VibGVBY2stdG9wLTE6MjIxZmVlNTAtY2Y1ZC00YmY5LTliNzUtMTlhMDg5MjFhOTBmXCJcbn0iLCJNRDVPZkJvZHkiOiJlOGM1ZGIyNjU3YzAyOTQxYzc5NWEzNTFkOTk5OTc5OSIsIk1lc3NhZ2VJZCI6ImEzZTQ2MTVkLWJkZGItNGVkMy1iNDAyLTI3NzJkMDNjYmZmYSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCTzA2dXpJZkliRG9XanVqcDR3bUNlVWhHYm9IbC9lS3Q2bEd3aFVRYTR0T3QwZGpTZytlZEVxMXFjcEZiZGtvOGhBdXlobkZGVzAxTFMwMzJ0TitsZXZ2WjRWR1kwa0VIRk82WGRQcFA0QmVCOXd3Zi9jQ2kvRy9SQk9aVHZNd0VMMmZsU2JWQnlMT0ltNWVrbEZBVTdmMWMvVU5EOFBwSUF5K3REUmJkZGM5MWMvbE5HQVQ4Mkx3eHBQVVhtM09uekJkbklCdHlkdTlXU1VMa3BiMVJHa1RoMWt2SC9keHg3enNnVEZ4QktpT3N1TGhOMnYxbENTRnlBZXB1RGV4Y0ZGVlpja1o5cnhvZ2JYVEtldlJZTVJBMUlKV0pJQ0kxamRMeVZDNEFGaUk2UVBOMnZ2V0hxeEZvdnd5VXRqNzRDVlk3NUdpN1l3V2xBbHowTzQvZFlRZ3VYZWc1Z0VndmI4cVN3UTlOMDQrem9yMy9QOHRNWmgrNmRuTG11dzhuTXRKQ0trOWNEWk1zRDNMQ2VzZ2xZZz09In1dfQ==" + } + }, + { + "ID": "6efec29151e1ded2", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "983" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkFLcHhVN0IxeGg1Q0JEOWtkdnVZQlhQY1I3V1B5alRYTmp5YVV0UlovL0RRaEhENmE4QVI5WlExNGVMb0E0UUhvaXNPeUlZUSt2dGpnSk9JTDdwWXFFMFZzRGNGdWdiMWhNVzlRR1ZscGZYcGsvQ1dYM2N5VW8yUUxpQk93SVpEU3pTMC9qdUtkZUdsSHExMVdKUmpIOG54WnlZYWhpYzgyNzN5NzNDT1NNL01HMnlISVF2K0ZvYWt1MkZQTGZMQVRBRGJScWM1NmlzL1NWU2hWYkVzSUxNYnczQjAyT3lpc2t3MFN1emN5ejVNczlUcmxkenFuM09KeTZHVzZ5WFRxOHFPWnV4ZUhqdGdZTWd4Q3lzb20vRlVMak52ZHUrY1BZYzd2Ri82T3lCRCtSc0k3TUtTYXNJS2RFQk8raXVXRGtiWEJZRFN5Zkx2WFUwV2VLTmc3cUg3U2paYXNJbzFWdXNBdzc5M3Y2MllST3ZuUkpQOXIrLzVTRTdTUDJSa08zK0hySTVudmQwSEppUmtOSUlWcWc9PSJ9LHsiSWQiOiIxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJIV0ZwU04vMVdkdnlSbzhhc2ZhZHFvdzRpQ1ZsckdpRk4ySkZ6RHMvdXJSRExEQVRGcDJ1U1JUbjdKeEx2YjIvblVrNzRhZXpZUmNFS253UmRUaHRHaHI4cTQ3QVcxMVZLamZJZW1SUDd2YTdDcXpCYTdwMDI5S0hvRzdpZGF5UUVhMHZwa2l3V3FtMjRwWFNkSG1mL0NqMGpRVkZBQkZxb3pqMTVrMmgyaG1IbEFhMm8xMXNaemNDdU5USWUyelY0OG9rSXJhbUk4NmpIbm5sa1lCREVSZk02TndwdlpOcDBGMTRFNHFiZk9Ocm1DM043SzlOem9LZnRDM1FTb1VJSk1icGNTckovQmhuWlRBVXpndUlneE1EckZCalZ0amNQbmNvTnNFQ2RXQ05JQVhhYXozcHphNU9sWjhxSmpORE5kM283YjU1SW16emJ1RysrUTB6aVBTU04ybUZkb0s1L0Q5NmNCWU5WUmcxN0FNb3k3dlVGZ1EwTlV6TXVuNGxIYk9tTmJMN2ordmI3bVVWT0VkYkhRPT0ifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NOU1RvcGljRG91YmxlQWNrLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "38" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:18 GMT" + ], + "X-Amzn-Requestid": [ + "85a293ac-e4e2-5d7b-9376-f358242cdab5" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifSx7IklkIjoiMSJ9XX0=" + } + }, + { + "ID": "354246537a4c4323", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "983" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkFLcHhVN0IxeGg1Q0JEOWtkdnVZQlhQY1I3V1B5alRYTmp5YVV0UlovL0RRaEhENmE4QVI5WlExNGVMb0E0UUhvaXNPeUlZUSt2dGpnSk9JTDdwWXFFMFZzRGNGdWdiMWhNVzlRR1ZscGZYcGsvQ1dYM2N5VW8yUUxpQk93SVpEU3pTMC9qdUtkZUdsSHExMVdKUmpIOG54WnlZYWhpYzgyNzN5NzNDT1NNL01HMnlISVF2K0ZvYWt1MkZQTGZMQVRBRGJScWM1NmlzL1NWU2hWYkVzSUxNYnczQjAyT3lpc2t3MFN1emN5ejVNczlUcmxkenFuM09KeTZHVzZ5WFRxOHFPWnV4ZUhqdGdZTWd4Q3lzb20vRlVMak52ZHUrY1BZYzd2Ri82T3lCRCtSc0k3TUtTYXNJS2RFQk8raXVXRGtiWEJZRFN5Zkx2WFUwV2VLTmc3cUg3U2paYXNJbzFWdXNBdzc5M3Y2MllST3ZuUkpQOXIrLzVTRTdTUDJSa08zK0hySTVudmQwSEppUmtOSUlWcWc9PSJ9LHsiSWQiOiIxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJIV0ZwU04vMVdkdnlSbzhhc2ZhZHFvdzRpQ1ZsckdpRk4ySkZ6RHMvdXJSRExEQVRGcDJ1U1JUbjdKeEx2YjIvblVrNzRhZXpZUmNFS253UmRUaHRHaHI4cTQ3QVcxMVZLamZJZW1SUDd2YTdDcXpCYTdwMDI5S0hvRzdpZGF5UUVhMHZwa2l3V3FtMjRwWFNkSG1mL0NqMGpRVkZBQkZxb3pqMTVrMmgyaG1IbEFhMm8xMXNaemNDdU5USWUyelY0OG9rSXJhbUk4NmpIbm5sa1lCREVSZk02TndwdlpOcDBGMTRFNHFiZk9Ocm1DM043SzlOem9LZnRDM1FTb1VJSk1icGNTckovQmhuWlRBVXpndUlneE1EckZCalZ0amNQbmNvTnNFQ2RXQ05JQVhhYXozcHphNU9sWjhxSmpORE5kM283YjU1SW16emJ1RysrUTB6aVBTU04ybUZkb0s1L0Q5NmNCWU5WUmcxN0FNb3k3dlVGZ1EwTlV6TXVuNGxIYk9tTmJMN2ordmI3bVVWT0VkYkhRPT0ifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NOU1RvcGljRG91YmxlQWNrLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "38" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:18 GMT" + ], + "X-Amzn-Requestid": [ + "b61c09a3-134e-509b-9b07-6957d3801755" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifSx7IklkIjoiMSJ9XX0=" + } + }, + { + "ID": "2646d136898b33b4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "1491" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ChangeMessageVisibilityBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkFLcHhVN0IxeGg1Q0JEOWtkdnVZQlhQY1I3V1B5alRYTmp5YVV0UlovL0RRaEhENmE4QVI5WlExNGVMb0E0UUhvaXNPeUlZUSt2dGpnSk9JTDdwWXFFMFZzRGNGdWdiMWhNVzlRR1ZscGZYcGsvQ1dYM2N5VW8yUUxpQk93SVpEU3pTMC9qdUtkZUdsSHExMVdKUmpIOG54WnlZYWhpYzgyNzN5NzNDT1NNL01HMnlISVF2K0ZvYWt1MkZQTGZMQVRBRGJScWM1NmlzL1NWU2hWYkVzSUxNYnczQjAyT3lpc2t3MFN1emN5ejVNczlUcmxkenFuM09KeTZHVzZ5WFRxOHFPWnV4ZUhqdGdZTWd4Q3lzb20vRlVMak52ZHUrY1BZYzd2Ri82T3lCRCtSc0k3TUtTYXNJS2RFQk8raXVXRGtiWEJZRFN5Zkx2WFUwV2VLTmc3cUg3U2paYXNJbzFWdXNBdzc5M3Y2MllST3ZuUkpQOXIrLzVTRTdTUDJSa08zK0hySTVudmQwSEppUmtOSUlWcWc9PSIsIlZpc2liaWxpdHlUaW1lb3V0IjoxfSx7IklkIjoiMSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCSFdGcFNOLzFXZHZ5Um84YXNmYWRxb3c0aUNWbHJHaUZOMkpGekRzL3VyUkRMREFURnAydVNSVG43SnhMdmIyL25Vazc0YWV6WVJjRUtud1JkVGh0R2hyOHE0N0FXMTFWS2pmSWVtUlA3dmE3Q3F6QmE3cDAyOUtIb0c3aWRheVFFYTB2cGtpd1dxbTI0cFhTZEhtZi9DajBqUVZGQUJGcW96ajE1azJoMmhtSGxBYTJvMTFzWnpjQ3VOVEllMnpWNDhva0lyYW1JODZqSG5ubGtZQkRFUmZNNk53cHZaTnAwRjE0RTRxYmZPTnJtQzNON0s5TnpvS2Z0QzNRU29VSUpNYnBjU3JKL0JoblpUQVV6Z3VJZ3hNRHJGQmpWdGpjUG5jb05zRUNkV0NOSUFYYWF6M3B6YTVPbFo4cUpqTkROZDNvN2I1NUltenpidUcrK1EwemlQU1NOMm1GZG9LNS9EOTZjQllOVlJnMTdBTW95N3ZVRmdRME5Vek11bjRsSGJPbU5iTDdqK3ZiN21VVk9FZGJIUT09IiwiVmlzaWJpbGl0eVRpbWVvdXQiOjF9LHsiSWQiOiIyIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJPMDZ1eklmSWJEb1dqdWpwNHdtQ2VVaEdib0hsL2VLdDZsR3doVVFhNHRPdDBkalNnK2VkRXExcWNwRmJka284aEF1eWhuRkZXMDFMUzAzMnROK2xldnZaNFZHWTBrRUhGTzZYZFBwUDRCZUI5d3dmL2NDaS9HL1JCT1pUdk13RUwyZmxTYlZCeUxPSW01ZWtsRkFVN2YxYy9VTkQ4UHBJQXkrdERSYmRkYzkxYy9sTkdBVDgyTHd4cFBVWG0zT256QmRuSUJ0eWR1OVdTVUxrcGIxUkdrVGgxa3ZIL2R4eDd6c2dURnhCS2lPc3VMaE4ydjFsQ1NGeUFlcHVEZXhjRkZWWmNrWjlyeG9nYlhUS2V2UllNUkExSUpXSklDSTFqZEx5VkM0QUZpSTZRUE4ydnZXSHF4Rm92d3lVdGo3NENWWTc1R2k3WXdXbEFsejBPNC9kWVFndVhlZzVnRWd2YjhxU3dROU4wNCt6b3IzL1A4dE1aaCs2ZG5MbXV3OG5NdEpDS2s5Y0RaTXNEM0xDZXNnbFlnPT0iLCJWaXNpYmlsaXR5VGltZW91dCI6MX1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "332" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:18 GMT" + ], + "X-Amzn-Requestid": [ + "5cae5de7-3f0f-51d1-b248-3d13ffc1561f" + ] + }, + "Body": "eyJGYWlsZWQiOlt7IkNvZGUiOiJSZWNlaXB0SGFuZGxlSXNJbnZhbGlkIiwiSWQiOiIwIiwiTWVzc2FnZSI6Ik1lc3NhZ2UgZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IGF2YWlsYWJsZSBmb3IgdmlzaWJpbGl0eSB0aW1lb3V0IGNoYW5nZSIsIlNlbmRlckZhdWx0Ijp0cnVlfSx7IkNvZGUiOiJSZWNlaXB0SGFuZGxlSXNJbnZhbGlkIiwiSWQiOiIxIiwiTWVzc2FnZSI6Ik1lc3NhZ2UgZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IGF2YWlsYWJsZSBmb3IgdmlzaWJpbGl0eSB0aW1lb3V0IGNoYW5nZSIsIlNlbmRlckZhdWx0Ijp0cnVlfV0sIlN1Y2Nlc3NmdWwiOlt7IklkIjoiMiJ9XX0=" + } + }, + { + "ID": "42b78385f144ac1b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:18 GMT" + ], + "X-Amzn-Requestid": [ + "a9edcc53-234b-5b75-ba1c-aca7e3853cbb" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8ae7b1ffb450dc97", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:18 GMT" + ], + "X-Amzn-Requestid": [ + "d5b44c33-f989-5eac-8994-2cc739477962" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "900222559d29bf4b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:18 GMT" + ], + "X-Amzn-Requestid": [ + "6c401ad4-8706-5dbb-b3a2-7a2047c81a75" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7fefd47141cfd31b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1696" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:19 GMT" + ], + "X-Amzn-Requestid": [ + "18c9a9f9-3764-5d2d-ac6e-c90df7abdae3" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzNzk1NCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMiIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjM3NzkzIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiOTFjMjdjYzktN2RiOS01ZWUyLWIyNDctMWMzZGJkNzQ0NTJjXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0RvdWJsZUFjay10b3AtMVwiLFxuICBcIk1lc3NhZ2VcIiA6IFwiMVwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjE3Ljc2NFpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiSUdNZ1E1c1prWkV4VFBtN0RXUnRvVUtFM21PaWRWbFVlZmJsb0dpMU1DL2tIbXA0NkJsUExqd3Noeng0Wm53dzVZcGF1RGlvTCtnN1VNOExsTFdOS1h5MzBRRUtxRlBUQ0dMdElNRmY3VWxDUDMzSHdMZHJqS2F5cTRnOXRLeGYvZWVDNEM0Ri8rWjJlY0dQeEhlemZqVnBCcG9pZFhEK0JuT2M4UEZLVE11dDVZY0p5YTBKem5NTVhUVCswSlZOYlhJQ0FqS1VBVkxSZFRSRElFaGU4bEo4RTNBOGhvQ3craEFoSnJLSUFUVTFJWDNha25IZ3JIVlRUeHdNL3NaZllrZ1VNMzBZbi94VXdUanpkeTFpaG11YXJOek54SnFWa2VIOXFyR3cvamxpWjZmS0NvNHdtVHZhMkZwb1pHQjNIajZyUHlodXdYYXBtWnN2SlBibVZBPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNEb3VibGVBY2stdG9wLTE6MjIxZmVlNTAtY2Y1ZC00YmY5LTliNzUtMTlhMDg5MjFhOTBmXCJcbn0iLCJNRDVPZkJvZHkiOiJlOGM1ZGIyNjU3YzAyOTQxYzc5NWEzNTFkOTk5OTc5OSIsIk1lc3NhZ2VJZCI6ImEzZTQ2MTVkLWJkZGItNGVkMy1iNDAyLTI3NzJkMDNjYmZmYSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCZG9udW9qSi9ib25XYUI0czM5VFFTQzhiOFRmRDl1R0NBRzc4T2xySS9XMmt6dHE1aHc2R1FCdWtlQ0VjSDN5a1AzOVBmdG9iVGVWZUxXdW5WVHVMTGlxWTFqZUczVTdnQXhJeDNBMHlYR3FTT0lTNnBybVltWGRMZHVKVTRKcC9TaXBaSDhjSE9xdHJoQnFwZ3BRSjE5b1lJQWlzcnkzd2l5Z2VEb0t5ajd2NjJvWmtwelVNcmFGak90Y3E2a0d4WXRlK3B5WXNhRUw5bHJId3ptTEtjRW4xaEdJaFQwdEJHd29kRitud0g2TUhodVVHOEwvVVpsNytremRrSUpZUitBQWdXU2JCVWl1aEZpZUo5SVB5YnkrbVJnK0pwNWdTbjhLeVZyemFKSUIxSXBXZUhUQklRK2tDYmtRTm1VenB5WSs2RzQ5YmV6TGdIeUp0T21FaEd2UFZ0dTVCQ3l6WTN3ZURIQTZ5bFE2R21XTnM0Q0dUaVErQlpPR2ZMMGk0TmVQbEE0cWJ0UGlyWTZpVXFocDVnUT09In1dfQ==" + } + }, + { + "ID": "198ea6ef8b5fa400", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "161" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0RvdWJsZUFjay10b3AtMSUzQTIyMWZlZTUwLWNmNWQtNGJmOS05Yjc1LTE5YTA4OTIxYTkwZiZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:19 GMT" + ], + "X-Amzn-Requestid": [ + "3a61f636-551a-5715-bf67-96c295d5fcdb" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4zYTYxZjYzNi01NTFhLTU3MTUtYmY2Ny05NmMyOTVkNWZjZGI8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "576e09033be2199e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "87" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:19 GMT" + ], + "X-Amzn-Requestid": [ + "aa01232f-f29d-57c0-aa53-43db3252900e" + ] + }, + "Body": "" + } + }, + { + "ID": "fd5012af79117309", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "115" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljRG91YmxlQWNrLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:19 GMT" + ], + "X-Amzn-Requestid": [ + "1ebecdf0-3517-533d-95dd-ad04f5d868f3" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4xZWJlY2RmMC0zNTE3LTUzM2QtOTVkZC1hZDA0ZjVkODY4ZjM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestErrorOnReceiveFromClosedSubscription.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestErrorOnReceiveFromClosedSubscription.replay new file mode 100644 index 000000000..2bef3f2f9 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestErrorOnReceiveFromClosedSubscription.replay @@ -0,0 +1,487 @@ +{ + "Initial": "AQAAAA7gDLV5MCC6eQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "67666e70c99e73e1", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "93" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNFcnJvck9uUmVjZWl2ZUZyb21DbG9zZWRTdWJzY3JpcHRpb24tdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "357" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:36:58 GMT" + ], + "X-Amzn-Requestid": [ + "061dc062-a1d4-53ec-af52-a096616ecb20" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljRXJyb3JPblJlY2VpdmVGcm9tQ2xvc2VkU3Vic2NyaXB0aW9uLXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4wNjFkYzA2Mi1hMWQ0LTUzZWMtYWY1Mi1hMDk2NjE2ZWNiMjA8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "6696b2fc5a6c56d0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "66" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "114" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:36:59 GMT" + ], + "X-Amzn-Requestid": [ + "dd533f83-412a-5e74-9517-5f778191fc65" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSJ9" + } + }, + { + "ID": "3df628ca022d6297", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "144" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "115" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:36:59 GMT" + ], + "X-Amzn-Requestid": [ + "156d50a9-2592-55f0-a66a-305de52937e1" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSJ9fQ==" + } + }, + { + "ID": "52748bf45e76cd04", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "514" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljRXJyb3JPblJlY2VpdmVGcm9tQ2xvc2VkU3Vic2NyaXB0aW9uLXN1Yi0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNFcnJvck9uUmVjZWl2ZUZyb21DbG9zZWRTdWJzY3JpcHRpb24tc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:36:59 GMT" + ], + "X-Amzn-Requestid": [ + "7da0b0a4-3c16-56cf-9012-d050fcad54de" + ] + }, + "Body": "" + } + }, + { + "ID": "6b0069ee62ab1498", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "258" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSZQcm90b2NvbD1zcXMmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBU05TVG9waWNFcnJvck9uUmVjZWl2ZUZyb21DbG9zZWRTdWJzY3JpcHRpb24tdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "400" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:36:59 GMT" + ], + "X-Amzn-Requestid": [ + "153f3ea8-5426-5031-93b0-5e5c949d38fd" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljRXJyb3JPblJlY2VpdmVGcm9tQ2xvc2VkU3Vic2NyaXB0aW9uLXRvcC0xOjVjY2RiZTZkLTBlYzUtNDE3MS1iYTRhLWJjYjlkMjBmYzY3MTwvU3Vic2NyaXB0aW9uQXJuPgogIDwvU3Vic2NyaWJlUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4xNTNmM2VhOC01NDI2LTUwMzEtOTNiMC01ZTVjOTQ5ZDM4ZmQ8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvU3Vic2NyaWJlUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "c358a328a4f6b5e8", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "188" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi10b3AtMSUzQTVjY2RiZTZkLTBlYzUtNDE3MS1iYTRhLWJjYjlkMjBmYzY3MSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:36:59 GMT" + ], + "X-Amzn-Requestid": [ + "294d1da0-153a-5cb8-b06a-7d54d5814474" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4yOTRkMWRhMC0xNTNhLTVjYjgtYjA2YS03ZDU0ZDU4MTQ0NzQ8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "809ddf747dd4dd96", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "114" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:36:59 GMT" + ], + "X-Amzn-Requestid": [ + "b875d6c6-2eaa-51db-9640-b632ee1143ca" + ] + }, + "Body": "" + } + }, + { + "ID": "0a105e0e87405e7c", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "142" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljRXJyb3JPblJlY2VpdmVGcm9tQ2xvc2VkU3Vic2NyaXB0aW9uLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:36:59 GMT" + ], + "X-Amzn-Requestid": [ + "987d13a6-acaa-5772-b6c8-73526c11efbe" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD45ODdkMTNhNi1hY2FhLTU3NzItYjZjOC03MzUyNmMxMWVmYmU8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestErrorOnSendToClosedTopic.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestErrorOnSendToClosedTopic.replay new file mode 100644 index 000000000..f4ef678a1 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestErrorOnSendToClosedTopic.replay @@ -0,0 +1,151 @@ +{ + "Initial": "AQAAAA7gDLWGM1Fq3QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "af1c80db2599d22f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNFcnJvck9uU2VuZFRvQ2xvc2VkVG9waWMtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "345" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:11 GMT" + ], + "X-Amzn-Requestid": [ + "09297555-bc9f-5c31-acae-15a17c5807d2" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljRXJyb3JPblNlbmRUb0Nsb3NlZFRvcGljLXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4wOTI5NzU1NS1iYzlmLTVjMzEtYWNhZS0xNWExN2M1ODA3ZDI8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "249c1ce7fd01d4e1", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "130" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljRXJyb3JPblNlbmRUb0Nsb3NlZFRvcGljLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:11 GMT" + ], + "X-Amzn-Requestid": [ + "203039aa-8425-5e65-b3e8-595e44e2f586" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4yMDMwMzlhYS04NDI1LTVlNjUtYjNlOC01OTVlNDRlMmY1ODY8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestMetadata.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestMetadata.replay new file mode 100644 index 000000000..e3f1f2466 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestMetadata.replay @@ -0,0 +1,823 @@ +{ + "Initial": "AQAAAA7gDLV9D4i9dwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "21ed72f94f5ac77f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNNZXRhZGF0YS10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "329" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:01 GMT" + ], + "X-Amzn-Requestid": [ + "3cebeec6-1d93-58af-8ff6-8e32dd2edf2a" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTWV0YWRhdGEtdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjNjZWJlZWM2LTFkOTMtNThhZi04ZmY2LThlMzJkZDJlZGYyYTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "5c10813795574271", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "38" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "86" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:01 GMT" + ], + "X-Amzn-Requestid": [ + "7c18067f-21eb-5c53-bafc-668be156c1dc" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY01ldGFkYXRhLXN1Yi0xIn0=" + } + }, + { + "ID": "72a8246455a47926", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "116" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "87" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:01 GMT" + ], + "X-Amzn-Requestid": [ + "d98d99b7-007d-5ba2-a656-f943c0c0d62d" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY01ldGFkYXRhLXN1Yi0xIn19" + } + }, + { + "ID": "8d2d62aef40dcd9b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "458" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTWV0YWRhdGEtc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:01 GMT" + ], + "X-Amzn-Requestid": [ + "ba7b7511-48c4-5eff-accc-15e58879e370" + ] + }, + "Body": "" + } + }, + { + "ID": "ee830b03a0211e61", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "202" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY01ldGFkYXRhLXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY01ldGFkYXRhLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "372" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:02 GMT" + ], + "X-Amzn-Requestid": [ + "caa23984-4cb4-5e80-a312-59708c0ae905" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTWV0YWRhdGEtdG9wLTE6NDI5NTY4ODYtNjI1Ny00OTQxLWFjODMtMGM4ZTM5ZDk3MzY5PC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmNhYTIzOTg0LTRjYjQtNWU4MC1hMzEyLTU5NzA4YzBhZTkwNTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "80c76e4dbc05987c", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "3730" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjEuQ0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:02 GMT" + ], + "X-Amzn-Requestid": [ + "afaf495e-6dbf-5cb8-bc2b-29aaad015b3d" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmFjOWY3NzQ0LWNlOTUtNTgxNC1iNmI1LTE3YjAwZTJiZmY5MTwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmFmYWY0OTVlLTZkYmYtNWNiOC1iYzJiLTI5YWFhZDAxNWIzZDwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "9138d71b2d2a3fbd", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "3269" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:02 GMT" + ], + "X-Amzn-Requestid": [ + "a87ec07b-f67f-50eb-ab1a-a08f36c1fd64" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyMjI4OSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjIyMjU2In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiYWM5Zjc3NDQtY2U5NS01ODE0LWI2YjUtMTdiMDBlMmJmZjkxXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY01ldGFkYXRhLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjAyLjIyMFpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiZkFoVTdRM0o0THJ6VUZrcnVidWsySHhCbXF2b1Q2L3JtUEJucTVPZmdYZGY4bTZ0aTBpYjRmR2JOUkQxbDY2YkZpVTl4aHV3bnJCWGNKaWliWThBUFBDK2JGckpsT2tCZVY0VVArb0FGTWRFRkVyRkFBZlFZN1UxbWVHYWVOWFNOQmV3cEI2N3FCRmk5Y3dNUU1BN09tMlRwdGtuc3VtZ1dlY2wzK25uQmFvMGlxL2txSlBtMEM1aytTWmxxY2M4aW9CMktWTVlIbDhqM1BtNzk5YVpuZ1RiMzdpTkhTUTQ5ZU43OVZMRW1VdlhhbnV2d0QwTnBJODFkbjZHcXFxcFREb095U0IyWW0wQVpuYTBnYU52a3J5bm1YQzhTYlJYRlEwVHMyVmlsd050eDZKUjJBKzgvUEVEc0NCQ2NKOW92NDZKSVJZd2crVFNCckJqYjN5Z2x3PT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNNZXRhZGF0YS10b3AtMTo0Mjk1Njg4Ni02MjU3LTQ5NDEtYWM4My0wYzhlMzlkOTczNjlcIixcbiAgXCJNZXNzYWdlQXR0cmlidXRlc1wiIDoge1xuICAgIFwiX18weDJlX19fXzB4MmVfX19fMHg1Y19fZm9vX18weDVjX19fXzB4NWNfX2Jhcl9fMHg1Y19fX18weDVjX19fXzB4NWNfX2JhelwiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiLi4lNUNmb28lNUMlNUNiYXIlNUMlNUMlNUNiYXpcIn0sXG4gICAgXCJfXzB4MTBfX19fMHgxMV9fX18weDEyX19fXzB4MTNfX19fMHgxNF9fX18weDE1X19fXzB4MTZfX19fMHgxN19fX18weDE4X19fXzB4MTlfX19fMHgxYV9fX18weDFiX19fXzB4MWNfX19fMHgxZF9fX18weDFlX19fXzB4MWZfX1wiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiJTEwJTExJTEyJTEzJTE0JTE1JTE2JTE3JTE4JTE5JTFBJTFCJTFDJTFEJTFFJTFGXCJ9LFxuICAgIFwiX18weDJlX19fXzB4MmVfX19fMHg1Y19fZm9vX18weDVjX18uX18weDJlX19fXzB4NWNfX2Jhcl9fMHg1Y19fLl9fMHgyZV9fX18weDVjX18uX18weDJlX19fXzB4NWNfX2Jhei5fXzB4MmVfX19fMHg1Y19fXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIuLiU1Q2ZvbyU1Qy4uJTVDYmFyJTVDLi4lNUMuLiU1Q2Jhei4uJTVDXCJ9LFxuICAgIFwiX18weDNhX19fXzB4M2JfX19fMHgzY19fX18weDNkX19fXzB4M2VfX19fMHgzZl9fXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCI6JTNCJTNDPSUzRSUzRlwifSxcbiAgICBcIl9fMHgwX19fXzB4MV9fX18weDJfX19fMHgzX19fXzB4NF9fX18weDVfX19fMHg2X19fXzB4N19fX18weDhfX19fMHg5X19fXzB4YV9fX18weGJfX19fMHhjX19fXzB4ZF9fX18weGVfX19fMHhmX19cIiA6IHtcIlR5cGVcIjpcIlN0cmluZ1wiLFwiVmFsdWVcIjpcIiUwMCUwMSUwMiUwMyUwNCUwNSUwNiUwNyUwOCUwOSUwQSUwQiUwQyUwRCUwRSUwRlwifSxcbiAgICBcIl9fMHgyZV9fX18weDJlX19fXzB4MmZfX2Zvb19fMHgyZl9fLl9fMHgyZV9fX18weDJmX19iYXJfXzB4MmZfXy5fXzB4MmVfX19fMHgyZl9fLl9fMHgyZV9fX18weDJmX19iYXouX18weDJlX19fXzB4MmZfX1wiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiLi4lMkZmb28lMkYuLiUyRmJhciUyRi4uJTJGLi4lMkZiYXouLiUyRlwifSxcbiAgICBcIl9fMHgyMF9fX18weDIxX19fXzB4MjJfX19fMHgyM19fX18weDI0X19fXzB4MjVfX19fMHgyNl9fX18weDI3X19fXzB4MjhfX19fMHgyOV9fX18weDJhX19fXzB4MmJfX19fMHgyY19fLS5fXzB4MmZfX1wiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiJTIwJTIxJTIyJTIzJCUyNSYlMjclMjglMjklMkErJTJDLS4lMkZcIn0sXG4gICAgXCIxMjM0NVwiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiMTIzNDVcIn0sXG4gICAgXCJfXzB4NDBfX1wiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiQFwifSxcbiAgICBcIl9fMHg1Yl9fX18weDVjX19fXzB4NWRfX19fMHg1ZV9fX1wiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiJTVCJTVDJTVEJTVFX1wifVxuICB9XG59IiwiTUQ1T2ZCb2R5IjoiYzU4MDgwZGI5ZmNjYTRmZWM1OTE2ODRmMTg2ZmVlMWQiLCJNZXNzYWdlSWQiOiIzZTZhYmJiNS0zNTM4LTQzZjQtOWNiMy1jYTI4MjUxZjY5NGMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQi9vKzlEU1FtYnhGNkVUMU5jTEtNYS94TWRrOE4rcjcwNUFNRTVlSzM0blNHMDJ0QkdjT2dqbG1DdENkdGgwOTU5MDVKczlHZXNjLys0akVKY0o3MVBzL1FYVmlhMVlNdHFWbGVsMVE0aWpQU09xWDE0MWZDSmdiSXRGLzErMy9Qc1VwVHVIb0cyUGtSR1Y1Sy82dGdnUVdWSUhTaVZMWWErQktLTTlJMy9BMWt3emprelhHeUthanpGdkdBUTBrK1NLMHA1cHIzWE9jVThsSVMrWkF5NzBFcldQUmd6QnY0TnhQRC9xS3RFZ0hmcWVjdmhFNEoyS29BQ3JqeTlxWndkaysxNFpaQ3JVK0U5MXdyZDM3UGhFQXA5dk1kWmtmLzFOYU1KaXp4ek1QanpGV1VhOFFuV0tsc28zK1l6STVNTVpWSzk3U0szcExvdkV3MW5vQUVKcUR2MEJLd2lRUHovSUpyN0dzd3dURVUrc0Q2MUtieFpjQTlTV3BmUCtxZi9pbDNCSXpaakVUWVB3ZDFaMG5QcUE9PSJ9XX0=" + } + }, + { + "ID": "fce26bf90ded831d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "540" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQi9vKzlEU1FtYnhGNkVUMU5jTEtNYS94TWRrOE4rcjcwNUFNRTVlSzM0blNHMDJ0QkdjT2dqbG1DdENkdGgwOTU5MDVKczlHZXNjLys0akVKY0o3MVBzL1FYVmlhMVlNdHFWbGVsMVE0aWpQU09xWDE0MWZDSmdiSXRGLzErMy9Qc1VwVHVIb0cyUGtSR1Y1Sy82dGdnUVdWSUhTaVZMWWErQktLTTlJMy9BMWt3emprelhHeUthanpGdkdBUTBrK1NLMHA1cHIzWE9jVThsSVMrWkF5NzBFcldQUmd6QnY0TnhQRC9xS3RFZ0hmcWVjdmhFNEoyS29BQ3JqeTlxWndkaysxNFpaQ3JVK0U5MXdyZDM3UGhFQXA5dk1kWmtmLzFOYU1KaXp4ek1QanpGV1VhOFFuV0tsc28zK1l6STVNTVpWSzk3U0szcExvdkV3MW5vQUVKcUR2MEJLd2lRUHovSUpyN0dzd3dURVUrc0Q2MUtieFpjQTlTV3BmUCtxZi9pbDNCSXpaakVUWVB3ZDFaMG5QcUE9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNNZXRhZGF0YS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:02 GMT" + ], + "X-Amzn-Requestid": [ + "60f38ad6-25de-5cd3-bcd5-ea22e560515c" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "fcb93eda9373ec38", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2484" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjEuQ0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:02 GMT" + ], + "X-Amzn-Requestid": [ + "d43858d6-c9c3-5fa8-9b48-3822097d882d" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjgxNDg2MzQyLTE5NDAtNWMwNy04MTc5LTAzYjZkOWZlZmI4MjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmQ0Mzg1OGQ2LWM5YzMtNWZhOC05YjQ4LTM4MjIwOTdkODgyZDwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "c7ef247fbfbbf5c6", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2492" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:02 GMT" + ], + "X-Amzn-Requestid": [ + "7f86ec22-58d1-5da5-a462-8cd6986f002a" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyMjQxOCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjIyMzgxIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiODE0ODYzNDItMTk0MC01YzA3LTgxNzktMDNiNmQ5ZmVmYjgyXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY01ldGFkYXRhLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCJoZWxsbyB3b3JsZFwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjAyLjM1MFpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiT1p0TDNEY2NhRmloa2FpWWdlWVo1Rlp0NFkwNXBqY3JPS2dZS2Z1TE53dmZqckp5WHo3dytZeS8yaGljU0tCS2xkTzE2bmladW00WndvUCtlNFhCSUVWZUt6enErNGxCbFU4VjBDd3c0WCtGM1ZCNWkwa0crRkZCZGV6bDU4TUt6UWIwTFRLNjFZaEhldU9Ja05URmhlV2dmQTJCdUdEWG1aVnZyMWJGRk9LRHRiZjRSNURJdjRRb1d1alF6cnZlOTUybWF2QnhNdUJvS1hZQ2JzMmd5MUpxZklpMmkxVGtCMkFvN3F1RHVraWtWOUNxbWZSc244bWRGQnVKMU1aRitwb1FQUXZOeGliRmJqbW5CVjJJVTREd0pNYjlmL0RYWEtieHFTWlVld0hVVWdlc3lsb0pjRHQzOE9ZbGZyYmdVS3VYYXhjazJnQS8wWlM2bDZna3NRPT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNNZXRhZGF0YS10b3AtMTo0Mjk1Njg4Ni02MjU3LTQ5NDEtYWM4My0wYzhlMzlkOTczNjlcIixcbiAgXCJNZXNzYWdlQXR0cmlidXRlc1wiIDoge1xuICAgIFwiZm9vX18weDIwX19iYXJfXzB4MjBfX2JhelwiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiZm9vJTIwYmFyJTIwYmF6XCJ9LFxuICAgIFwiZm9vX18weDIyX19iYXJfXzB4MjJfX2JhelwiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiZm9vJTIyYmFyJTIyYmF6XCJ9LFxuICAgIFwiZm9vX18weDJmX19iYXJfXzB4MmZfX2JhelwiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiZm9vJTJGYmFyJTJGYmF6XCJ9LFxuICAgIFwiX18weDdiX19fXzB4N2NfX19fMHg3ZF9fX18weDdlX19fXzB4N2ZfX1wiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiJTdCJTdDJTdEfiU3RlwifSxcbiAgICBcImZvb19fMHg1Y19fYmFyX18weDVjX19iYXpcIiA6IHtcIlR5cGVcIjpcIlN0cmluZ1wiLFwiVmFsdWVcIjpcImZvbyU1Q2JhciU1Q2JhelwifSxcbiAgICBcIl9fMHg2MF9fXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIlNjBcIn0sXG4gICAgXCJfXzB4MjYzYV9fX18weDI2M2FfX19fMHgyNjNhX19cIiA6IHtcIlR5cGVcIjpcIlN0cmluZ1wiLFwiVmFsdWVcIjpcIiVFMiU5OCVCQSVFMiU5OCVCQSVFMiU5OCVCQVwifSxcbiAgICBcImZvb19fMHgyZl9fX18weDJmX19iYXJfXzB4MmZfX19fMHgyZl9fX18weDJmX19iYXpcIiA6IHtcIlR5cGVcIjpcIlN0cmluZ1wiLFwiVmFsdWVcIjpcImZvbyUyRiUyRmJhciUyRiUyRiUyRmJhelwifVxuICB9XG59IiwiTUQ1T2ZCb2R5IjoiYWUwZWU3NGMwNGRiNDc4NmFlZGYyZDk1NjVjZjYzYjkiLCJNZXNzYWdlSWQiOiIzMDRmZTM2Mi03N2E2LTRhZWMtYjA1MS0zNGUxZmQ3YTQ5NDgiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQndPcnQ5YVgzRkFrbStCZDkzcWxoa1g2eUtLMFpjbHhGNjE5SVBhZUw3bXh5aDlkUFFtMkZCNGYvVXJkVElPUWVaeERMb0F1MjNVbkRjVnR3OWtqVkk2VkhKaUtldzdDLzFwQWQ5TzQ4alFHT3NqMXlyc3NRZ2FHTXF4ZHpPT2w4bi9Obkd4S0xpR1ZRU0svdnVNckE2bUxUcnNnWFpGcjhTRTBBdTdEcSthd1VPWlpvaWc0TWhrekdFQnBMVG5taU81K0R6S040ZjZhRDBsejZ1U0k0M0RuS0dRZzBkK0ZKdmpPZEhqMEVxQ3MyZ2V4dGYxWnJQUnZpRVZ6VU1acmcvYmZtZGF4RVpvU0hjaFNjRktkRGtTTFVoNWQzVDdPblNjNVIzeXVDY2dEandMMnRLWTI0M2RrcmlJNVhOUmRQak9zOSt4YnRxMmRYaXJsMGEvQ0srVWZ1ZUU4YjMzMGtnclFXMUNDQmg3LzRVY1c4TllkcXRlRWZpM0FmOHVNbGw4WXF4Tzl2LzI0NUVVYi81K2dzMmc9PSJ9XX0=" + } + }, + { + "ID": "cb6f83fd84607af8", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "540" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQndPcnQ5YVgzRkFrbStCZDkzcWxoa1g2eUtLMFpjbHhGNjE5SVBhZUw3bXh5aDlkUFFtMkZCNGYvVXJkVElPUWVaeERMb0F1MjNVbkRjVnR3OWtqVkk2VkhKaUtldzdDLzFwQWQ5TzQ4alFHT3NqMXlyc3NRZ2FHTXF4ZHpPT2w4bi9Obkd4S0xpR1ZRU0svdnVNckE2bUxUcnNnWFpGcjhTRTBBdTdEcSthd1VPWlpvaWc0TWhrekdFQnBMVG5taU81K0R6S040ZjZhRDBsejZ1U0k0M0RuS0dRZzBkK0ZKdmpPZEhqMEVxQ3MyZ2V4dGYxWnJQUnZpRVZ6VU1acmcvYmZtZGF4RVpvU0hjaFNjRktkRGtTTFVoNWQzVDdPblNjNVIzeXVDY2dEandMMnRLWTI0M2RrcmlJNVhOUmRQak9zOSt4YnRxMmRYaXJsMGEvQ0srVWZ1ZUU4YjMzMGtnclFXMUNDQmg3LzRVY1c4TllkcXRlRWZpM0FmOHVNbGw4WXF4Tzl2LzI0NUVVYi81K2dzMmc9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNNZXRhZGF0YS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:02 GMT" + ], + "X-Amzn-Requestid": [ + "b9c1ab89-a5ae-5a74-990e-cb7d6510f7fb" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "89f58dda6424e992", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "160" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY01ldGFkYXRhLXRvcC0xJTNBNDI5NTY4ODYtNjI1Ny00OTQxLWFjODMtMGM4ZTM5ZDk3MzY5JlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:02 GMT" + ], + "X-Amzn-Requestid": [ + "e4451e41-14da-5151-a692-7eb5d464d6d4" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5lNDQ1MWU0MS0xNGRhLTUxNTEtYTY5Mi03ZWI1ZDQ2NGQ2ZDQ8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "527ee2eefd4e5a75", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "86" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:02 GMT" + ], + "X-Amzn-Requestid": [ + "df406bef-e53e-5f36-ab77-0b1b258012b9" + ] + }, + "Body": "" + } + }, + { + "ID": "b94876bf3a037ec8", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "114" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljTWV0YWRhdGEtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:02 GMT" + ], + "X-Amzn-Requestid": [ + "573475dd-e782-56e2-9e42-1529273c8167" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD41NzM0NzVkZC1lNzgyLTU2ZTItOWU0Mi0xNTI5MjczYzgxNjc8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNack.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNack.replay new file mode 100644 index 000000000..9a5d6e6f8 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNack.replay @@ -0,0 +1,1229 @@ +{ + "Initial": "AQAAAA7gDLWJJDGtkQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "858bb813bde2a00a", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "61" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNOYWNrLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "325" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:13 GMT" + ], + "X-Amzn-Requestid": [ + "d62f4007-de65-595b-9a80-20f31eacc1b3" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTmFjay10b3AtMTwvVG9waWNBcm4+CiAgPC9DcmVhdGVUb3BpY1Jlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+ZDYyZjQwMDctZGU2NS01OTViLTlhODAtMjBmMzFlYWNjMWIzPC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L0NyZWF0ZVRvcGljUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "aef45438a8888b12", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "34" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "82" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:14 GMT" + ], + "X-Amzn-Requestid": [ + "016cd069-0a68-56c4-9972-b09dcaa24288" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05hY2stc3ViLTEifQ==" + } + }, + { + "ID": "170983a1dcf583aa", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "112" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "83" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:14 GMT" + ], + "X-Amzn-Requestid": [ + "22aaa926-f606-5052-86c7-c9d236cc641e" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY05hY2stc3ViLTEifX0=" + } + }, + { + "ID": "8a15a241e27d7dc5", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "450" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTmFjay1zdWItMVwiXG5cdFx0fVxuXHRcdF1cblx0XHR9In0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NOU1RvcGljTmFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:14 GMT" + ], + "X-Amzn-Requestid": [ + "b861a33c-9d42-537c-bf2e-c3c85d881730" + ] + }, + "Body": "" + } + }, + { + "ID": "6aab1c7719a3ef60", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "194" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY05hY2stc3ViLTEmUHJvdG9jb2w9c3FzJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljTmFjay10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "368" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:14 GMT" + ], + "X-Amzn-Requestid": [ + "201b6528-dbe7-578c-b85b-05dc1b2d5f64" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTmFjay10b3AtMTo5NTQyYzM3MC1iNmEzLTQ0ODYtOGM2NC04NzA1ODAxNTVmNWQ8L1N1YnNjcmlwdGlvbkFybj4KICA8L1N1YnNjcmliZVJlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+MjAxYjY1MjgtZGJlNy01NzhjLWI4NWItMDVkYzFiMmQ1ZjY0PC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L1N1YnNjcmliZVJlc3BvbnNlPgo=" + } + }, + { + "ID": "019b0f0d8b8fa333", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "433" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:14 GMT" + ], + "X-Amzn-Requestid": [ + "8aca951a-8350-5f50-9699-f5ee439a07b8" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjg1N2JmZWFkLWI2N2ItNWYyNC1hOWU2LTllNTk3NmIxOTdjYzwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjhhY2E5NTFhLTgzNTAtNWY1MC05Njk5LWY1ZWU0MzlhMDdiODwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "0cc23cf00beea435", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "433" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MSZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:14 GMT" + ], + "X-Amzn-Requestid": [ + "e3f1b461-c0c5-51ea-b9db-d495000fb902" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmM2NzNhMTYwLTA1OWEtNTQ3YS05MDFkLWMxOTRjNTUwN2M5MjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmUzZjFiNDYxLWMwYzUtNTFlYS1iOWRiLWQ0OTUwMDBmYjkwMjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "d77415091169a111", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1772" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:14 GMT" + ], + "X-Amzn-Requestid": [ + "b303b06d-5b2c-57f4-8b20-d0999be623b8" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzNDcwNyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjM0NjExIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiODU3YmZlYWQtYjY3Yi01ZjI0LWE5ZTYtOWU1OTc2YjE5N2NjXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY05hY2stdG9wLTFcIixcbiAgXCJNZXNzYWdlXCIgOiBcIjBcIixcbiAgXCJUaW1lc3RhbXBcIiA6IFwiMjAyNS0wNy0xOFQyMTozNzoxNC41NzVaXCIsXG4gIFwiU2lnbmF0dXJlVmVyc2lvblwiIDogXCIxXCIsXG4gIFwiU2lnbmF0dXJlXCIgOiBcIlpUaWNYMWNlVVdxNE1LS0NuUGRKVEJkVE5JcnV1UmI5UHkwWjVGNGh1V05NbEFqY09oU09ZczREM2t2T3JkNGdWb2FHU0NrQkdWYzFYRzlmeGtUNDFQRGlMYWRTVjRtUHU4dVlLZlRlRTVFOEVaekFZWjUvMjZhNWkxajA3djBtZ3BSNFJsZjVVdlBlYnNiTGVSV0JNemVscUVYZ0dnbUxVNjcvSjhQeXdMWVZGYmFCRjZIRlh0Zy9GQUxBcUl3TnQ2TjVsQysxaUl2TVczRXFFZ1V4blhXVnFNQ0t0aHZMSkltb0NPTVpUcEEydkViejR5TkhRTDNoRkZKVGVGeFg4cHNPdXQ4VUtZd1NYdnNSb2dSQ1krWEpvQnBuSG1PaDZMejdOTU9OSFBXb0lQbGMwOWxYNE5QVE1lcHNsNjFEdFhPNGJ2VXRPZlduTU9xVlFFaHN2dz09XCIsXG4gIFwiU2lnbmluZ0NlcnRVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vU2ltcGxlTm90aWZpY2F0aW9uU2VydmljZS05YzY0NjVmYTdmNDhmNWNhY2QyMzAxNDYzMWVjMTEzNi5wZW1cIixcbiAgXCJVbnN1YnNjcmliZVVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS8/QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTmFjay10b3AtMTo5NTQyYzM3MC1iNmEzLTQ0ODYtOGM2NC04NzA1ODAxNTVmNWRcIixcbiAgXCJNZXNzYWdlQXR0cmlidXRlc1wiIDoge1xuICAgIFwiYVwiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiMFwifVxuICB9XG59IiwiTUQ1T2ZCb2R5IjoiNGIwMTg5MDQxNzZhZGVkNjU3N2EwMjJjMDM3Yzg2N2UiLCJNZXNzYWdlSWQiOiI4NGZlZTM0OC05YzY4LTRiNTQtOGRjNi00N2UzZTA2NDZiOGIiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQk9aTkFPM3gxOXBGdFB1djd1OHhaUHZjdUlPTGhEU3ZWTlp1VzdqZGJyYnZ5bFJoYTc2ZEV5S2ZJUXVvL00zTTVsclFHc0hRbDBYNEI0ai84N2ZuRVBYd3c5NzgwMVE0UzMwK0piUmNxVy8zN0ZtZmVoT0pXTHJzbTVyNFlMN0dRVXIxNGUvVUR6Vjhsd1Zucm5VYWpTMTlYcjNxSXM5di9nemdXMk1xS3RHYmxwYWhXdVp4MlVxTVlBclZmSHY0RWp5UzNXM1pIVmcxa0NzNUNLM3RtVmxSMDVTY2toTVRRS2EyNFRkZEJGWWsvNG0vZzhpY0lBUFRoS3pJaVlFcnlETTJOVU5IY0Y5VGJKN1BlRzlzaXB6Sm1BalBGOUVHQmY0YVZEWXh4ZGR5WktzcWJBOEQwN29LZnJzTU5kRy9CbHAwRVk4NEMyQktkcTA2d05rOGRhdGtYNWhPTXpBVXdJeVVjajJkK0ZKeWxUUENkNUZxeXg0R1ZpWTkyTU5YZExRSm5UNmxCdEYvVDMrdUtNZzZ5NHc9PSJ9XX0=" + } + }, + { + "ID": "fde1df2dcffd891b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1772" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:14 GMT" + ], + "X-Amzn-Requestid": [ + "c8d15309-0fed-5e24-b15f-33fdcf27ea68" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzNDc2NCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjM0NjczIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiYzY3M2ExNjAtMDU5YS01NDdhLTkwMWQtYzE5NGM1NTA3YzkyXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY05hY2stdG9wLTFcIixcbiAgXCJNZXNzYWdlXCIgOiBcIjFcIixcbiAgXCJUaW1lc3RhbXBcIiA6IFwiMjAyNS0wNy0xOFQyMTozNzoxNC42NDBaXCIsXG4gIFwiU2lnbmF0dXJlVmVyc2lvblwiIDogXCIxXCIsXG4gIFwiU2lnbmF0dXJlXCIgOiBcIkFqdFpjNnJibEJlODM1NUYxd3JkRFJhdnVKNmJWOGtLQ3N4OTZyVG83TldPV25HcFo1MUx6TUs2cHpTcUswQnk2a2VObFhYU0w4YmhUVTRtTCtwSjcvVGJvd0tWQ2JDejRxMURuYjE5Q1RsR2ducWFtNXhDMVVJSXN0RUU2U1hhdEYrSHBnUGVIRFRIQ1Nobk5qOGdudlVUcXl0WFJjd2hERDJOL0xUdHRRVldYS3M0ekR4VTcyclRHZTZtdVJZaTdGSHRna25EN3Rhcm4wbTdkMUU4MzJtZEdWUmNiS01Wa0w4RWlRQlV1a05GUThReVJqemJMbjUrYVFpbGRZZ1l0SjdGU08yb1FJenYyS0hXQXh1Vkp2UU9qOW9YSGgwS0NTcXhiUE0zVHZ0SytTMmlvQ2ZlYXV2aG9KYnh1elo0aEJuejIrV2FEUDV2eGt6QktUVklBZz09XCIsXG4gIFwiU2lnbmluZ0NlcnRVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vU2ltcGxlTm90aWZpY2F0aW9uU2VydmljZS05YzY0NjVmYTdmNDhmNWNhY2QyMzAxNDYzMWVjMTEzNi5wZW1cIixcbiAgXCJVbnN1YnNjcmliZVVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS8/QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTmFjay10b3AtMTo5NTQyYzM3MC1iNmEzLTQ0ODYtOGM2NC04NzA1ODAxNTVmNWRcIixcbiAgXCJNZXNzYWdlQXR0cmlidXRlc1wiIDoge1xuICAgIFwiYVwiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiMVwifVxuICB9XG59IiwiTUQ1T2ZCb2R5IjoiZDM2ZTM3YWQwMmI5Y2Q0OWEzZTRiOTdmNWNlYWM5MTgiLCJNZXNzYWdlSWQiOiIxNGZkN2ZiNS04OTg2LTRkOWUtOWRhZS01ODQ2NmM3NDdhNTMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlNhdHNQK084djBxNjZUZkhyV2l2TzRyazF1cVBmWVlnZ1RuSlpLQmtjeWVzcFU5Y0pUK3FWa05jV0RoU2wwVnhGMTNyelBBMkNFU0ZwVDRvV3JnTzcvSXpuSEFranVEcUFjUERqcUpsZ0k5SHNMZ3k5TzU2T2lvMEtaOHNFOVUwdWJOZmI3bEsybGx0a3BOWElpSG1vNk9xZVAwemllSHVSUXluemVJM1dxNzAzSlpVOWhZWExlYmF2eFhySEZ3b3BPdURRaVNNR1RHMTY3dEtVRW1admJpdEtEVUlZTnR1SEUrY2Fhek5pUjIwbFBEYUVKU3RPc3VwbUQ0b1ZLMlpnWlRKdmhHSlNvd1QyWnNyM2Z6a1JPeHhHTXFPN0Fsd2hLbnR2dTVSbmZMK1pOSTBXQUo2NTJSSkZ1TkJhdG5MYkhhTTBtcG9DcU5GV09qNGlwK2hQY0QxenBSbld5Ky84Vm5ITHBLZGYxM2wxZU9Oa0F4VXFxSVVIbVlFSmFWZjNnVmIwYS8wSWNRUjkvcmx2elN5eXc9PSJ9XX0=" + } + }, + { + "ID": "f7e1e5aed4721975", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "558" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ChangeMessageVisibilityBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQk9aTkFPM3gxOXBGdFB1djd1OHhaUHZjdUlPTGhEU3ZWTlp1VzdqZGJyYnZ5bFJoYTc2ZEV5S2ZJUXVvL00zTTVsclFHc0hRbDBYNEI0ai84N2ZuRVBYd3c5NzgwMVE0UzMwK0piUmNxVy8zN0ZtZmVoT0pXTHJzbTVyNFlMN0dRVXIxNGUvVUR6Vjhsd1Zucm5VYWpTMTlYcjNxSXM5di9nemdXMk1xS3RHYmxwYWhXdVp4MlVxTVlBclZmSHY0RWp5UzNXM1pIVmcxa0NzNUNLM3RtVmxSMDVTY2toTVRRS2EyNFRkZEJGWWsvNG0vZzhpY0lBUFRoS3pJaVlFcnlETTJOVU5IY0Y5VGJKN1BlRzlzaXB6Sm1BalBGOUVHQmY0YVZEWXh4ZGR5WktzcWJBOEQwN29LZnJzTU5kRy9CbHAwRVk4NEMyQktkcTA2d05rOGRhdGtYNWhPTXpBVXdJeVVjajJkK0ZKeWxUUENkNUZxeXg0R1ZpWTkyTU5YZExRSm5UNmxCdEYvVDMrdUtNZzZ5NHc9PSIsIlZpc2liaWxpdHlUaW1lb3V0IjoxfV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NOU1RvcGljTmFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:14 GMT" + ], + "X-Amzn-Requestid": [ + "5cac120c-9eb9-526c-9133-72f85e737620" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "9302b3ec644c6685", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:14 GMT" + ], + "X-Amzn-Requestid": [ + "a7408d88-a690-5557-bd8e-ed7c665ae11b" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9227c142095e1c25", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "558" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ChangeMessageVisibilityBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlNhdHNQK084djBxNjZUZkhyV2l2TzRyazF1cVBmWVlnZ1RuSlpLQmtjeWVzcFU5Y0pUK3FWa05jV0RoU2wwVnhGMTNyelBBMkNFU0ZwVDRvV3JnTzcvSXpuSEFranVEcUFjUERqcUpsZ0k5SHNMZ3k5TzU2T2lvMEtaOHNFOVUwdWJOZmI3bEsybGx0a3BOWElpSG1vNk9xZVAwemllSHVSUXluemVJM1dxNzAzSlpVOWhZWExlYmF2eFhySEZ3b3BPdURRaVNNR1RHMTY3dEtVRW1admJpdEtEVUlZTnR1SEUrY2Fhek5pUjIwbFBEYUVKU3RPc3VwbUQ0b1ZLMlpnWlRKdmhHSlNvd1QyWnNyM2Z6a1JPeHhHTXFPN0Fsd2hLbnR2dTVSbmZMK1pOSTBXQUo2NTJSSkZ1TkJhdG5MYkhhTTBtcG9DcU5GV09qNGlwK2hQY0QxenBSbld5Ky84Vm5ITHBLZGYxM2wxZU9Oa0F4VXFxSVVIbVlFSmFWZjNnVmIwYS8wSWNRUjkvcmx2elN5eXc9PSIsIlZpc2liaWxpdHlUaW1lb3V0IjoxfV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NOU1RvcGljTmFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:15 GMT" + ], + "X-Amzn-Requestid": [ + "ce0e116f-0dd9-5a11-b74a-719bcd139779" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "7a2065ffd4e77a09", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:15 GMT" + ], + "X-Amzn-Requestid": [ + "05d846e2-cce5-5a0d-a7dd-26160c2e5c00" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ae075eaa0d17b7bb", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:15 GMT" + ], + "X-Amzn-Requestid": [ + "1fe22a7d-7015-538d-a6d7-4a89b0dee580" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "68f868cf4221efa7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1772" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:15 GMT" + ], + "X-Amzn-Requestid": [ + "6722e3e7-039f-5608-b221-8313c354f005" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzNDcwNyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMiIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjM0NjExIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiODU3YmZlYWQtYjY3Yi01ZjI0LWE5ZTYtOWU1OTc2YjE5N2NjXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY05hY2stdG9wLTFcIixcbiAgXCJNZXNzYWdlXCIgOiBcIjBcIixcbiAgXCJUaW1lc3RhbXBcIiA6IFwiMjAyNS0wNy0xOFQyMTozNzoxNC41NzVaXCIsXG4gIFwiU2lnbmF0dXJlVmVyc2lvblwiIDogXCIxXCIsXG4gIFwiU2lnbmF0dXJlXCIgOiBcIlpUaWNYMWNlVVdxNE1LS0NuUGRKVEJkVE5JcnV1UmI5UHkwWjVGNGh1V05NbEFqY09oU09ZczREM2t2T3JkNGdWb2FHU0NrQkdWYzFYRzlmeGtUNDFQRGlMYWRTVjRtUHU4dVlLZlRlRTVFOEVaekFZWjUvMjZhNWkxajA3djBtZ3BSNFJsZjVVdlBlYnNiTGVSV0JNemVscUVYZ0dnbUxVNjcvSjhQeXdMWVZGYmFCRjZIRlh0Zy9GQUxBcUl3TnQ2TjVsQysxaUl2TVczRXFFZ1V4blhXVnFNQ0t0aHZMSkltb0NPTVpUcEEydkViejR5TkhRTDNoRkZKVGVGeFg4cHNPdXQ4VUtZd1NYdnNSb2dSQ1krWEpvQnBuSG1PaDZMejdOTU9OSFBXb0lQbGMwOWxYNE5QVE1lcHNsNjFEdFhPNGJ2VXRPZlduTU9xVlFFaHN2dz09XCIsXG4gIFwiU2lnbmluZ0NlcnRVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vU2ltcGxlTm90aWZpY2F0aW9uU2VydmljZS05YzY0NjVmYTdmNDhmNWNhY2QyMzAxNDYzMWVjMTEzNi5wZW1cIixcbiAgXCJVbnN1YnNjcmliZVVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS8/QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTmFjay10b3AtMTo5NTQyYzM3MC1iNmEzLTQ0ODYtOGM2NC04NzA1ODAxNTVmNWRcIixcbiAgXCJNZXNzYWdlQXR0cmlidXRlc1wiIDoge1xuICAgIFwiYVwiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiMFwifVxuICB9XG59IiwiTUQ1T2ZCb2R5IjoiNGIwMTg5MDQxNzZhZGVkNjU3N2EwMjJjMDM3Yzg2N2UiLCJNZXNzYWdlSWQiOiI4NGZlZTM0OC05YzY4LTRiNTQtOGRjNi00N2UzZTA2NDZiOGIiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkFydmJwM2JNam1qWjgwN2RDbkE2QW1ZRmZXQUFjZkRyZDYyNnV2SktKVUt6dWFEb29oOTJ2bUxhZnRBNDAwTjJQTVZhL0o5SWxwZnlLMi9sclovTUh0czlzbGFNU2JveHFCWDB2RUpTY3Q1SHU1RGZjc0F2WFJ4aDVOdjd3bWdYY2pucW9mUklGUmlDSTFIVzY4Z2lHNDA5Z1Bsc0Q1MDlXU3QxQkVscnduQXRDYklNdnpHelpzRllMV1hLV2grM1Y1RU1VSU84VVVSWmZyQzVYcmhNR3U1NjFWTHVRK3lQMFhxdU9GNWdzWDZsaU5UTGxZb0xSbU5talRWRGcvNWgwaGVzODdNNW5LNWNCNUdUaVZPQVlJVlFmS2lHODNrclNTL21OMFlHNGhwZ0NoZEJPaUpLNDhXQzlrOTBZbHYyQWVvaklQRVNBOHdlekJlRXFIVUkzakJGVGVLYmxOM3JMVlVRVkZwbVgvL1gycy9MN3R1T09BQjZ1a2hDd3VwMW91cE85L1dOb1lNN1g1aVkwTlBJK1E9PSJ9XX0=" + } + }, + { + "ID": "6597f14025dec522", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1772" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:16 GMT" + ], + "X-Amzn-Requestid": [ + "9e0e1622-df0a-5d8d-81e9-76d61fc6eb80" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzNDc2NCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMiIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjM0NjczIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiYzY3M2ExNjAtMDU5YS01NDdhLTkwMWQtYzE5NGM1NTA3YzkyXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY05hY2stdG9wLTFcIixcbiAgXCJNZXNzYWdlXCIgOiBcIjFcIixcbiAgXCJUaW1lc3RhbXBcIiA6IFwiMjAyNS0wNy0xOFQyMTozNzoxNC42NDBaXCIsXG4gIFwiU2lnbmF0dXJlVmVyc2lvblwiIDogXCIxXCIsXG4gIFwiU2lnbmF0dXJlXCIgOiBcIkFqdFpjNnJibEJlODM1NUYxd3JkRFJhdnVKNmJWOGtLQ3N4OTZyVG83TldPV25HcFo1MUx6TUs2cHpTcUswQnk2a2VObFhYU0w4YmhUVTRtTCtwSjcvVGJvd0tWQ2JDejRxMURuYjE5Q1RsR2ducWFtNXhDMVVJSXN0RUU2U1hhdEYrSHBnUGVIRFRIQ1Nobk5qOGdudlVUcXl0WFJjd2hERDJOL0xUdHRRVldYS3M0ekR4VTcyclRHZTZtdVJZaTdGSHRna25EN3Rhcm4wbTdkMUU4MzJtZEdWUmNiS01Wa0w4RWlRQlV1a05GUThReVJqemJMbjUrYVFpbGRZZ1l0SjdGU08yb1FJenYyS0hXQXh1Vkp2UU9qOW9YSGgwS0NTcXhiUE0zVHZ0SytTMmlvQ2ZlYXV2aG9KYnh1elo0aEJuejIrV2FEUDV2eGt6QktUVklBZz09XCIsXG4gIFwiU2lnbmluZ0NlcnRVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vU2ltcGxlTm90aWZpY2F0aW9uU2VydmljZS05YzY0NjVmYTdmNDhmNWNhY2QyMzAxNDYzMWVjMTEzNi5wZW1cIixcbiAgXCJVbnN1YnNjcmliZVVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS8/QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTmFjay10b3AtMTo5NTQyYzM3MC1iNmEzLTQ0ODYtOGM2NC04NzA1ODAxNTVmNWRcIixcbiAgXCJNZXNzYWdlQXR0cmlidXRlc1wiIDoge1xuICAgIFwiYVwiIDoge1wiVHlwZVwiOlwiU3RyaW5nXCIsXCJWYWx1ZVwiOlwiMVwifVxuICB9XG59IiwiTUQ1T2ZCb2R5IjoiZDM2ZTM3YWQwMmI5Y2Q0OWEzZTRiOTdmNWNlYWM5MTgiLCJNZXNzYWdlSWQiOiIxNGZkN2ZiNS04OTg2LTRkOWUtOWRhZS01ODQ2NmM3NDdhNTMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlVuczZZS05pZVhveVg3M1Jxejh3SnpOMXRBQWQ5QUthNXdlVlczTzBNc2VFUElUUlJWeG8ybENtdmR0WGtIbUZ6aUU4aEJUaHVBZW8vdGRZUFYzM3lTRjZTa3Z2UUp0NFBRRWQ3U3pVUnB6cC8rRzhhWFkyc050VVg5bkNvdEJIZVlyektmRjU0ejZrZU5xYVcrZUI5aXhzRy8zaGx0azQxQzhEOVJaM3dzTjZpano1c3pxRFk3cW4wYkxFeXNJdnFBblhDZkl5VEJKWXcrSjFBVlFSd0oxQUJaZzhlRkJ1Z3FZTGpUa2hQRUJVSW9TQzczOHg2ZW9kVnZ2LzREK2JMUkgxeU5WbU5hMWlnTUFQVEF2Ny9NNXorVGpVTXYxZFpWUk1HWHd6SUlBdHdvTlZVdEJ5d1RSUnJjbFlKdTk2N0xidDBHUkVjSldLSy9La2RHeURteURXMTVhaFJENUp4QkV4RkdJUTBWeGJPOWdCU0JGazdpM3lzWDBZbS83QTJMSTRhTURzNDgrcXQ3TFE1NnVZc3c9PSJ9XX0=" + } + }, + { + "ID": "8322b552c251d332", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "536" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkFydmJwM2JNam1qWjgwN2RDbkE2QW1ZRmZXQUFjZkRyZDYyNnV2SktKVUt6dWFEb29oOTJ2bUxhZnRBNDAwTjJQTVZhL0o5SWxwZnlLMi9sclovTUh0czlzbGFNU2JveHFCWDB2RUpTY3Q1SHU1RGZjc0F2WFJ4aDVOdjd3bWdYY2pucW9mUklGUmlDSTFIVzY4Z2lHNDA5Z1Bsc0Q1MDlXU3QxQkVscnduQXRDYklNdnpHelpzRllMV1hLV2grM1Y1RU1VSU84VVVSWmZyQzVYcmhNR3U1NjFWTHVRK3lQMFhxdU9GNWdzWDZsaU5UTGxZb0xSbU5talRWRGcvNWgwaGVzODdNNW5LNWNCNUdUaVZPQVlJVlFmS2lHODNrclNTL21OMFlHNGhwZ0NoZEJPaUpLNDhXQzlrOTBZbHYyQWVvaklQRVNBOHdlekJlRXFIVUkzakJGVGVLYmxOM3JMVlVRVkZwbVgvL1gycy9MN3R1T09BQjZ1a2hDd3VwMW91cE85L1dOb1lNN1g1aVkwTlBJK1E9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNOYWNrLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:16 GMT" + ], + "X-Amzn-Requestid": [ + "e345d932-499f-5773-8866-b9c68953333f" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "9f36ea3fa20428e0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "536" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlVuczZZS05pZVhveVg3M1Jxejh3SnpOMXRBQWQ5QUthNXdlVlczTzBNc2VFUElUUlJWeG8ybENtdmR0WGtIbUZ6aUU4aEJUaHVBZW8vdGRZUFYzM3lTRjZTa3Z2UUp0NFBRRWQ3U3pVUnB6cC8rRzhhWFkyc050VVg5bkNvdEJIZVlyektmRjU0ejZrZU5xYVcrZUI5aXhzRy8zaGx0azQxQzhEOVJaM3dzTjZpano1c3pxRFk3cW4wYkxFeXNJdnFBblhDZkl5VEJKWXcrSjFBVlFSd0oxQUJaZzhlRkJ1Z3FZTGpUa2hQRUJVSW9TQzczOHg2ZW9kVnZ2LzREK2JMUkgxeU5WbU5hMWlnTUFQVEF2Ny9NNXorVGpVTXYxZFpWUk1HWHd6SUlBdHdvTlZVdEJ5d1RSUnJjbFlKdTk2N0xidDBHUkVjSldLSy9La2RHeURteURXMTVhaFJENUp4QkV4RkdJUTBWeGJPOWdCU0JGazdpM3lzWDBZbS83QTJMSTRhTURzNDgrcXQ3TFE1NnVZc3c9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNOYWNrLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:16 GMT" + ], + "X-Amzn-Requestid": [ + "8f81fb3b-1872-5fbb-a0d1-9bcfd8be99b6" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "dc9380d3b4ebe033", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "156" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY05hY2stdG9wLTElM0E5NTQyYzM3MC1iNmEzLTQ0ODYtOGM2NC04NzA1ODAxNTVmNWQmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:16 GMT" + ], + "X-Amzn-Requestid": [ + "28753039-31c7-58db-af12-50cdf10b7033" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4yODc1MzAzOS0zMWM3LTU4ZGItYWYxMi01MGNkZjEwYjcwMzM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "eb9daf6fc792d5d1", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:16 GMT" + ], + "X-Amzn-Requestid": [ + "4e7756e8-6190-58c5-8666-361ca15cdec8" + ] + }, + "Body": "" + } + }, + { + "ID": "17e4efb1b64f14fa", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "110" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljTmFjay10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:16 GMT" + ], + "X-Amzn-Requestid": [ + "912aeefc-f4aa-5598-8887-8e0834665d70" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD45MTJhZWVmYy1mNGFhLTU1OTgtODg4Ny04ZTA4MzQ2NjVkNzA8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay new file mode 100644 index 000000000..6393af469 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay @@ -0,0 +1,108 @@ +{ + "Initial": "AQAAAA7gDLWHH02oRwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "61eba56cc5d701b7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "165" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vdXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L25vbmV4aXN0ZW50LXN1YnNjcmlwdGlvbiJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:11 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "c805e61e-3b49-5177-b0cb-86eafb8ef1d9" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay new file mode 100644 index 000000000..3f613be38 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay @@ -0,0 +1,99 @@ +{ + "Initial": "AQAAAA7gDLWHEI7NXwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "051fa8c0c2911f7f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "195" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9JlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQW5vbmV4aXN0ZW50dG9waWMmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "259" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:11 GMT" + ], + "X-Amzn-Requestid": [ + "232ada60-2b6f-5576-add4-ba94eba8779f" + ] + }, + "Body": "PEVycm9yUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxFcnJvcj4KICAgIDxUeXBlPlNlbmRlcjwvVHlwZT4KICAgIDxDb2RlPk5vdEZvdW5kPC9Db2RlPgogICAgPE1lc3NhZ2U+VG9waWMgZG9lcyBub3QgZXhpc3Q8L01lc3NhZ2U+CiAgPC9FcnJvcj4KICA8UmVxdWVzdElkPjIzMmFkYTYwLTJiNmYtNTU3Ni1hZGQ0LWJhOTRlYmE4Nzc5ZjwvUmVxdWVzdElkPgo8L0Vycm9yUmVzcG9uc2U+Cg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNonUTF8MessageBody.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNonUTF8MessageBody.replay new file mode 100644 index 000000000..bba88abbb --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestNonUTF8MessageBody.replay @@ -0,0 +1,655 @@ +{ + "Initial": "AQAAAA7gDLV+M6IsawAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "5e9d7d51737d5667", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "75" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNOb25VVEY4TWVzc2FnZUJvZHktdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "339" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:03 GMT" + ], + "X-Amzn-Requestid": [ + "0ed5cf99-f1d8-5d50-a48a-af6d316774bb" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTm9uVVRGOE1lc3NhZ2VCb2R5LXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4wZWQ1Y2Y5OS1mMWQ4LTVkNTAtYTQ4YS1hZjZkMzE2Nzc0YmI8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "9512baf2e7d8b04e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "48" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:03 GMT" + ], + "X-Amzn-Requestid": [ + "6e51d549-56a3-5816-873c-b5bd961ce2dd" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + } + }, + { + "ID": "95488302373190a2", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "126" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "97" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:03 GMT" + ], + "X-Amzn-Requestid": [ + "e803ffbe-9193-578d-87e3-9f4a512c1d46" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9fQ==" + } + }, + { + "ID": "bbb7268f199ae88c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "478" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTm9uVVRGOE1lc3NhZ2VCb2R5LXN1Yi0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNOb25VVEY4TWVzc2FnZUJvZHktc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:03 GMT" + ], + "X-Amzn-Requestid": [ + "731c3bc4-3913-5988-962d-5b30f9ac1343" + ] + }, + "Body": "" + } + }, + { + "ID": "0d3373437d25b539", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "222" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY05vblVURjhNZXNzYWdlQm9keS1zdWItMSZQcm90b2NvbD1zcXMmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBU05TVG9waWNOb25VVEY4TWVzc2FnZUJvZHktdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "382" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:03 GMT" + ], + "X-Amzn-Requestid": [ + "7e45b934-8483-5f11-b974-d9c0443cb6fa" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljTm9uVVRGOE1lc3NhZ2VCb2R5LXRvcC0xOmFjOTJkYmYyLTU3NDAtNGY2OC1hOTRlLTUyNmNlZTE0ODUxMzwvU3Vic2NyaXB0aW9uQXJuPgogIDwvU3Vic2NyaWJlUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD43ZTQ1YjkzNC04NDgzLTVmMTEtYjk3NC1kOWMwNDQzY2I2ZmE8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvU3Vic2NyaWJlUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "bec022f6f138cc9c", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "747" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9QUFFQ0F3UUZCZ2NJQ1FvTERBME9EeEFSRWhNVUZSWVhHQmthR3h3ZEhoOGdJU0lqSkNVbUp5Z3BLaXNzTFM0dk9qczhQVDQlMkZRRnRjWFY1ZllIdDhmWDUlMkZabTl2WEdKaGNseGlZWG91TGx4bWIyOWNMaTVjWW1GeVhDNHVYQzR1WEdKaGVpNHVYQzR1TDJadmJ5OHVMaTlpWVhJdkxpNHZMaTR2WW1GNkxpNHZabTl2TDJKaGNpOWlZWHBtYjI4aVltRnlJbUpoZWk0dVhHWnZiMXhjWW1GeVhGeGNZbUY2Wm05dkx5OWlZWEl2THk5aVlYcG1iMjhnWW1GeUlHSmhlakV5TXpRMTRwaTY0cGk2NHBpNnZiSSUzRCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:03 GMT" + ], + "X-Amzn-Requestid": [ + "2b06a2f1-5028-5cda-af47-c20590975531" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjUzZDY2YTMzLTA0NTgtNTEwNi1hOWE2LTBhYzdjNGU3YzhlZDwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjJiMDZhMmYxLTUwMjgtNWNkYS1hZjQ3LWMyMDU5MDk3NTUzMTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "cb8f4265efb06a9c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "177" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2114" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:03 GMT" + ], + "X-Amzn-Requestid": [ + "50979159-0dd9-5251-a8d3-f1adcd66b89a" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyMzkzMyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjIzODU0In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiNTNkNjZhMzMtMDQ1OC01MTA2LWE5YTYtMGFjN2M0ZTdjOGVkXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY05vblVURjhNZXNzYWdlQm9keS10b3AtMVwiLFxuICBcIk1lc3NhZ2VcIiA6IFwiQUFFQ0F3UUZCZ2NJQ1FvTERBME9EeEFSRWhNVUZSWVhHQmthR3h3ZEhoOGdJU0lqSkNVbUp5Z3BLaXNzTFM0dk9qczhQVDQvUUZ0Y1hWNWZZSHQ4Zlg1L1ptOXZYR0poY2x4aVlYb3VMbHhtYjI5Y0xpNWNZbUZ5WEM0dVhDNHVYR0poZWk0dVhDNHVMMlp2Ynk4dUxpOWlZWEl2TGk0dkxpNHZZbUY2TGk0dlptOXZMMkpoY2k5aVlYcG1iMjhpWW1GeUltSmhlaTR1WEdadmIxeGNZbUZ5WEZ4Y1ltRjZabTl2THk5aVlYSXZMeTlpWVhwbWIyOGdZbUZ5SUdKaGVqRXlNelExNHBpNjRwaTY0cGk2dmJJPVwiLFxuICBcIlRpbWVzdGFtcFwiIDogXCIyMDI1LTA3LTE4VDIxOjM3OjAzLjgxNFpcIixcbiAgXCJTaWduYXR1cmVWZXJzaW9uXCIgOiBcIjFcIixcbiAgXCJTaWduYXR1cmVcIiA6IFwiVjFMQ2ZsbDcvUXJzZVZYUUpWY1ZxZDB6UE1Ucm95WDY3VmNOWnI0QlJQekU5cEwrcitkOVA5VWJLWnV1Q2l5cFhtV2owZ05HNWQxYys1Uk5wNEVnNU9NZm5EMUI4SzY2MXRpWTlDQUlKNmpTcmovSWsxMS9OL2oyUDh6QWZrdHkxSnRLZmxNeHNyNzQ2Uk5DZ3NsQm1NemNIcGdhYlNZa252WkowUDkxdngzeWFnT1RKUGRNb1JwOVVOZTNkalZyMUxURTZiWlhoRGJGOHJoZml6Q1V5OVVXMUtxTnUxb1oyYkxYN3dqemp4OXB4QTFWUlVuUjRWUzFycEpPZ2Znd1VlaXlnZWRFbVBBTVgzWkxYY3FzOHV2cVgxeENIdklJMzR3MTJnTWM4WFNZZCttRTZoMDZvZU5hd1RwTWFkc2thNFhtY1FmRytRZFl6MG9xL0ljbnd3PT1cIixcbiAgXCJTaWduaW5nQ2VydFVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS9TaW1wbGVOb3RpZmljYXRpb25TZXJ2aWNlLTljNjQ2NWZhN2Y0OGY1Y2FjZDIzMDE0NjMxZWMxMTM2LnBlbVwiLFxuICBcIlVuc3Vic2NyaWJlVVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLz9BY3Rpb249VW5zdWJzY3JpYmUmU3Vic2NyaXB0aW9uQXJuPWFybjphd3M6c25zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6U05TVG9waWNOb25VVEY4TWVzc2FnZUJvZHktdG9wLTE6YWM5MmRiZjItNTc0MC00ZjY4LWE5NGUtNTI2Y2VlMTQ4NTEzXCIsXG4gIFwiTWVzc2FnZUF0dHJpYnV0ZXNcIiA6IHtcbiAgICBcImJhc2U2NGVuY29kZWRcIiA6IHtcIlR5cGVcIjpcIlN0cmluZ1wiLFwiVmFsdWVcIjpcInRydWVcIn1cbiAgfVxufSIsIk1ENU9mQm9keSI6IjBhZTc1ZTgwZmEwNTJjOTI0ZThiNzdhMjVmYTg1NTk5IiwiTWVzc2FnZUlkIjoiNzUxNDI3YmItYWRmNS00ZjE5LWIwYjMtY2U3NjIyMWU4MzU0IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJhVHpsbDVSaExpMjVYcFg2VHRCdmZmcFV6QXRjVTRXeDJVL0d4Y2dVVUtxcHViWjVGZ1hMV1Y4RjJTZkJkem9vZEhESWJwSUdBRXNkbGNESitydzB1SDNaRTVsaHdiTnBMNlpBT2F0bHlVMnhCcGFqc3BZZUVvMlNlT1REWUxIT281d3BuQWl4eVBZckVjTml1TmJScjh5bnZGRWQ2SnhRcktIQUpHRlNKVDZXVWVOUHp5cjJGU2N1VWx4YXpvR1lkRnI0M2ZLVlEwRnJSSW9xMHRzNGZkUDVRMkNMb1E5VmNUcjBPcDRnWWtZcTQ1YVdrYkdLY1Z2Q3dFSGJWZGdKRzZGVERXcUdYbEtUS2lJRjEvOVRzZ0VUSVNIaTgrR0tralFubi9RdlJBUVVvSEZkRXl0NDRBNGZoUmhBaFlLd0JVQ29McVB0QWJWeDhjZ25HSlI5WXBocFBiZzkzQ0dwNUhCWlRTMlUzU3ViYmx4MXNRQVRteEFvT1p1RTczOExrUlBnWUdoYVhzdEFjbFByNlJ0SU1weWRrZUw5RWJlVlRRZmNmM08rSFIwPSJ9XX0=" + } + }, + { + "ID": "5f3eb5efc061bc94", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "570" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmFUemxsNVJoTGkyNVhwWDZUdEJ2ZmZwVXpBdGNVNFd4MlUvR3hjZ1VVS3FwdWJaNUZnWExXVjhGMlNmQmR6b29kSERJYnBJR0FFc2RsY0RKK3J3MHVIM1pFNWxod2JOcEw2WkFPYXRseVUyeEJwYWpzcFllRW8yU2VPVERZTEhPbzV3cG5BaXh5UFlyRWNOaXVOYlJyOHludkZFZDZKeFFyS0hBSkdGU0pUNldVZU5QenlyMkZTY3VVbHhhem9HWWRGcjQzZktWUTBGclJJb3EwdHM0ZmRQNVEyQ0xvUTlWY1RyME9wNGdZa1lxNDVhV2tiR0tjVnZDd0VIYlZkZ0pHNkZURFdxR1hsS1RLaUlGMS85VHNnRVRJU0hpOCtHS2tqUW5uL1F2UkFRVW9IRmRFeXQ0NEE0ZmhSaEFoWUt3QlVDb0xxUHRBYlZ4OGNnbkdKUjlZcGhwUGJnOTNDR3A1SEJaVFMyVTNTdWJibHgxc1FBVG14QW9PWnVFNzM4TGtSUGdZR2hhWHN0QWNsUHI2UnRJTXB5ZGtlTDlFYmVWVFFmY2YzTytIUjA9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:03 GMT" + ], + "X-Amzn-Requestid": [ + "c7ed39cd-a1b0-5965-8a8a-5939610f63ae" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "e340cfbab4fac347", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY05vblVURjhNZXNzYWdlQm9keS10b3AtMSUzQWFjOTJkYmYyLTU3NDAtNGY2OC1hOTRlLTUyNmNlZTE0ODUxMyZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:04 GMT" + ], + "X-Amzn-Requestid": [ + "330ef2bf-a1bc-58fc-837b-924b617cc117" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4zMzBlZjJiZi1hMWJjLTU4ZmMtODM3Yi05MjRiNjE3Y2MxMTc8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "6da78eb6c2b31eab", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "96" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:04 GMT" + ], + "X-Amzn-Requestid": [ + "f0c7d8c0-5960-5285-84fd-b83499a0d84e" + ] + }, + "Body": "" + } + }, + { + "ID": "8497df7b12df04c9", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "124" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljTm9uVVRGOE1lc3NhZ2VCb2R5LXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:04 GMT" + ], + "X-Amzn-Requestid": [ + "2488dfc8-5e6f-5e19-b897-bf3c9eaf67f2" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4yNDg4ZGZjOC01ZTZmLTVlMTktYjg5Ny1iZjNjOWVhZjY3ZjI8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestSendReceive.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestSendReceive.replay new file mode 100644 index 000000000..0a4930ad0 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestSendReceive.replay @@ -0,0 +1,991 @@ +{ + "Initial": "AQAAAA7gDLWHLhPwAwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "61c29de76f5c73df", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNTZW5kUmVjZWl2ZS10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "332" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:12 GMT" + ], + "X-Amzn-Requestid": [ + "273cac5e-1591-5d9e-9f95-ccaad5563e70" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmUtdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjI3M2NhYzVlLTE1OTEtNWQ5ZS05Zjk1LWNjYWFkNTU2M2U3MDwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "8a3f41fb523b1330", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "41" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "89" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:12 GMT" + ], + "X-Amzn-Requestid": [ + "9b65b965-d779-5299-8a6e-d99117b1d33f" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + } + }, + { + "ID": "e45acf150c8e4713", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "119" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "90" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:12 GMT" + ], + "X-Amzn-Requestid": [ + "939543cd-b9d4-5dac-8ccf-2339791c5c0a" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn19" + } + }, + { + "ID": "a1b3649ad12836b8", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "464" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmUtc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:12 GMT" + ], + "X-Amzn-Requestid": [ + "c24e972c-0ea3-5662-a081-f7d8ce6b47c4" + ] + }, + "Body": "" + } + }, + { + "ID": "9f570e562c1dfeeb", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "208" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "375" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:12 GMT" + ], + "X-Amzn-Requestid": [ + "b48a4d16-2563-518d-a608-2de2e5ab7263" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmUtdG9wLTE6Yjg2Zjc1ZjItYzNiNy00MTEwLTlhOTgtYjBjMDUyZDc1NjY5PC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmI0OGE0ZDE2LTI1NjMtNTE4ZC1hNjA4LTJkZTJlNWFiNzI2MzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "2925be84322e1022", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "440" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:12 GMT" + ], + "X-Amzn-Requestid": [ + "b87b2d83-e54d-5b79-9a9a-4d7725851897" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmJiYTI3M2I2LTQ2ZTQtNWQ1MC05OGVlLTEzNDI4NjJjOWViZTwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmI4N2IyZDgzLWU1NGQtNWI3OS05YTlhLTRkNzcyNTg1MTg5NzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "9c62ce4ea5dd33bb", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "440" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MSZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:12 GMT" + ], + "X-Amzn-Requestid": [ + "7c0bfe4d-1c3e-5557-bc36-9eb9dcf606b9" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmYwMDNhMWQ5LWNhYjUtNTA0YS05M2Q4LWMxMmQwYTdkMjNhNDwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjdjMGJmZTRkLTFjM2UtNTU1Ny1iYzM2LTllYjlkY2Y2MDZiOTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "d37fdfbb8ba1f2e2", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "440" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MiZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:12 GMT" + ], + "X-Amzn-Requestid": [ + "7f0ed5dc-9f90-5962-93c1-b5285f58ca8c" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjBmMGE1ODVhLTVmZTMtNWUyOC04MmM4LTM4YWU5ZjJiOGRjNjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjdmMGVkNWRjLTlmOTAtNTk2Mi05M2MxLWI1Mjg1ZjU4Y2E4YzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "1c0268c67e7b45fb", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1806" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:12 GMT" + ], + "X-Amzn-Requestid": [ + "4cb096e0-828e-53af-91f3-f6144246e209" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzMjg5NSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjMyODU5In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiMGYwYTU4NWEtNWZlMy01ZTI4LTgyYzgtMzhhZTlmMmI4ZGM2XCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCIyXCIsXG4gIFwiVGltZXN0YW1wXCIgOiBcIjIwMjUtMDctMThUMjE6Mzc6MTIuODMyWlwiLFxuICBcIlNpZ25hdHVyZVZlcnNpb25cIiA6IFwiMVwiLFxuICBcIlNpZ25hdHVyZVwiIDogXCJUeSsvQk50Z0t1anFxR1B1cmVhUXhTenc1ZCtJUHZ5THhGMmVhZG9PNGNOVWV3VzJZSmVIVEg5SVo3ZE5oL3FZTXNVeFJ4MzBNaVVtS2pUN1hTZitCYmNqSDJtMWh4cUhqd3hlY1dNTkdZV09VYVR0a3hRWXZPbWJsRGk3c3pMdE1Bem5mcGtEbFhJNGFRemc0STNnZElkTjUvQll5OUQ5dDNScmovSWtQOVQyRWRyK1I4ZDlhaWh0UDdiVHl6VEVmTUhqZTdvT21vVUQzamFZR2tZbkxsdEFwQVVMbGhTSnZTRC9RWXpObVFWeFdzc3NCbG9TVkZIQlc1emNlbExmQnpScVl2cGZoSVRva1U3MHY1SHRNTVBTU0UrTkp4bWdENVo1Q2Vpc0k1UUZ3VU03bUYrMVpGNWV0N2R0SUY0dWQrY3pBa0xvL2l6VllUdGMvejdCdEE9PVwiLFxuICBcIlNpZ25pbmdDZXJ0VVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL1NpbXBsZU5vdGlmaWNhdGlvblNlcnZpY2UtOWM2NDY1ZmE3ZjQ4ZjVjYWNkMjMwMTQ2MzFlYzExMzYucGVtXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xOmI4NmY3NWYyLWMzYjctNDExMC05YTk4LWIwYzA1MmQ3NTY2OVwiLFxuICBcIk1lc3NhZ2VBdHRyaWJ1dGVzXCIgOiB7XG4gICAgXCJhXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIyXCJ9XG4gIH1cbn0iLCJNRDVPZkJvZHkiOiI0YWI3Y2I4YjNhMTc1OWY3ZjFmNDMzYTA4MjE1ZWU0OSIsIk1lc3NhZ2VJZCI6IjRkMWUyNGY5LWU3NWItNDg3Ni05OGJiLTViZjU0MGYwMjQyMiIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCeXozV1oyc3RDNkRXRnhidlRMNkEvMitJeHZYS0lMQjRFazdYaWxFVldUdHoxRmt4N0daUElZMElyMDVORmhZUDZ6Ri91VStmMHRkdzBMQWkxdTdCTW1BcE9LS1lOTjNIYklFcjVaaFNpY2NoT3RhYmc2anlnbVpvR1FscmxXaW5yTmVuRmhqUEVSV1J4amowWURDNUczOFhNcXk0Z1hVYjRETGx5a1ByT0YydFZreXF2cXoydHNXOExETUkzeFBUeThwajhZSHI5eHpXSzkwS3NFNWJtN29CbklXZXoxRlUwcncvaGV3YUhqNE0xZmZrWlpOV1BEd3FqTzd2MU1QS3FkS3RWTWsxS0FWbWRaRDJvSG1uY2RoSkpEeUs5TGtGSVM5TlhDc0tjY3J0WnVwV2FxSm1RTXA3LzdRRmJjbTdFblJ2Nkx6cjZSOVNtSHBhSUtKR2liVUR3WkNEYWIxMUZvYWRaOWlZcW5Ia1RBM0ZCbDZZRThiNWovUUlJSi84VVhYejVpK2tTaG8wTS9RaVlHSk5yakJsYXZRdjdlOHBjcjRMeHBWZDU3Yz0ifV19" + } + }, + { + "ID": "57ef0b0819212b3a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "563" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnl6M1daMnN0QzZEV0Z4YnZUTDZBLzIrSXh2WEtJTEI0RWs3WGlsRVZXVHR6MUZreDdHWlBJWTBJcjA1TkZoWVA2ekYvdVUrZjB0ZHcwTEFpMXU3Qk1tQXBPS0tZTk4zSGJJRXI1WmhTaWNjaE90YWJnNmp5Z21ab0dRbHJsV2luck5lbkZoalBFUldSeGpqMFlEQzVHMzhYTXF5NGdYVWI0RExseWtQck9GMnRWa3lxdnF6MnRzVzhMRE1JM3hQVHk4cGo4WUhyOXh6V0s5MEtzRTVibTdvQm5JV2V6MUZVMHJ3L2hld2FIajRNMWZma1paTldQRHdxak83djFNUEtxZEt0Vk1rMUtBVm1kWkQyb0htbmNkaEpKRHlLOUxrRklTOU5YQ3NLY2NydFp1cFdhcUptUU1wNy83UUZiY203RW5SdjZMenI2UjlTbUhwYUlLSkdpYlVEd1pDRGFiMTFGb2FkWjlpWXFuSGtUQTNGQmw2WUU4YjVqL1FJSUovOFVYWHo1aStrU2hvME0vUWlZR0pOcmpCbGF2UXY3ZThwY3I0THhwVmQ1N2M9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:12 GMT" + ], + "X-Amzn-Requestid": [ + "e13502ae-599b-57a2-a827-625a99536604" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "25fb6c248abd9683", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1806" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:13 GMT" + ], + "X-Amzn-Requestid": [ + "91cc9e53-cf18-5a09-a25a-fea70fd1cbaf" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzMzAxMCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjMyODAyIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiZjAwM2ExZDktY2FiNS01MDRhLTkzZDgtYzEyZDBhN2QyM2E0XCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCIxXCIsXG4gIFwiVGltZXN0YW1wXCIgOiBcIjIwMjUtMDctMThUMjE6Mzc6MTIuNzYzWlwiLFxuICBcIlNpZ25hdHVyZVZlcnNpb25cIiA6IFwiMVwiLFxuICBcIlNpZ25hdHVyZVwiIDogXCJXOWNBRWp4LzZSSTNBaHJDWTNtUTFteC9Ib0pMNExFTFM4cTBNUDB3SDBxa0s3VG16b0NSR2dWZmhvcjluTjhNM0NnaktKUDhxRVZpVWJ3cjZtSkNiaFBMWnE4RytPV1ErMEx3NzlJaTV0dkRhRCs5UHV1aisxMHRyaTNObGZuYVF4c3R3NGRydmRYZXJxNng4aU8xdGI3SzNVaGdCaHVHQnVYZ2RiSE5nZjJVQmM5M2FaNXBMbjRLNXh2MWkxbVZNV0ZoeEtFOWpYWlk0bE1wekx0T3JsdzhMcVJyRDBPbmtZSjZuTWJjQzM0V1BHNEZqbkN2N2lqYVh1eUZOQ1d5cEdrWkRBcEY3SmxJRVNQZ3RyMjNSSmJtSG1jd3NheThhYkhyNUNsOW9Bei9rZ21sVEgrb2FHRElXN05KcU1jb1hwQmJVOGdwWXk1YUwvNVJtQkUvbmc9PVwiLFxuICBcIlNpZ25pbmdDZXJ0VVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL1NpbXBsZU5vdGlmaWNhdGlvblNlcnZpY2UtOWM2NDY1ZmE3ZjQ4ZjVjYWNkMjMwMTQ2MzFlYzExMzYucGVtXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xOmI4NmY3NWYyLWMzYjctNDExMC05YTk4LWIwYzA1MmQ3NTY2OVwiLFxuICBcIk1lc3NhZ2VBdHRyaWJ1dGVzXCIgOiB7XG4gICAgXCJhXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIxXCJ9XG4gIH1cbn0iLCJNRDVPZkJvZHkiOiI3YTNmYjdjYTcwMjlmZGVlM2MxMDdlZmJiNmUyYjkyZCIsIk1lc3NhZ2VJZCI6IjE1NmNmYzg5LTFkM2QtNGY1MS04ZjA0LTljMGE2YzMxNzI1NSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCUDNkWGV0K3d3ZUxIQWxTNmRrMXJYRkxDUU9EYXRyRG0zamZYL0Y2enM0NHdmczloQWNhUDBuYXp5aDNsT080dXdJL09ITk90Q1BRQ0IzTkp1ZnJNYVRGd0g0c3dWQzBwRXpOVTRJUUJRbWxkVk41NkdBSzByT1V5Z3U0RnRkQnMyWXRnL0FuUFpJVnhpaVhUUWlLUjVoVDRSOFhyVEFBQ3JqeklJSFd5aDZZNEZsVTZ3dDdKQUFQWFAvMUlHak5aUlpZaG8reTYzNDNOTDh3T3NocHFXYlFwMExOQ3JicVVQSEVDOUhWdjRvSGNjSHJGMkVxU0IrMjNxSjNRUDRRQnFJWFhTQ3VKdjc5SS9jdlI4aWZrTURieGVUWnJpQVNId3dKVUZqSDI4R3JVb0lvczYyeGRCSXlTZzVFcXhoV0thVnI0TW1JSFg3S21aRm1xSlQvbUJsZDUvaExBK3h0VGJqSkl0OExvUkpyT242Ni9GRU53WWhPMGdFV2dtaUJIRWtrZEdFRys5eTdWL25FaG5PNnExVGhHSHJ2b0tKMHY3NDhVWHR2MkFtaz0ifV19" + } + }, + { + "ID": "a358d44059f553d6", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1806" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:13 GMT" + ], + "X-Amzn-Requestid": [ + "9dcb555b-4014-557a-8672-35af80dd14dc" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYzMzA3MyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjMyNzMyIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiYmJhMjczYjYtNDZlNC01ZDUwLTk4ZWUtMTM0Mjg2MmM5ZWJlXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCIwXCIsXG4gIFwiVGltZXN0YW1wXCIgOiBcIjIwMjUtMDctMThUMjE6Mzc6MTIuNjk5WlwiLFxuICBcIlNpZ25hdHVyZVZlcnNpb25cIiA6IFwiMVwiLFxuICBcIlNpZ25hdHVyZVwiIDogXCJjWFhhRFRhV0hqaTRKTGcxdThmQld5S0hubjJrTnpycXVWeU13bmQ3Zi9Zc0xCemcybkpkK1ZLVGhBbzRsRjZPN2VBZmJqYytWak9uNmpRUzhXeFltdWhZWlB6dzYzMVcza1pDRUJpcGppM1lpMGRGanYzeittMEdCVndqNC9PVUtkOER5SDlhTklrSWZoOWFlUjFvbHJVdG96RVY4OVJnL1NNYjVRcnJCbkE0eEFEaWowV0FEblhFbWNONGNyS3FtbFNWYTY3SjRUVytzVDhCcWpjakpudVV3ejFvMDdOYWMzS0hVU3BOcGVabllJcmVOQWkzTW1mUUFOMFpxbGVSaGo1ck5mbnZxQjZTRlRPNzMwMHp0UkQwODBoQnlranFDRHFUV2FsaEJtTXdkNUVFOEFqaXFLdWRyYjhPSzkxaXdQeXN2OWVqSDVFUk4zby80LytUUWc9PVwiLFxuICBcIlNpZ25pbmdDZXJ0VVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL1NpbXBsZU5vdGlmaWNhdGlvblNlcnZpY2UtOWM2NDY1ZmE3ZjQ4ZjVjYWNkMjMwMTQ2MzFlYzExMzYucGVtXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xOmI4NmY3NWYyLWMzYjctNDExMC05YTk4LWIwYzA1MmQ3NTY2OVwiLFxuICBcIk1lc3NhZ2VBdHRyaWJ1dGVzXCIgOiB7XG4gICAgXCJhXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIwXCJ9XG4gIH1cbn0iLCJNRDVPZkJvZHkiOiJlOTJkMzlmNmRmYTY5NWNkNjU4NDM2NzAwZTExZWY1NSIsIk1lc3NhZ2VJZCI6IjJkODFkMjAwLTlkZDQtNDk3Yi04Y2RlLTM2OTQyYjM2MjBiYiIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCK0hZcFV5bTV5OXI5R2VUTFF0Ym9lTHlVRjdONjRCZCtYNkNuaFZVNjNaNjBhVWR2eTJ2aVdQamtBMi9TVWxjRFdyTUpVR29iQkRsa2pWa0pRam9Db2JSSjNoang3dzFaeUFiblhUSk5aYS9aa09TeEdoZk9wRWhMN1pxcVoxekNTTTRZY1Y1WEY1TnJJQVVFQ2dqZWNRSDdKcFpRRDBHb1kxV0srRGUvQ2Myd2VBTGN4dG1HMGFHNUJoMGhFT05GbjdXSEo2RWpyYmMySE1uR2RwMUFNN1AwQUxIVGtLVzMyaXB1cjZWNzYyaU9ZVVZHOVQ2NGlZRUVEa1puOUJtUWZ5TUJ2WG9KOUZTeDJETWp5RGJsYWlLdVJCS0NybVJ2SjlFRCs4cXNzczY0cC9aa3JSVktYN2hHMmMyMnhITmprMzBkNXZuZXp0L0VFUFA1NENWYjhHcmxDQ21yUm55YWRNYXNWWUR3ckNRNEZCL2ZpdU5aMlJjLzRZUGVSaXJqbTBTMUU0aUR5Z0kvZmZuUWdzME9iYjJkelZKclVVUnZKek1TaW9WTDZmaz0ifV19" + } + }, + { + "ID": "d96e41ed81799055", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "563" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlAzZFhldCt3d2VMSEFsUzZkazFyWEZMQ1FPRGF0ckRtM2pmWC9GNnpzNDR3ZnM5aEFjYVAwbmF6eWgzbE9PNHV3SS9PSE5PdENQUUNCM05KdWZyTWFURndINHN3VkMwcEV6TlU0SVFCUW1sZFZONTZHQUswck9VeWd1NEZ0ZEJzMll0Zy9BblBaSVZ4aWlYVFFpS1I1aFQ0UjhYclRBQUNyanpJSUhXeWg2WTRGbFU2d3Q3SkFBUFhQLzFJR2pOWlJaWWhvK3k2MzQzTkw4d09zaHBxV2JRcDBMTkNyYnFVUEhFQzlIVnY0b0hjY0hyRjJFcVNCKzIzcUozUVA0UUJxSVhYU0N1SnY3OUkvY3ZSOGlma01EYnhlVFpyaUFTSHd3SlVGakgyOEdyVW9Jb3M2MnhkQkl5U2c1RXF4aFdLYVZyNE1tSUhYN0ttWkZtcUpUL21CbGQ1L2hMQSt4dFRiakpJdDhMb1JKck9uNjYvRkVOd1loTzBnRVdnbWlCSEVra2RHRUcrOXk3Vi9uRWhuTzZxMVRoR0hydm9LSjB2NzQ4VVh0djJBbWs9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:13 GMT" + ], + "X-Amzn-Requestid": [ + "d11463d1-0242-5766-a29e-0325c28bf16b" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "b018a652d3027b0e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "563" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQitIWXBVeW01eTlyOUdlVExRdGJvZUx5VUY3TjY0QmQrWDZDbmhWVTYzWjYwYVVkdnkydmlXUGprQTIvU1VsY0RXck1KVUdvYkJEbGtqVmtKUWpvQ29iUkozaGp4N3cxWnlBYm5YVEpOWmEvWmtPU3hHaGZPcEVoTDdacXFaMXpDU000WWNWNVhGNU5ySUFVRUNnamVjUUg3SnBaUUQwR29ZMVdLK0RlL0NjMndlQUxjeHRtRzBhRzVCaDBoRU9ORm43V0hKNkVqcmJjMkhNbkdkcDFBTTdQMEFMSFRrS1czMmlwdXI2Vjc2MmlPWVVWRzlUNjRpWUVFRGtabjlCbVFmeU1CdlhvSjlGU3gyRE1qeURibGFpS3VSQktDcm1Sdko5RUQrOHFzc3M2NHAvWmtyUlZLWDdoRzJjMjJ4SE5qazMwZDV2bmV6dC9FRVBQNTRDVmI4R3JsQ0NtclJueWFkTWFzVllEd3JDUTRGQi9maXVOWjJSYy80WVBlUmlyam0wUzFFNGlEeWdJL2ZmblFnczBPYmIyZHpWSnJVVVJ2SnpNU2lvVkw2Zms9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:13 GMT" + ], + "X-Amzn-Requestid": [ + "c2550caa-d60c-5b7c-9fd9-6c5e16c5ed71" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "30e18becc3379765", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xJTNBYjg2Zjc1ZjItYzNiNy00MTEwLTlhOTgtYjBjMDUyZDc1NjY5JlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:13 GMT" + ], + "X-Amzn-Requestid": [ + "7c44eec5-161e-5bea-b235-8e31d6d77804" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD43YzQ0ZWVjNS0xNjFlLTViZWEtYjIzNS04ZTMxZDZkNzc4MDQ8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "4817483e08dfa68b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "89" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:13 GMT" + ], + "X-Amzn-Requestid": [ + "5ad49b9c-03aa-54ee-94f0-fb68c3633265" + ] + }, + "Body": "" + } + }, + { + "ID": "a23f5da534e5171c", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "117" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljU2VuZFJlY2VpdmUtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:13 GMT" + ], + "X-Amzn-Requestid": [ + "f698e4ce-a843-525a-a841-843a688a41b4" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5mNjk4ZTRjZS1hODQzLTUyNWEtYTg0MS04NDNhNjg4YTQxYjQ8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestSendReceiveJSON.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestSendReceiveJSON.replay new file mode 100644 index 000000000..8bcd2bf3d --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestSendReceiveJSON.replay @@ -0,0 +1,655 @@ +{ + "Initial": "AQAAAA7gDLWDCuAoyAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "c2c9a11ed8d35af1", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNTZW5kUmVjZWl2ZUpTT04tdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "336" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:07 GMT" + ], + "X-Amzn-Requestid": [ + "3130dcb3-d540-5b5a-a79a-bc4715834cdf" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmVKU09OLXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4zMTMwZGNiMy1kNTQwLTViNWEtYTc5YS1iYzQ3MTU4MzRjZGY8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "280e06bdecf4373c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "45" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "93" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:07 GMT" + ], + "X-Amzn-Requestid": [ + "40c4f5f3-fc19-5ada-8a1b-95073cda5a96" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + } + }, + { + "ID": "6989a997bfc67b40", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "94" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:07 GMT" + ], + "X-Amzn-Requestid": [ + "22618d9b-daec-55d0-bbb8-ed6f1a2fa59c" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9fQ==" + } + }, + { + "ID": "d65ee2faec10156c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "472" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmVKU09OLXN1Yi0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNTZW5kUmVjZWl2ZUpTT04tc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:07 GMT" + ], + "X-Amzn-Requestid": [ + "45dc297f-f5ea-5711-8cc5-498b3529e75d" + ] + }, + "Body": "" + } + }, + { + "ID": "2c420f7b5964f745", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "216" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlSlNPTi1zdWItMSZQcm90b2NvbD1zcXMmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBU05TVG9waWNTZW5kUmVjZWl2ZUpTT04tdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "379" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:08 GMT" + ], + "X-Amzn-Requestid": [ + "34f1313c-2ad8-5ac0-88b6-51c8ea1b7d45" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmVKU09OLXRvcC0xOmY1ZTM1ZGY5LTg3MjItNDU3OC1hMWFkLWM0YzlhZWRkNmExOTwvU3Vic2NyaXB0aW9uQXJuPgogIDwvU3Vic2NyaWJlUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4zNGYxMzEzYy0yYWQ4LTVhYzAtODhiNi01MWM4ZWExYjdkNDU8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvU3Vic2NyaWJlUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "61a22953960489a9", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "236" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9JTdCJTIyRm9vJTIyJTNBKyUyMkJhciUyMiU3RCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlSlNPTi10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:08 GMT" + ], + "X-Amzn-Requestid": [ + "8beb6d3e-495e-5577-ac7c-0dca899a62f2" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmU4Y2VkZjY3LTA1YTYtNThiYi1hMWE3LWJmOTNjNTYyNmYzZTwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjhiZWI2ZDNlLTQ5NWUtNTU3Ny1hYzdjLTBkY2E4OTlhNjJmMjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "40e9b927b363c4a7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "174" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1753" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:08 GMT" + ], + "X-Amzn-Requestid": [ + "de1488d1-225a-527a-b4b9-e825e29ec236" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyODE3NyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI4MTM5In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiZThjZWRmNjctMDVhNi01OGJiLWExYTctYmY5M2M1NjI2ZjNlXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlSlNPTi10b3AtMVwiLFxuICBcIk1lc3NhZ2VcIiA6IFwie1xcXCJGb29cXFwiOiBcXFwiQmFyXFxcIn1cIixcbiAgXCJUaW1lc3RhbXBcIiA6IFwiMjAyNS0wNy0xOFQyMTozNzowOC4xMTBaXCIsXG4gIFwiU2lnbmF0dXJlVmVyc2lvblwiIDogXCIxXCIsXG4gIFwiU2lnbmF0dXJlXCIgOiBcImpIcWdLVFRpRXEvN1ZVaHg0MExsZjhTKzJWVnBtVEMwbEhhUW5QMDZYYXVSM2kzRmhEdTFNVXNFQUhWbTlBbFhVMHVxaTFLK1JYYXRlTG9UU0QwYXhpREpVTkVpZDg2ZjVFbENjbVdmYlB2R2tXRWphNjg2ZEVRcWJOZTFkV0xGc1ZuNW5WYWlEYU92dTlrZS94K1FQTDRQZURYZjhocTNBcVRYVy9zM1lxdERoTUhqR21DOG5rcTk5WW1Ja0NlOCs4VVJENy9JaDVEaG9GNEd0WUJNWU1ra3FqUTI2dVhSMTM4eUlOaG5HWWRmY3FySzk3ZEV6TUVqTzRBUnN5bEVXSHg3QXhQYmdxZ2ltY3AxWndtZkpxOVJSY0hnUXhLYWJUTU1yUmJrRkpZQldpQTNEV3RwUmhiUVpMUDVobDloR3VnMklpSFFzNHJrRTg4WE1UTWFhUT09XCIsXG4gIFwiU2lnbmluZ0NlcnRVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vU2ltcGxlTm90aWZpY2F0aW9uU2VydmljZS05YzY0NjVmYTdmNDhmNWNhY2QyMzAxNDYzMWVjMTEzNi5wZW1cIixcbiAgXCJVbnN1YnNjcmliZVVSTFwiIDogXCJodHRwczovL3Nucy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS8/QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmVKU09OLXRvcC0xOmY1ZTM1ZGY5LTg3MjItNDU3OC1hMWFkLWM0YzlhZWRkNmExOVwiXG59IiwiTUQ1T2ZCb2R5IjoiNjdkODlkYTYzZTI2MDBmOTIyMzE5MDA5YmZiYzNkZWMiLCJNZXNzYWdlSWQiOiJjZGMwNzFjZi0yMWYzLTQwYTAtODc0NS1kN2ZkYzQ2ZjYzOWEiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmo2d3Z2Q1h5Z2JybWYzajJ3N1U1WFRqSFRKK0VzTitRckxaZVpqVncxdGdZSVR6QVJRVXJrcnU0QmluWHRsalZ3U2ZCRGRSdEd0Tk1INlJBVHViYWZoSS9FRzRpdXFPdDBPd1NTSVlDN29YQmxqOW9BaTBMVGFjbmFxaC9IbGNubHRDZUhHdHJIbkNCanFXN0ZYRTJSU2tRVWFPbHBFeWp3YXFaV1pKcE95RGZ1ZG5hOFhaaXQySFNFMEJyT3RUayt1amIzbzREdXkya2RzZklvWTI2VUV5dTdpQzZIanB2VUxXUzAwUnlBa0NFMk5iSnNJaFhPQzRrU2xaNVcyak8zMkZFcjZteXJwR3FZSDVBVGxkK0w2aWQ5Y0RnUE9wZjhwcGxRN1VoRWo1UU12SDFSY3EzM1hHNUQxb2VEQUc1TXVSZTh6OGd3MnNFcS9icUQ3OGNYcUNIdGJMaHlSL1BVVWJhZGFuaVllTlY5OXpwak45T294Mm5yL0czVW5lSFI0ZTU1b09Sb214dmFyN0R2T2haL0k1cW9LUmwvU2JlYXhwMnp1WmxjSk09In1dfQ==" + } + }, + { + "ID": "ce718d323b745115", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "567" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmo2d3Z2Q1h5Z2JybWYzajJ3N1U1WFRqSFRKK0VzTitRckxaZVpqVncxdGdZSVR6QVJRVXJrcnU0QmluWHRsalZ3U2ZCRGRSdEd0Tk1INlJBVHViYWZoSS9FRzRpdXFPdDBPd1NTSVlDN29YQmxqOW9BaTBMVGFjbmFxaC9IbGNubHRDZUhHdHJIbkNCanFXN0ZYRTJSU2tRVWFPbHBFeWp3YXFaV1pKcE95RGZ1ZG5hOFhaaXQySFNFMEJyT3RUayt1amIzbzREdXkya2RzZklvWTI2VUV5dTdpQzZIanB2VUxXUzAwUnlBa0NFMk5iSnNJaFhPQzRrU2xaNVcyak8zMkZFcjZteXJwR3FZSDVBVGxkK0w2aWQ5Y0RnUE9wZjhwcGxRN1VoRWo1UU12SDFSY3EzM1hHNUQxb2VEQUc1TXVSZTh6OGd3MnNFcS9icUQ3OGNYcUNIdGJMaHlSL1BVVWJhZGFuaVllTlY5OXpwak45T294Mm5yL0czVW5lSFI0ZTU1b09Sb214dmFyN0R2T2haL0k1cW9LUmwvU2JlYXhwMnp1WmxjSk09In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:08 GMT" + ], + "X-Amzn-Requestid": [ + "db689d75-f8b6-5c2d-bbc4-fd8138725c61" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "3c4fa178e481c5e3", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlSlNPTi10b3AtMSUzQWY1ZTM1ZGY5LTg3MjItNDU3OC1hMWFkLWM0YzlhZWRkNmExOSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:08 GMT" + ], + "X-Amzn-Requestid": [ + "f40087a1-3560-5e79-b47c-e755f5a439fc" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5mNDAwODdhMS0zNTYwLTVlNzktYjQ3Yy1lNzU1ZjVhNDM5ZmM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "496940087c304e9c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "93" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:08 GMT" + ], + "X-Amzn-Requestid": [ + "38f44dad-48de-56ab-86a2-2d59881ac6e7" + ] + }, + "Body": "" + } + }, + { + "ID": "1350331366546535", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "121" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljU2VuZFJlY2VpdmVKU09OLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:08 GMT" + ], + "X-Amzn-Requestid": [ + "c37b2189-d0f9-5c4b-91b4-417d103d0bce" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5jMzdiMjE4OS1kMGY5LTVjNGItOTFiNC00MTdkMTAzZDBiY2U8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestSendReceiveTwo.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestSendReceiveTwo.replay new file mode 100644 index 000000000..a8b838468 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopic/TestSendReceiveTwo.replay @@ -0,0 +1,1675 @@ +{ + "Initial": "AQAAAA7gDLWAFr8ntwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "74ad9d45198d064f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNTZW5kUmVjZWl2ZVR3by10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "335" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:04 GMT" + ], + "X-Amzn-Requestid": [ + "72d0817d-c9cc-5c2a-a297-e189090ce9e5" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmVUd28tdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjcyZDA4MTdkLWM5Y2MtNWMyYS1hMjk3LWUxODkwOTBjZTllNTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "8efaec2f8294b292", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "44" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "92" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:05 GMT" + ], + "X-Amzn-Requestid": [ + "e7f96d77-5d39-53cb-a977-0d839df80ee3" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + } + }, + { + "ID": "7c4d57a919c103bd", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "122" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "93" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:05 GMT" + ], + "X-Amzn-Requestid": [ + "8425f3a3-364b-5e8f-9395-9357f68ae3a7" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn19" + } + }, + { + "ID": "d038d70ac774618b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "470" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmVUd28tc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:05 GMT" + ], + "X-Amzn-Requestid": [ + "8cede6a4-2fd9-5944-9ddf-8650ef18846c" + ] + }, + "Body": "" + } + }, + { + "ID": "40799f7ed06f95a5", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "214" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "378" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:05 GMT" + ], + "X-Amzn-Requestid": [ + "f47f750a-a5d2-542f-99c0-15fe651351e0" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmVUd28tdG9wLTE6ZDgxOTY3NWYtYmYzZi00ODc3LWEwZTctM2ExMjBkMDM3YjRiPC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmY0N2Y3NTBhLWE1ZDItNTQyZi05OWMwLTE1ZmU2NTEzNTFlMDwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "476518c78490a7da", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "44" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "92" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:05 GMT" + ], + "X-Amzn-Requestid": [ + "362831db-cae2-5420-a8e5-512f0a23e908" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + } + }, + { + "ID": "90955e2092d10f13", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "122" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "93" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:05 GMT" + ], + "X-Amzn-Requestid": [ + "ba64e30c-1be0-534b-b362-83f8db21de63" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn19" + } + }, + { + "ID": "5c4bd23a1ac567ca", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "470" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmVUd28tc3ViLTJcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:05 GMT" + ], + "X-Amzn-Requestid": [ + "af66b6ec-7a16-5756-954f-d618bad71a7e" + ] + }, + "Body": "" + } + }, + { + "ID": "7b31a5fc272fc13c", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "214" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "378" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:05 GMT" + ], + "X-Amzn-Requestid": [ + "2be9a77b-0129-58f0-a1ba-c78fc1e8dd3f" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljU2VuZFJlY2VpdmVUd28tdG9wLTE6Y2JiOWQ0ZmEtNzdmNi00MmMwLTgzY2YtYjIyNWMzMTM5ZjRkPC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjJiZTlhNzdiLTAxMjktNThmMC1hMWJhLWM3OGZjMWU4ZGQzZjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "5bd84e0dd3f43f0e", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "443" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:05 GMT" + ], + "X-Amzn-Requestid": [ + "db662637-1c22-5141-9231-46c3dce3648e" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmExMTIwYTdmLTNmZWYtNTBjMy1iYWI2LTZhOGJmZjJlNjUwYzwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmRiNjYyNjM3LTFjMjItNTE0MS05MjMxLTQ2YzNkY2UzNjQ4ZTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "1eed03350bfc8e2e", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "443" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MSZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:05 GMT" + ], + "X-Amzn-Requestid": [ + "0cc49383-864b-578e-8d40-f377468a4241" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmYwYjE4ZGQ5LWEzNjctNWMwMy1hMzU5LWVkMmQ2M2E2NDljYzwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjBjYzQ5MzgzLTg2NGItNTc4ZS04ZDQwLWYzNzc0NjhhNDI0MTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "66571a218e26c6c6", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "443" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MiZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "c3eaf821-e5a8-5de8-99d0-98d5256a5827" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjczNmJiY2ZiLTk3YzItNWY3OC1iODg1LWRjMGY1NzAwM2FiNzwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmMzZWFmODIxLWU1YTgtNWRlOC05OWQwLTk4ZDUyNTZhNTgyNzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "22b623061f0db97e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1812" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "2922e7a7-d1b8-5fe6-8b12-8753117a42ce" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyNjA4MyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI1OTI4In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiYTExMjBhN2YtM2ZlZi01MGMzLWJhYjYtNmE4YmZmMmU2NTBjXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCIwXCIsXG4gIFwiVGltZXN0YW1wXCIgOiBcIjIwMjUtMDctMThUMjE6Mzc6MDUuODkxWlwiLFxuICBcIlNpZ25hdHVyZVZlcnNpb25cIiA6IFwiMVwiLFxuICBcIlNpZ25hdHVyZVwiIDogXCJLdG1aYmZYRnMvYjVvd1dKSFBDanpMM0pmdDNoRlZqLzM4T1pQOTVtakwwWXdKUUtZaXBUdTIxSzMzaDVXa3BZNXhEbDY0R0FQb0F4K2hnSGNBeVRDRElIL3NUZ293VkNjSXlHZWZNK3VrRXlWcDlnSTdPeGJ6L0N3R3hiK3U3L1ZremRRaUo5RHdpUWRpVm5acXdZV1N3ZCt1Zmh2Q3VxWkw2ZEZpeTlpQ0hvcUwwZ2pkb3FnQ1VwYWR1NVhuSGxUcDBOc1RWYm8yZDdZSnBnZEx3c3FYRXczdTc1RDF6ck9kQzhtY0ppdm1TcDI0TFgzS3BBa3ppUkN2M3A5RnFVRll1clNZc21heWhjMDkwV3RBUHIyeE5ldnFjMTRzZnZGRVJEU0JVVFZRWjNmeUJpMzltNHM1Q1RJV1dJdFVDbDcvN055cUZ3b3dmaTJWSmU1YmRqdXc9PVwiLFxuICBcIlNpZ25pbmdDZXJ0VVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL1NpbXBsZU5vdGlmaWNhdGlvblNlcnZpY2UtOWM2NDY1ZmE3ZjQ4ZjVjYWNkMjMwMTQ2MzFlYzExMzYucGVtXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xOmQ4MTk2NzVmLWJmM2YtNDg3Ny1hMGU3LTNhMTIwZDAzN2I0YlwiLFxuICBcIk1lc3NhZ2VBdHRyaWJ1dGVzXCIgOiB7XG4gICAgXCJhXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIwXCJ9XG4gIH1cbn0iLCJNRDVPZkJvZHkiOiJmNTEzMDdkNTU5Mzc2OGQxZjAzZGQ4Y2ZmY2VjZGQzNyIsIk1lc3NhZ2VJZCI6ImZmNGFhNTYzLTRkMGYtNGVkMi05ZjFlLTE2ZWIzZjg3NWJhYSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCNUROWGFmRE10YmFJWFBzSytyQVZpK0tISlUrbjlvYkh2MHk0eW5Wd2plL3JrRDRRaERaVmpGT2JzNUhPNnVCL09za3JKd2g0VXNvNWU1WVJONDJ6Y3hkNE5UOHQ0YjM4dmxLcmUvcEc2c3ZkZS9ia2swVmtLWnphUTFUck1ZWlVxemRXTkV4UDR2bXZseWRZcmF5dXpYZm5sc2g5ckFuVUJ3c3MveDJkalZUUlNGdWoxeVRFQVlvbEV5bFFGR09lNzVDdStHUU5SaEc5ZHBEcUtXNkd4bEc5Z2dpODgrcGRZZzVsTnBQNXlJVXFQdkpEVHUwSHorbUx3bHN4RTU1Vkp2VjRsZFRkenQ3SlhtbnNIQUg1TE0xNmlEVVBpRld0Nmd4cjN3VituQXdsWEpNTGJTVE9hcGNYekFmdTVzZ3QyWWg2d1QwL0YwRkdzYU52anBLc0FKUzFTajd6TEZNZ3RKWmEwVWJTc3ZZcHMzdVc0RHZ3VTdWZFRIVVlyWERMTlFCak1oVlpKNHVmYVZyUUUxWk84cXRCUk1UN0lCSStXVm1OQitGNWdlST0ifV19" + } + }, + { + "ID": "6212a8b2e3ba515a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1812" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "107b3c66-5d94-57bb-bde0-5c929d569a93" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyNjE0OSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI2MDUyIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiNzM2YmJjZmItOTdjMi01Zjc4LWI4ODUtZGMwZjU3MDAzYWI3XCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCIyXCIsXG4gIFwiVGltZXN0YW1wXCIgOiBcIjIwMjUtMDctMThUMjE6Mzc6MDYuMDIxWlwiLFxuICBcIlNpZ25hdHVyZVZlcnNpb25cIiA6IFwiMVwiLFxuICBcIlNpZ25hdHVyZVwiIDogXCJFRHVDSTI1N2I3ejdnRzlTR25YeUFqSFZRN2JPRFFPUEZhRGNhUmI5WDltemhwUkU1OW9yaHBOcjFzbzZCUWdYRVdjVFRBWnBkYTNIT3pyM0Z6dWZMbk5jNzJIV2xnaWxjM1cxWGw2d0l1bkRrR1RoYkk4R1JOWkphUGhyR2tWWlR1MHlrUTNZdFhzYWtJNWNaaStPWm9yeDJTdUtpeFFDZVZIS3JqcHZzUlZ6czkwblhMVGJ3Y0RXK0hqdmJDelNkQmhHbHFoMm5XQ041YVc2Ny9xZVNweW5KQkNyQWxCWmZObXNKSUFDR2l2UHNJbmpTZHplM2o3SVZMZUhobXhPWEZPdC9XVklIUjRXTmVwNVUrV2hRajRHazVaUkJhTlk4NWxnZGJHWVpqWW5ES0hwMm40Q2hnN1cwV0V3YitWTFA3L2ZROWtVcE03ZlQyd1FZRml5QlE9PVwiLFxuICBcIlNpZ25pbmdDZXJ0VVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL1NpbXBsZU5vdGlmaWNhdGlvblNlcnZpY2UtOWM2NDY1ZmE3ZjQ4ZjVjYWNkMjMwMTQ2MzFlYzExMzYucGVtXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xOmQ4MTk2NzVmLWJmM2YtNDg3Ny1hMGU3LTNhMTIwZDAzN2I0YlwiLFxuICBcIk1lc3NhZ2VBdHRyaWJ1dGVzXCIgOiB7XG4gICAgXCJhXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIyXCJ9XG4gIH1cbn0iLCJNRDVPZkJvZHkiOiJiN2FhY2U5MDc0N2U0ZGJiMzcwMTE0NjlkZTFhZjA4MSIsIk1lc3NhZ2VJZCI6IjdlNTNkNWYzLTk2MWItNGM0YS1hNDI1LTNjODJkMGVkODcxMSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCY2RhelE2bm4xdS9MckV3UXg2QjA1S3dqOHI2a1Z5SVpTVEdXS1FtMGRUQjhCR1M1QzRNWThOUUR3SVN3L1ZPZURleGxFK3Bxa3J3WEJGT0N6NU15VjVGSzY3SjhTR0ZYcGN6S1lSTGlvc0xuc2FtZnYyUkU3MmNpbm1PcDlpcEJpVFNxWkpqeHZjL0lnRnZDUzROaHQ4S0NUajdiK2NzaUkvK1BYTEJRaU52NmM2d2x4QUxkVWFUQ3AzczcyaGFDaWFQdWpua09KQk5oOXRuTHhnNXFYUExLeTEzUTVMc0FmTFhNMUl2VjJGa3R3RkpnMVZyNWtqd0dXN2svZnNmZy9WWTZDam5adUZiNHRNb0JEQU9NQlRQSncyNDV5b1V5L1dzL2s4SkpyVTRxRFZQNVNyU3RPeDFnSFBLanovOFU2WmI0ejRjYlluaW5wT3RDdmk2UG5NRUQ5bnZJNERlWGw0c2RqME9UTmR3dVFqeTZkVk5VQjI4a2JzMFpIVmZaR3kvWGlzU1VaUFR5Nmh4cTRXNXpJV3pmUGZ3N1dmMFBCQ2NZM1VhSVl1VT0ifV19" + } + }, + { + "ID": "342fbf97b9255a6a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "566" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjVETlhhZkRNdGJhSVhQc0srckFWaStLSEpVK245b2JIdjB5NHluVndqZS9ya0Q0UWhEWlZqRk9iczVITzZ1Qi9Pc2tySndoNFVzbzVlNVlSTjQyemN4ZDROVDh0NGIzOHZsS3JlL3BHNnN2ZGUvYmtrMFZrS1p6YVExVHJNWVpVcXpkV05FeFA0dm12bHlkWXJheXV6WGZubHNoOXJBblVCd3NzL3gyZGpWVFJTRnVqMXlURUFZb2xFeWxRRkdPZTc1Q3UrR1FOUmhHOWRwRHFLVzZHeGxHOWdnaTg4K3BkWWc1bE5wUDV5SVVxUHZKRFR1MEh6K21Md2xzeEU1NVZKdlY0bGRUZHp0N0pYbW5zSEFINUxNMTZpRFVQaUZXdDZneHIzd1YrbkF3bFhKTUxiU1RPYXBjWHpBZnU1c2d0MlloNndUMC9GMEZHc2FOdmpwS3NBSlMxU2o3ekxGTWd0SlphMFViU3N2WXBzM3VXNER2d1U3VmRUSFVZclhETE5RQmpNaFZaSjR1ZmFWclFFMVpPOHF0QlJNVDdJQkkrV1ZtTkIrRjVnZUk9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "6fef1151-cd96-5f55-877f-71a50d54b27d" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "f3faf895b3674d0f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1812" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "9ddb6179-2e4a-513c-a6c0-018dee88ac14" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyNjI2NiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI1OTg1In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiZjBiMThkZDktYTM2Ny01YzAzLWEzNTktZWQyZDYzYTY0OWNjXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCIxXCIsXG4gIFwiVGltZXN0YW1wXCIgOiBcIjIwMjUtMDctMThUMjE6Mzc6MDUuOTU2WlwiLFxuICBcIlNpZ25hdHVyZVZlcnNpb25cIiA6IFwiMVwiLFxuICBcIlNpZ25hdHVyZVwiIDogXCJlRjlGZDltU3ExMWpHTmFCREJoc2dIQ1JmSzd2RW1ZM0Nabk45QTYyRUN4TDJvZHN4VERleHhBSnhuVmRMMVVqOGxyZ1BmR2xjTkRBTU9CQzRKaVdad09XTHpyaERvMGM2NFpwNytBZkExY29CUnlIVHBHR1p0bjRkQTVxdVdpb0VqT2IxbXVKNWk0dnBDTmY2bjFQZDhlZDhiUnk4OG1ubENmWEt4Y3F2aUMyMlZOOHJzdzJ2N0lNc0NScFBVVmxHUEM1KzhoZXQ4aVRDUzE1bFg3SWJuU2dONDFsUlErbm5IUXIveGtZbHdjOHpzUmczRXVKbkxuWlQ1UUxKQWdTdkVGaWVvZXl1SlE0R2xYTXZvd2dPamtWTGMzQ0grS3RtQ0U4K0R3MGdrejNaemhjZS9GcFQvU1Q0QzFMdHZqaERMc2NnSnRSWk5kY2NoQk1jRnZmS2c9PVwiLFxuICBcIlNpZ25pbmdDZXJ0VVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL1NpbXBsZU5vdGlmaWNhdGlvblNlcnZpY2UtOWM2NDY1ZmE3ZjQ4ZjVjYWNkMjMwMTQ2MzFlYzExMzYucGVtXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xOmQ4MTk2NzVmLWJmM2YtNDg3Ny1hMGU3LTNhMTIwZDAzN2I0YlwiLFxuICBcIk1lc3NhZ2VBdHRyaWJ1dGVzXCIgOiB7XG4gICAgXCJhXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIxXCJ9XG4gIH1cbn0iLCJNRDVPZkJvZHkiOiI5NmUwN2MyZmQ5Y2E0NTJkOGJiOTU0YWViZDM4ZTc5ZCIsIk1lc3NhZ2VJZCI6IjRkYzkyYjJhLTJmZDctNDk4MS1hMDA1LTkyZTQ4MWQyNjY5YyIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCazFPYSttczNlZGlGcGhRTlBhTWh1TzJkY01BY3I3d0Z2eUdrTEg4bVFuaTIxTjQ2MC8xM2xTTUh6QXgxamVvampJNkZybzgyTi92SVNoK3lvNkxwODdJOS9sdHNNRGFOSjNqWnZzV0RxMDBKZU9YaWhrTW44VExwdjhsTm5hQmJDSHB6RStrQnlpTXhLOFFRc2NLL2xmQlZBa2JZWStCR05yY0tvQU9kekJEMVM1b3Ywb3FkQ3FpbmhMS2hhanU5QVBRWURvVS90S3NYM3VrdkNPSGZ0c2xuV1ZXRk5rZlpKMW9VZXNtOVFuQjhINHE5alh5eGtWaC93aXoyWlRKdkpucjNmV2ZpTDNrZ1RWTjVsMG4vSDlFL3A4aGJJdGFqM3ZPQVNBQ01HdnFnUFZ3KzV5ZFFEdzhIdXZnODl6MXVna1pnU2w4dWtWR3kvdXEzUDkrRmkzZlJ6aEJwZWZoT3BkY3FkZWFNNlAvRndwVlduSXlxZmdkV1ZzWjFUSHQ5aWpDdTVaQnJsOUZrSnN6RmU5akZhM294TzFmekEvbi9qSlpoQWRHSlJoZz0ifV19" + } + }, + { + "ID": "3802df97f056b3c9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "566" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmNkYXpRNm5uMXUvTHJFd1F4NkIwNUt3ajhyNmtWeUlaU1RHV0tRbTBkVEI4QkdTNUM0TVk4TlFEd0lTdy9WT2VEZXhsRStwcWtyd1hCRk9DejVNeVY1Rks2N0o4U0dGWHBjektZUkxpb3NMbnNhbWZ2MlJFNzJjaW5tT3A5aXBCaVRTcVpKanh2Yy9JZ0Z2Q1M0Tmh0OEtDVGo3Yitjc2lJLytQWExCUWlOdjZjNndseEFMZFVhVENwM3M3MmhhQ2lhUHVqbmtPSkJOaDl0bkx4ZzVxWFBMS3kxM1E1THNBZkxYTTFJdlYyRmt0d0ZKZzFWcjVrandHVzdrL2ZzZmcvVlk2Q2puWnVGYjR0TW9CREFPTUJUUEp3MjQ1eW9VeS9Xcy9rOEpKclU0cURWUDVTclN0T3gxZ0hQS2p6LzhVNlpiNHo0Y2JZbmlucE90Q3ZpNlBuTUVEOW52STREZVhsNHNkajBPVE5kd3VRank2ZFZOVUIyOGticzBaSFZmWkd5L1hpc1NVWlBUeTZoeHE0VzV6SVd6ZlBmdzdXZjBQQkNjWTNVYUlZdVU9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "7b53259e-b952-5bbe-8d54-456a7990cc70" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "d78e90c62bdc7a0e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1812" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "60657771-5cf1-54d7-92ca-17859c3339ff" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyNjMyNyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI1OTI3In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiYTExMjBhN2YtM2ZlZi01MGMzLWJhYjYtNmE4YmZmMmU2NTBjXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCIwXCIsXG4gIFwiVGltZXN0YW1wXCIgOiBcIjIwMjUtMDctMThUMjE6Mzc6MDUuODkxWlwiLFxuICBcIlNpZ25hdHVyZVZlcnNpb25cIiA6IFwiMVwiLFxuICBcIlNpZ25hdHVyZVwiIDogXCJLdG1aYmZYRnMvYjVvd1dKSFBDanpMM0pmdDNoRlZqLzM4T1pQOTVtakwwWXdKUUtZaXBUdTIxSzMzaDVXa3BZNXhEbDY0R0FQb0F4K2hnSGNBeVRDRElIL3NUZ293VkNjSXlHZWZNK3VrRXlWcDlnSTdPeGJ6L0N3R3hiK3U3L1ZremRRaUo5RHdpUWRpVm5acXdZV1N3ZCt1Zmh2Q3VxWkw2ZEZpeTlpQ0hvcUwwZ2pkb3FnQ1VwYWR1NVhuSGxUcDBOc1RWYm8yZDdZSnBnZEx3c3FYRXczdTc1RDF6ck9kQzhtY0ppdm1TcDI0TFgzS3BBa3ppUkN2M3A5RnFVRll1clNZc21heWhjMDkwV3RBUHIyeE5ldnFjMTRzZnZGRVJEU0JVVFZRWjNmeUJpMzltNHM1Q1RJV1dJdFVDbDcvN055cUZ3b3dmaTJWSmU1YmRqdXc9PVwiLFxuICBcIlNpZ25pbmdDZXJ0VVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL1NpbXBsZU5vdGlmaWNhdGlvblNlcnZpY2UtOWM2NDY1ZmE3ZjQ4ZjVjYWNkMjMwMTQ2MzFlYzExMzYucGVtXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xOmNiYjlkNGZhLTc3ZjYtNDJjMC04M2NmLWIyMjVjMzEzOWY0ZFwiLFxuICBcIk1lc3NhZ2VBdHRyaWJ1dGVzXCIgOiB7XG4gICAgXCJhXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIwXCJ9XG4gIH1cbn0iLCJNRDVPZkJvZHkiOiI5MDc2YWY2NTdjYmMxNTFmZDU3OWJhY2QyOTVlOTI5YiIsIk1lc3NhZ2VJZCI6IjVkODYyYWFkLWY0NDItNDQ3NC05YzViLTRkNTRlMTk0NzIxNyIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCcVBVKys5Qis2cFJrSnJKSzlLZ1pINDk3WGpIN25IVW5QaTVqbU1Ed2hqUlROUyt3bkZYVThiTVZjRUlRTVhjbVZkbDB4VVc2Q3BicnlrTHlHamlrS29BNmtOdHUwZm05bm9SaHpxakZERmxwVWJmSFBvZDc1WlVJRWY2L2IxMmV2TGl4RGpPZWxTSUhMRmRKY0V6dXdSV1RTQ2VtdEg4UHFmc1YwUzd1UWtFVjZydVhxeVAyRzNSWUpmdVlaV2JhZ05TUjgyeXU4dndya3c2V3E4Z2R2eGpmK3A5OXo5QmNKcFgvV2tDSVM1ZS8reFZ3VXM2RklHYkhnb1VZRkdHOW90aWtOSU4wR01GOExGbEY2R0lYQmI0M2dkZURBWkZtY09IL05GaTRYNFpadmMvUU0rZzZQRG5PL1FYOURvMEZmSW1zTDZFOWRkbWkxQnZ2MGtjZGhQb285OGhEWGRVUThiZTByRzdyWDZkNFBtQlJ6RzhOVlZ2QUhkVjVHcXphTEFxaXYwTXFiLzlFejFLcHlrQ2tDMU9IcmhYUHZKY0VKZTdWejBvZjBPQT0ifV19" + } + }, + { + "ID": "66f7e669f4af23af", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "566" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnFQVSsrOUIrNnBSa0pySks5S2daSDQ5N1hqSDduSFVuUGk1am1NRHdoalJUTlMrd25GWFU4Yk1WY0VJUU1YY21WZGwweFVXNkNwYnJ5a0x5R2ppa0tvQTZrTnR1MGZtOW5vUmh6cWpGREZscFViZkhQb2Q3NVpVSUVmNi9iMTJldkxpeERqT2VsU0lITEZkSmNFenV3UldUU0NlbXRIOFBxZnNWMFM3dVFrRVY2cnVYcXlQMkczUllKZnVZWldiYWdOU1I4Mnl1OHZ3cmt3NldxOGdkdnhqZitwOTl6OUJjSnBYL1drQ0lTNWUvK3hWd1VzNkZJR2JIZ29VWUZHRzlvdGlrTklOMEdNRjhMRmxGNkdJWEJiNDNnZGVEQVpGbWNPSC9ORmk0WDRaWnZjL1FNK2c2UERuTy9RWDlEbzBGZkltc0w2RTlkZG1pMUJ2djBrY2RoUG9vOThoRFhkVVE4YmUwckc3clg2ZDRQbUJSekc4TlZWdkFIZFY1R3F6YUxBcWl2ME1xYi85RXoxS3B5a0NrQzFPSHJoWFB2SmNFSmU3Vnowb2YwT0E9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "b4d2cae2-521e-584d-a0a9-aa1692dc4565" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "38452daae1ffcf70", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1812" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "2bac1c08-d304-5a5a-835a-7cfc13c65aca" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyNjQwMiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI1OTkxIn0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiZjBiMThkZDktYTM2Ny01YzAzLWEzNTktZWQyZDYzYTY0OWNjXCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCIxXCIsXG4gIFwiVGltZXN0YW1wXCIgOiBcIjIwMjUtMDctMThUMjE6Mzc6MDUuOTU2WlwiLFxuICBcIlNpZ25hdHVyZVZlcnNpb25cIiA6IFwiMVwiLFxuICBcIlNpZ25hdHVyZVwiIDogXCJlRjlGZDltU3ExMWpHTmFCREJoc2dIQ1JmSzd2RW1ZM0Nabk45QTYyRUN4TDJvZHN4VERleHhBSnhuVmRMMVVqOGxyZ1BmR2xjTkRBTU9CQzRKaVdad09XTHpyaERvMGM2NFpwNytBZkExY29CUnlIVHBHR1p0bjRkQTVxdVdpb0VqT2IxbXVKNWk0dnBDTmY2bjFQZDhlZDhiUnk4OG1ubENmWEt4Y3F2aUMyMlZOOHJzdzJ2N0lNc0NScFBVVmxHUEM1KzhoZXQ4aVRDUzE1bFg3SWJuU2dONDFsUlErbm5IUXIveGtZbHdjOHpzUmczRXVKbkxuWlQ1UUxKQWdTdkVGaWVvZXl1SlE0R2xYTXZvd2dPamtWTGMzQ0grS3RtQ0U4K0R3MGdrejNaemhjZS9GcFQvU1Q0QzFMdHZqaERMc2NnSnRSWk5kY2NoQk1jRnZmS2c9PVwiLFxuICBcIlNpZ25pbmdDZXJ0VVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL1NpbXBsZU5vdGlmaWNhdGlvblNlcnZpY2UtOWM2NDY1ZmE3ZjQ4ZjVjYWNkMjMwMTQ2MzFlYzExMzYucGVtXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xOmNiYjlkNGZhLTc3ZjYtNDJjMC04M2NmLWIyMjVjMzEzOWY0ZFwiLFxuICBcIk1lc3NhZ2VBdHRyaWJ1dGVzXCIgOiB7XG4gICAgXCJhXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIxXCJ9XG4gIH1cbn0iLCJNRDVPZkJvZHkiOiJlNTZhNDZlZDUxMWVjNTc0YzA5ZWYxNjM1NDk0OWE5MiIsIk1lc3NhZ2VJZCI6IjVmMmEwZTQ3LWUwNzUtNDY2MS04NWY2LWVlOWYwNmM3NzdhYiIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCaGhoTkZyR0VETEF2cm5zMzBCUk5ONEFLWE5HaEcxM2dDOThXb1BGeUhOS2ZMRWRsb1BhRzdTQ3Z4RWF6Mit6OHRYWmVnK2ovYXNzTXRRR0VmbGxPNWtra2lGN0YyVTlFK2hHZmVKUFdzdGgra1B4d05QSW5ySDhENG9hSnh1T3ZRRGVpVTFjazR5UXZ2VVlNNGcwUlNVd1RoNmMxZWVsK0NoYlRnSHhmcjdWTi9FclZ4dlVOb095eHh6TC9JRzA4S2QvdWN4YlUrQk1LRDFSMW84OHVNR0lzRUNKT0dJakxBK2U3RFRLcWpMRWpFK2piODFCQWVmUUJKOXlVYWMxNlMraXFvL0drZkhPM2JSM3RBd1lPWnJtK0x2SUFjZkpXejk1QVJOTUNKSXBEd24zVzhrS1hrOUt2ZnhvOENqZjZaSlM3WkorQlpSQUNwVURWdmMwWC90K1VDOHJYSFgzWEVkUjZtcW5JY3JtcEJOMy80Z0twRCtxNEllVnh2d2ZJbjN5NDBpdWtqUjRrZ3NLbGUvNXdsNi9VYkZYTXZpVWFlL3BMVzFEOGZBOD0ifV19" + } + }, + { + "ID": "640e0f889cf2e999", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "566" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmsxT2ErbXMzZWRpRnBoUU5QYU1odU8yZGNNQWNyN3dGdnlHa0xIOG1RbmkyMU40NjAvMTNsU01IekF4MWplb2pqSTZGcm84Mk4vdklTaCt5bzZMcDg3STkvbHRzTURhTkozalp2c1dEcTAwSmVPWGloa01uOFRMcHY4bE5uYUJiQ0hwekUra0J5aU14SzhRUXNjSy9sZkJWQWtiWVkrQkdOcmNLb0FPZHpCRDFTNW92MG9xZENxaW5oTEtoYWp1OUFQUVlEb1UvdEtzWDN1a3ZDT0hmdHNsbldWV0ZOa2ZaSjFvVWVzbTlRbkI4SDRxOWpYeXhrVmgvd2l6MlpUSnZKbnIzZldmaUwza2dUVk41bDBuL0g5RS9wOGhiSXRhajN2T0FTQUNNR3ZxZ1BWdys1eWRRRHc4SHV2Zzg5ejF1Z2taZ1NsOHVrVkd5L3VxM1A5K0ZpM2ZSemhCcGVmaE9wZGNxZGVhTTZQL0Z3cFZXbkl5cWZnZFdWc1oxVEh0OWlqQ3U1WkJybDlGa0pzekZlOWpGYTNveE8xZnpBL24vakpaaEFkR0pSaGc9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "3b534f55-9da8-58f4-b09d-2fa15d6a5f3a" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "07b87602e8b20ad0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "566" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmhoaE5GckdFRExBdnJuczMwQlJOTjRBS1hOR2hHMTNnQzk4V29QRnlITktmTEVkbG9QYUc3U0N2eEVhejIrejh0WFplZytqL2Fzc010UUdFZmxsTzVra2tpRjdGMlU5RStoR2ZlSlBXc3RoK2tQeHdOUEluckg4RDRvYUp4dU92UURlaVUxY2s0eVF2dlVZTTRnMFJTVXdUaDZjMWVlbCtDaGJUZ0h4ZnI3Vk4vRXJWeHZVTm9PeXh4ekwvSUcwOEtkL3VjeGJVK0JNS0QxUjFvODh1TUdJc0VDSk9HSWpMQStlN0RUS3FqTEVqRStqYjgxQkFlZlFCSjl5VWFjMTZTK2lxby9Ha2ZITzNiUjN0QXdZT1pybStMdklBY2ZKV3o5NUFSTk1DSklwRHduM1c4a0tYazlLdmZ4bzhDamY2WkpTN1pKK0JaUkFDcFVEVnZjMFgvdCtVQzhyWEhYM1hFZFI2bXFuSWNybXBCTjMvNGdLcEQrcTRJZVZ4dndmSW4zeTQwaXVralI0a2dzS2xlLzV3bDYvVWJGWE12aVVhZS9wTFcxRDhmQTg9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "a34601b6-0209-5bd1-9337-6142c2cbf6f9" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "19383f53af855a61", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1812" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "ca7519d3-f265-5c0e-a485-792732a7bafc" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDYyNjQ4MyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjI2MDU2In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiNzM2YmJjZmItOTdjMi01Zjc4LWI4ODUtZGMwZjU3MDAzYWI3XCIsXG4gIFwiVG9waWNBcm5cIiA6IFwiYXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xXCIsXG4gIFwiTWVzc2FnZVwiIDogXCIyXCIsXG4gIFwiVGltZXN0YW1wXCIgOiBcIjIwMjUtMDctMThUMjE6Mzc6MDYuMDIxWlwiLFxuICBcIlNpZ25hdHVyZVZlcnNpb25cIiA6IFwiMVwiLFxuICBcIlNpZ25hdHVyZVwiIDogXCJFRHVDSTI1N2I3ejdnRzlTR25YeUFqSFZRN2JPRFFPUEZhRGNhUmI5WDltemhwUkU1OW9yaHBOcjFzbzZCUWdYRVdjVFRBWnBkYTNIT3pyM0Z6dWZMbk5jNzJIV2xnaWxjM1cxWGw2d0l1bkRrR1RoYkk4R1JOWkphUGhyR2tWWlR1MHlrUTNZdFhzYWtJNWNaaStPWm9yeDJTdUtpeFFDZVZIS3JqcHZzUlZ6czkwblhMVGJ3Y0RXK0hqdmJDelNkQmhHbHFoMm5XQ041YVc2Ny9xZVNweW5KQkNyQWxCWmZObXNKSUFDR2l2UHNJbmpTZHplM2o3SVZMZUhobXhPWEZPdC9XVklIUjRXTmVwNVUrV2hRajRHazVaUkJhTlk4NWxnZGJHWVpqWW5ES0hwMm40Q2hnN1cwV0V3YitWTFA3L2ZROWtVcE03ZlQyd1FZRml5QlE9PVwiLFxuICBcIlNpZ25pbmdDZXJ0VVJMXCIgOiBcImh0dHBzOi8vc25zLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tL1NpbXBsZU5vdGlmaWNhdGlvblNlcnZpY2UtOWM2NDY1ZmE3ZjQ4ZjVjYWNkMjMwMTQ2MzFlYzExMzYucGVtXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xOmNiYjlkNGZhLTc3ZjYtNDJjMC04M2NmLWIyMjVjMzEzOWY0ZFwiLFxuICBcIk1lc3NhZ2VBdHRyaWJ1dGVzXCIgOiB7XG4gICAgXCJhXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIyXCJ9XG4gIH1cbn0iLCJNRDVPZkJvZHkiOiJmOWQ4MWViMzkwZjIzYzIzOTA3MDVlMjNmMmVhZTE0ZSIsIk1lc3NhZ2VJZCI6ImMyZjlkZjAxLTgxZmItNGIwOS1iOWNmLTQzOWQ5ZmEyNzA3NyIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCZytscDF6eW9rdUdhMlBmTU9lY0ZIeENJWGxRZGFRYjVTMmdTcFUxdUQ0cnRIMVU4cEVOdFdTbUpDQmNHR2EwdlZ0MjJMYkVNTTBrblRpYnowc0tMaU1qZVI4dzF3QUc0aDBJTGY0VmZXSnh5bXRSd3pxZm5qdVlRNlhxNFFlQUN2KzRqZC9OdDMvYVAwNjZjdXBjQllUQmRGOGppdHplQXhVMXJNaXczNk5NdFduaGZEL2Zwd0h4aDhTbVdEa0FUZU9VYlJiU3VmOHYyVSt1NUhZTW1LU2dUdjZtcDNhNlZPT0VIWEo4dEFWRHduZ1Q2aERyRGd6Wk9qU2NXMzBCTzRER0NOTGRRYW9tS2pEVjVBUllGWEhuRmR1SlJmNWZRdithRWZiNFFGeGkra3JFNlM2TDR0eW5OMERtczNsUTNqS0djOFV5NUVXWGZIQ3lGVE4ycVZIN1dKWUxwZ2lXVnplSzBlUlhsSkhsUHNJaU9nSUxKanVLVGNHVThLYnp1MXJxVjMvMnR1SzMwVXZ0eFptZ3BObWhwd1ZXc3phNHBGanlZaWJST1ROQT0ifV19" + } + }, + { + "ID": "ad9bf202682643e5", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "566" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmcrbHAxenlva3VHYTJQZk1PZWNGSHhDSVhsUWRhUWI1UzJnU3BVMXVENHJ0SDFVOHBFTnRXU21KQ0JjR0dhMHZWdDIyTGJFTU0wa25UaWJ6MHNLTGlNamVSOHcxd0FHNGgwSUxmNFZmV0p4eW10Und6cWZuanVZUTZYcTRRZUFDdis0amQvTnQzL2FQMDY2Y3VwY0JZVEJkRjhqaXR6ZUF4VTFyTWl3MzZOTXRXbmhmRC9mcHdIeGg4U21XRGtBVGVPVWJSYlN1Zjh2MlUrdTVIWU1tS1NnVHY2bXAzYTZWT09FSFhKOHRBVkR3bmdUNmhEckRnelpPalNjVzMwQk80REdDTkxkUWFvbUtqRFY1QVJZRlhIbkZkdUpSZjVmUXYrYUVmYjRRRnhpK2tyRTZTNkw0dHluTjBEbXMzbFEzaktHYzhVeTVFV1hmSEN5RlROMnFWSDdXSllMcGdpV1Z6ZUswZVJYbEpIbFBzSWlPZ0lMSmp1S1RjR1U4S2J6dTFycVYzLzJ0dUszMFV2dHhabWdwTm1ocHdWV3N6YTRwRmp5WWliUk9UTkE9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "5e63ad6e-ce34-50fe-9ad6-cd9a0ef6add6" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "ab78933f82e5477f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xJTNBY2JiOWQ0ZmEtNzdmNi00MmMwLTgzY2YtYjIyNWMzMTM5ZjRkJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "6c09048e-00dc-515c-88f5-647ac01e4493" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD42YzA5MDQ4ZS0wMGRjLTUxNWMtODhmNS02NDdhYzAxZTQ0OTM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "bb7b19a5037397c4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "92" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "713c46c1-9336-5264-913b-263553f47f4c" + ] + }, + "Body": "" + } + }, + { + "ID": "dedc3330ee16e366", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXRvcC0xJTNBZDgxOTY3NWYtYmYzZi00ODc3LWEwZTctM2ExMjBkMDM3YjRiJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:06 GMT" + ], + "X-Amzn-Requestid": [ + "4b9df332-12d1-5739-8c41-93c6d21362f6" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD40YjlkZjMzMi0xMmQxLTU3MzktOGM0MS05M2M2ZDIxMzYyZjY8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "3b15eaf5a398ec1a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "92" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:07 GMT" + ], + "X-Amzn-Requestid": [ + "efa1a814-ea7f-592b-ac17-c8e02abda403" + ] + }, + "Body": "" + } + }, + { + "ID": "1654e2ddf3bed77e", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "120" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljU2VuZFJlY2VpdmVUd28tdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:07 GMT" + ], + "X-Amzn-Requestid": [ + "f6b3e7da-ad21-5b3f-a238-872e6de27ef0" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5mNmIzZTdkYS1hZDIxLTViM2YtYTIzOC04NzJlNmRlMjdlZjA8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestAs/aws_test.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestAs/aws_test.replay new file mode 100644 index 000000000..41d4a69ed --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestAs/aws_test.replay @@ -0,0 +1,768 @@ +{ + "Initial": "AQAAAA7gDLWqLFhlVAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "f310a0c6a7208e42", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdBc19hd3NfdGVzdC10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "335" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:47 GMT" + ], + "X-Amzn-Requestid": [ + "3fa75f05-0707-5a21-a820-3ff1c7ed6f50" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3QXNfYXdzX3Rlc3QtdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjNmYTc1ZjA1LTA3MDctNWEyMS1hODIwLTNmZjFjN2VkNmY1MDwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "8d8b4af0bf2c2805", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "44" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "92" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:47 GMT" + ], + "X-Amzn-Requestid": [ + "61e5bfa5-143e-5ff8-b03e-df51d4d5e5a9" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXN1Yi0xIn0=" + } + }, + { + "ID": "680eb81bfcec4def", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "122" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "93" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:47 GMT" + ], + "X-Amzn-Requestid": [ + "378cb0ac-ac88-5a6e-beb3-d0586c63903f" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXN1Yi0xIn19" + } + }, + { + "ID": "97ce376ce5df42b8", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "470" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3QXNfYXdzX3Rlc3Qtc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:47 GMT" + ], + "X-Amzn-Requestid": [ + "32a54933-d019-5318-be74-29c710f29949" + ] + }, + "Body": "" + } + }, + { + "ID": "cbee261ae37e74d1", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "286" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "378" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:47 GMT" + ], + "X-Amzn-Requestid": [ + "b37d426d-07bc-5cda-8888-2299c757f9ab" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3QXNfYXdzX3Rlc3QtdG9wLTE6ZGExMDRkYzUtZDI3ZC00ZjMxLWFkYjAtOTg2ZTgzYzQ3ZjVlPC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmIzN2Q0MjZkLTA3YmMtNWNkYS04ODg4LTIyOTljNzU3ZjlhYjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "925ce08e27411b89", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "208" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9eCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:47 GMT" + ], + "X-Amzn-Requestid": [ + "47895a99-c0c7-5f7e-bd75-3a6d002cba0f" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmZkZmM5ZWZiLTczNDEtNWRjYy05YWQ5LWZlMGZiM2FhMDhiZDwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjQ3ODk1YTk5LWMwYzctNWY3ZS1iZDc1LTNhNmQwMDJjYmEwZjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "5f795c29f23476c3", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "739" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:47 GMT" + ], + "X-Amzn-Requestid": [ + "74103aa4-9de9-5a12-9a17-5a505d02e043" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY2Nzc1OSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjY3NzI2In0sIkJvZHkiOiJ4IiwiTUQ1T2ZCb2R5IjoiOWRkNGU0NjEyNjhjODAzNGY1Yzg1NjRlMTU1YzY3YTYiLCJNZXNzYWdlSWQiOiIxNTNlM2NlMS05YjU5LTRjZTktYjY1NS01NmExNWZmYzA5N2UiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnZpb2Z1OGZyL0c4UFlTeG1rekJBT3F4YStESUpYVUZCY0JkZktMQy9wUndvTHhQVUhmSHVmcVFJVWZvT3RwRm9yc0NKZEtuM1doVjQ2S3JlMzlsT2JSMVV0TndyNFhCOUpYV0huYmxVVFZOSW9ac3RtWDRXZjdRMUJzc3BHV3V2SEpZajZXRWY1NVhhdFNCTmE3OFB4MUdZTGpZclpuSEFwZ3YxSXV4ZkIwMC9pRkZpaFZnT2tQYkluSjNkR0phRHZPaC9la3ZEeDBPMlpGYmRXcStGelZZNlJITGc4R0VrbjllVGpsNmUxM1N3cGdlM1RuSUdjY1gvWXpQY28wc1doT0VKSkE3VHNTMVA4R0FDTFNneEdYWVVtQjd1am42THRReFBCYTZyVVpMK2YxbmM4WnlCRGhtMUNpRDJCQkRGOFA0blFuZnZiUDRqemd6OWNwWXlFT0ZDR3VUZXc0eVBpM3dPT21ZT1FKUVc2ck5ZZUp4WVcrYTBCQ01JdjR0T3RCdFdkRmYxWHdKMDBCVWZaRzVvbGI3aGVndjJBU0twODhyMjgrcnY1dUU9In1dfQ==" + } + }, + { + "ID": "b07a872656fb2c64", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "195" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9JlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQW5vbmV4aXN0ZW50dG9waWMmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "259" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:47 GMT" + ], + "X-Amzn-Requestid": [ + "6b677a5d-ea02-538b-b509-1aa92ae906fa" + ] + }, + "Body": "PEVycm9yUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxFcnJvcj4KICAgIDxUeXBlPlNlbmRlcjwvVHlwZT4KICAgIDxDb2RlPk5vdEZvdW5kPC9Db2RlPgogICAgPE1lc3NhZ2U+VG9waWMgZG9lcyBub3QgZXhpc3Q8L01lc3NhZ2U+CiAgPC9FcnJvcj4KICA8UmVxdWVzdElkPjZiNjc3YTVkLWVhMDItNTM4Yi1iNTA5LTFhYTkyYWU5MDZmYTwvUmVxdWVzdElkPgo8L0Vycm9yUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "b87ed5b042f1722a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "566" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnZpb2Z1OGZyL0c4UFlTeG1rekJBT3F4YStESUpYVUZCY0JkZktMQy9wUndvTHhQVUhmSHVmcVFJVWZvT3RwRm9yc0NKZEtuM1doVjQ2S3JlMzlsT2JSMVV0TndyNFhCOUpYV0huYmxVVFZOSW9ac3RtWDRXZjdRMUJzc3BHV3V2SEpZajZXRWY1NVhhdFNCTmE3OFB4MUdZTGpZclpuSEFwZ3YxSXV4ZkIwMC9pRkZpaFZnT2tQYkluSjNkR0phRHZPaC9la3ZEeDBPMlpGYmRXcStGelZZNlJITGc4R0VrbjllVGpsNmUxM1N3cGdlM1RuSUdjY1gvWXpQY28wc1doT0VKSkE3VHNTMVA4R0FDTFNneEdYWVVtQjd1am42THRReFBCYTZyVVpMK2YxbmM4WnlCRGhtMUNpRDJCQkRGOFA0blFuZnZiUDRqemd6OWNwWXlFT0ZDR3VUZXc0eVBpM3dPT21ZT1FKUVc2ck5ZZUp4WVcrYTBCQ01JdjR0T3RCdFdkRmYxWHdKMDBCVWZaRzVvbGI3aGVndjJBU0twODhyMjgrcnY1dUU9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:47 GMT" + ], + "X-Amzn-Requestid": [ + "d22619b5-6487-5c7c-874b-7941a46c462d" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "97afe4f14dfcaa35", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "165" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vdXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L25vbmV4aXN0ZW50LXN1YnNjcmlwdGlvbiJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:47 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "d6437623-d2d8-5edc-9a56-16d71233b48d" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + }, + { + "ID": "1395f2b7aa03d5e3", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXRvcC0xJTNBZGExMDRkYzUtZDI3ZC00ZjMxLWFkYjAtOTg2ZTgzYzQ3ZjVlJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:48 GMT" + ], + "X-Amzn-Requestid": [ + "e76fc76d-91bd-5a0b-bea8-a7995156ff7a" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5lNzZmYzc2ZC05MWJkLTVhMGItYmVhOC1hNzk5NTE1NmZmN2E8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "71f11f17d49d5180", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "92" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0FzX2F3c190ZXN0LXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:48 GMT" + ], + "X-Amzn-Requestid": [ + "857e3b12-bebf-5a11-9dcd-5be67e531040" + ] + }, + "Body": "" + } + }, + { + "ID": "59845cd4771e0c2b", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "120" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3QXNfYXdzX3Rlc3QtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:48 GMT" + ], + "X-Amzn-Requestid": [ + "e6fe82e4-a7a9-5928-99e4-e21067454c59" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5lNmZlODJlNC1hN2E5LTU5MjgtOTllNC1lMjEwNjc0NTRjNTk8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..372dc8117 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,768 @@ +{ + "Initial": "AQAAAA7gDLWsEAKZWgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b2f74a47820b3388", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdBc192ZXJpZnlfQXNfcmV0dXJuc19mYWxzZV93aGVuX3Bhc3NlZF9uaWwtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "366" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:48 GMT" + ], + "X-Amzn-Requestid": [ + "a0042d1a-1a24-5e1b-8f33-4deedac83bb6" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3QXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5hMDA0MmQxYS0xYTI0LTVlMWItOGYzMy00ZGVlZGFjODNiYjY8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "eb598dd0e018ffb9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "75" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "123" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:48 GMT" + ], + "X-Amzn-Requestid": [ + "ca3103da-1059-52d9-ba64-632ed0b5ddf6" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9" + } + }, + { + "ID": "861792b2bc171d66", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "153" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "124" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:49 GMT" + ], + "X-Amzn-Requestid": [ + "7c471e85-20a5-5c38-932e-7e71e0486317" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9fQ==" + } + }, + { + "ID": "5b0121a5be9f508a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "532" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3QXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXN1Yi0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNSYXdBc192ZXJpZnlfQXNfcmV0dXJuc19mYWxzZV93aGVuX3Bhc3NlZF9uaWwtc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:49 GMT" + ], + "X-Amzn-Requestid": [ + "24d1e75a-349d-595e-b122-87aef4702671" + ] + }, + "Body": "" + } + }, + { + "ID": "a71738139a830f35", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "348" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSZQcm90b2NvbD1zcXMmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBU05TVG9waWNSYXdBc192ZXJpZnlfQXNfcmV0dXJuc19mYWxzZV93aGVuX3Bhc3NlZF9uaWwtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "409" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:49 GMT" + ], + "X-Amzn-Requestid": [ + "f3d638f3-60ed-58ec-a7dc-5807a000ed41" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3QXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXRvcC0xOjViYTM3YWQzLTJjNmMtNDRlMS1iZjQzLTZiMjhjZTYzY2RhYzwvU3Vic2NyaXB0aW9uQXJuPgogIDwvU3Vic2NyaWJlUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5mM2Q2MzhmMy02MGVkLTU4ZWMtYTdkYy01ODA3YTAwMGVkNDE8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvU3Vic2NyaWJlUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "f86d3ffc42b94974", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "239" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9eCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:49 GMT" + ], + "X-Amzn-Requestid": [ + "8f862787-9fb2-5f57-aa67-47735f5feafa" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjZiYmZhY2QyLTE4ODctNTZmMi05NDBjLWNjMjZkODZhMTM1ZjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjhmODYyNzg3LTlmYjItNWY1Ny1hYTY3LTQ3NzM1ZjVmZWFmYTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "1448b77069941ae2", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "204" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "783" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:49 GMT" + ], + "X-Amzn-Requestid": [ + "c518d165-5ea9-5aa8-9365-b1919e444587" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY2OTQ4OSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjY5NDU2In0sIkJvZHkiOiJ4IiwiTUQ1T2ZCb2R5IjoiOWRkNGU0NjEyNjhjODAzNGY1Yzg1NjRlMTU1YzY3YTYiLCJNZXNzYWdlSWQiOiJhYzg5MjUwMS1jOGJjLTRmZTUtYmRlYy00ZThlNDU4YzNlYzEiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQi9DMGtCK3AxOFNhNi9qMkFjUEpoVnZHdkxvQ1NTM011UkdQNWN1Q2tCZEl4OGZBYnc4Z3JLdkMxTEVYRXJJTGJPWXhpTmhad1dOVVBMOFZzUGQ3OW55OG5OT2hMMnVPT1BuOU1VL1NuclZ4YytMeXlZUWtZemdYZ2QraG9CVXR5TlRxMVBoUENQS2dPd2hrZTFyT0lBczhha3hsS3ljSkovdlNJdjl3akJETzVLaW15SlRyU1ZKNFhYSDY2U0M2c0lkaTJJTXRoWVB1bGRKd1FEeWNEUGJ4RGJzSGUvelJOOFdXRUZISElMU3p3eEJPbVZvSUJmdERleWtyc2VvcUVYdU9xaGRQQ1U2cmJxZnYvb05TVzFZRnprNUgrM3B2a0dsTEZHVlhLVGpLQzVZSkJPTk1peldrQ0FucFF5dDFWclBlcVFKckZyZkJGTlE4b3dZcTl6TUl3M1FYM2xKN3dCeTZGK3E2SjFNVmc5MVpBVGVOSWF4c0YxZXpNUHdMMFg2RzNVNnZiYytJK09FaXlmRmZEOFQrekFSY3hOVXlZTWpxWlJ3R3lZc25haTdBMGpaYUQ5em1XRXFkMTJsNzlkaSt1ZmwzZlgycFI0bXo2VnNzUER3PT0ifV19" + } + }, + { + "ID": "fc13b9f706c4b94a", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "195" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9JlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQW5vbmV4aXN0ZW50dG9waWMmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "259" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:49 GMT" + ], + "X-Amzn-Requestid": [ + "6b7b9660-1a18-57eb-bd6a-f694daf56246" + ] + }, + "Body": "PEVycm9yUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxFcnJvcj4KICAgIDxUeXBlPlNlbmRlcjwvVHlwZT4KICAgIDxDb2RlPk5vdEZvdW5kPC9Db2RlPgogICAgPE1lc3NhZ2U+VG9waWMgZG9lcyBub3QgZXhpc3Q8L01lc3NhZ2U+CiAgPC9FcnJvcj4KICA8UmVxdWVzdElkPjZiN2I5NjYwLTFhMTgtNTdlYi1iZDZhLWY2OTRkYWY1NjI0NjwvUmVxdWVzdElkPgo8L0Vycm9yUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "3b783c1e9e26f577", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "641" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQi9DMGtCK3AxOFNhNi9qMkFjUEpoVnZHdkxvQ1NTM011UkdQNWN1Q2tCZEl4OGZBYnc4Z3JLdkMxTEVYRXJJTGJPWXhpTmhad1dOVVBMOFZzUGQ3OW55OG5OT2hMMnVPT1BuOU1VL1NuclZ4YytMeXlZUWtZemdYZ2QraG9CVXR5TlRxMVBoUENQS2dPd2hrZTFyT0lBczhha3hsS3ljSkovdlNJdjl3akJETzVLaW15SlRyU1ZKNFhYSDY2U0M2c0lkaTJJTXRoWVB1bGRKd1FEeWNEUGJ4RGJzSGUvelJOOFdXRUZISElMU3p3eEJPbVZvSUJmdERleWtyc2VvcUVYdU9xaGRQQ1U2cmJxZnYvb05TVzFZRnprNUgrM3B2a0dsTEZHVlhLVGpLQzVZSkJPTk1peldrQ0FucFF5dDFWclBlcVFKckZyZkJGTlE4b3dZcTl6TUl3M1FYM2xKN3dCeTZGK3E2SjFNVmc5MVpBVGVOSWF4c0YxZXpNUHdMMFg2RzNVNnZiYytJK09FaXlmRmZEOFQrekFSY3hOVXlZTWpxWlJ3R3lZc25haTdBMGpaYUQ5em1XRXFkMTJsNzlkaSt1ZmwzZlgycFI0bXo2VnNzUER3PT0ifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NOU1RvcGljUmF3QXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:49 GMT" + ], + "X-Amzn-Requestid": [ + "582713ed-e3ff-5d39-b5a0-731923120216" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "c56c6a90cadd4000", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "165" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vdXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L25vbmV4aXN0ZW50LXN1YnNjcmlwdGlvbiJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:49 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "828ac876-8b25-5209-9740-a8824bc8bd26" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + }, + { + "ID": "ce9b8679387fe174", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "197" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC10b3AtMSUzQTViYTM3YWQzLTJjNmMtNDRlMS1iZjQzLTZiMjhjZTYzY2RhYyZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:49 GMT" + ], + "X-Amzn-Requestid": [ + "61644ea9-cdff-5179-ada8-2e5d0d12b4d4" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD42MTY0NGVhOS1jZGZmLTUxNzktYWRhOC0yZTVkMGQxMmI0ZDQ8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "2e34bd77665485bb", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:49 GMT" + ], + "X-Amzn-Requestid": [ + "cb64b599-7c8c-5361-bb5e-d56dbc61cc4e" + ] + }, + "Body": "" + } + }, + { + "ID": "90422b67d79c784c", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "151" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3QXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:49 GMT" + ], + "X-Amzn-Requestid": [ + "a5ee945c-25a0-557f-a6d4-f4a8e54d80d2" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5hNWVlOTQ1Yy0yNWEwLTU1N2YtYTZkNC1mNGE4ZTU0ZDgwZDI8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestBatching.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestBatching.replay new file mode 100644 index 000000000..18a10632f --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestBatching.replay @@ -0,0 +1,1403 @@ +{ + "Initial": "AQAAAA7gDLWaHxADAwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "ac53af83b6afd8cb", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdCYXRjaGluZy10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "332" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:30 GMT" + ], + "X-Amzn-Requestid": [ + "df23b873-978a-5f61-a93e-d887575030cf" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3QmF0Y2hpbmctdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmRmMjNiODczLTk3OGEtNWY2MS1hOTNlLWQ4ODc1NzUwMzBjZjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "8dc2019d31ba7f18", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "41" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "89" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "048cb1ad-f413-502f-b82a-d15934c8cee0" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + } + }, + { + "ID": "1c204560795d51c9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "119" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "90" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "90abd52c-344b-5511-a3b0-b5d8f4907bde" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn19" + } + }, + { + "ID": "eca067c6a1484c3d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "464" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3QmF0Y2hpbmctc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "cc9e2bd0-b809-54a2-8166-4b2478d21a6d" + ] + }, + "Body": "" + } + }, + { + "ID": "5d1f54836d435dd2", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "280" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0JhdGNoaW5nLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "375" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "a984b198-c05b-5cf4-b7d6-d16c0080535a" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3QmF0Y2hpbmctdG9wLTE6YjIyY2U2ZjctY2QyZC00ZDdjLTlhMTAtNTQ5MWZkZmQ1OWUxPC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmE5ODRiMTk4LWMwNWItNWNmNC1iN2Q2LWQxNmMwMDgwNTM1YTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "ea7318091249f7b0", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "700" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjIuSWQ9MSZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMi5NZXNzYWdlPWhlbGxvK3dvcmxkJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4zLklkPTImUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjMuTWVzc2FnZT1oZWxsbyt3b3JsZCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuNC5JZD0zJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci40Lk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjUuSWQ9NCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuNS5NZXNzYWdlPWhlbGxvK3dvcmxkJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci42LklkPTUmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjYuTWVzc2FnZT1oZWxsbyt3b3JsZCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0JhdGNoaW5nLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1007" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "2e0b71bc-c2be-50a6-8abc-11480265af08" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjRlYzBlYjRiLTQyYzEtNTVjMS1iOTJkLThiYmY4MjFhMGE2ZjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICAgIDxtZW1iZXI+CiAgICAgICAgPE1lc3NhZ2VJZD4wNGM1YzkwMi0xMGUyLTU0ZjEtODU3NC1hOWY2ZDAzOWJiNWY8L01lc3NhZ2VJZD4KICAgICAgICA8SWQ+MTwvSWQ+CiAgICAgIDwvbWVtYmVyPgogICAgICA8bWVtYmVyPgogICAgICAgIDxNZXNzYWdlSWQ+OTkwZjk0YTctZGEyZS01YmJmLTk0OGUtZjQ1MzFhZjUzNDExPC9NZXNzYWdlSWQ+CiAgICAgICAgPElkPjI8L0lkPgogICAgICA8L21lbWJlcj4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjA0Mjg0ZTY0LTJlZDAtNWY2MC1iZjI3LTJlOTBlZTBiYzBjZTwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4zPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICAgIDxtZW1iZXI+CiAgICAgICAgPE1lc3NhZ2VJZD4wYmNiM2NiNi1hZTlhLTUzMTAtYjAyNi01YzQyNmU0MThjYmU8L01lc3NhZ2VJZD4KICAgICAgICA8SWQ+NDwvSWQ+CiAgICAgIDwvbWVtYmVyPgogICAgICA8bWVtYmVyPgogICAgICAgIDxNZXNzYWdlSWQ+OWNjYmUxM2ItNGQ1YS01NzMzLTg0ODItODFjZjhkODE2ODlkPC9NZXNzYWdlSWQ+CiAgICAgICAgPElkPjU8L0lkPgogICAgICA8L21lbWJlcj4KICAgIDwvU3VjY2Vzc2Z1bD4KICA8L1B1Ymxpc2hCYXRjaFJlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+MmUwYjcxYmMtYzJiZS01MGE2LThhYmMtMTE0ODAyNjVhZjA4PC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L1B1Ymxpc2hCYXRjaFJlc3BvbnNlPgo=" + } + }, + { + "ID": "cad99a9e11724dcc", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "700" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjIuSWQ9MSZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMi5NZXNzYWdlPWhlbGxvK3dvcmxkJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4zLklkPTImUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjMuTWVzc2FnZT1oZWxsbyt3b3JsZCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuNC5JZD0zJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci40Lk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjUuSWQ9NCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuNS5NZXNzYWdlPWhlbGxvK3dvcmxkJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci42LklkPTUmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjYuTWVzc2FnZT1oZWxsbyt3b3JsZCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0JhdGNoaW5nLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1007" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "82241f83-1b57-58e2-ac45-7f77db8c474c" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjc0Yjc0NTEzLTkzMDgtNTIwYy1hODJiLTI1ZTc1M2QzYmRhMjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICAgIDxtZW1iZXI+CiAgICAgICAgPE1lc3NhZ2VJZD5mMjRiYzkxOS1mNWE1LTU3MjYtYmMyMy1hOWVkMzU3ZTM4ODg8L01lc3NhZ2VJZD4KICAgICAgICA8SWQ+MTwvSWQ+CiAgICAgIDwvbWVtYmVyPgogICAgICA8bWVtYmVyPgogICAgICAgIDxNZXNzYWdlSWQ+OGM1NjM0YzMtYzA2Yy01YzE0LWIzNmEtNTQzNzAwYjdiM2JhPC9NZXNzYWdlSWQ+CiAgICAgICAgPElkPjI8L0lkPgogICAgICA8L21lbWJlcj4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjBhYjkwMzg1LWNkMzgtNTdkYy1iOWZmLTYzNzEwZGUzZTg3MjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4zPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICAgIDxtZW1iZXI+CiAgICAgICAgPE1lc3NhZ2VJZD4wNWExMmM4Mi1hMWY5LTU3MWQtYjIwOC00Yzc2NjEyMjQ4YjM8L01lc3NhZ2VJZD4KICAgICAgICA8SWQ+NDwvSWQ+CiAgICAgIDwvbWVtYmVyPgogICAgICA8bWVtYmVyPgogICAgICAgIDxNZXNzYWdlSWQ+NTkyNjg3MmEtMGJjZS01MGU4LWJkYzQtZTdkZWNiMTU1ZjQ2PC9NZXNzYWdlSWQ+CiAgICAgICAgPElkPjU8L0lkPgogICAgICA8L21lbWJlcj4KICAgIDwvU3VjY2Vzc2Z1bD4KICA8L1B1Ymxpc2hCYXRjaFJlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+ODIyNDFmODMtMWI1Ny01OGUyLWFjNDUtN2Y3N2RiOGM0NzRjPC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L1B1Ymxpc2hCYXRjaFJlc3BvbnNlPgo=" + } + }, + { + "ID": "57c5c9b47d4089c2", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "3b2c8a70-aa0e-5b9b-8324-ea846ad5a554" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MTYxNyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTEyIn0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiYjExZjlkMjItOTk0Yy00NmYwLWEzNmUtYzMyMzc2MjAwNzg3IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJNSExlOFVxN0RUNWpndysxMjcweWE0b2NRa3FocEh4MU9zclFzeWR0ZjBiUHp4aEJZMlJGSDY3ZUdmcnRmT3l0Z1VRK3VUNmtXMTA2bVpyRGVDck1RNzUwQTkwYStFenVFbDdlNHgzUk9NbWhVVEdkaWJRb2xXTTllMlViQnNtcnh1WHB0dHRRd0JQMVFFaXM5OVh2eDdRRDJMUDE2ekJCb2FrWWNoNUY1S1FhdFVNeGFFWmVBNFZrZWluYm9QTUYyQWVqc0NTYWJxb3VyMkFES0krWTBpSytPUlJBWWdNSEhnc2xIU1B3NWl6b1cxa2V5RFY2WXNjbUFmK01aT3hNSGM5UGxPUmw5UFRKSGVqTHVEWkNQUmJ1NkcwTFBKS1RLVTdxRzErK2hSTnJ6UUdJQWUwVndjQjdZdmRxcW9HOFdlazhTaFMvRUEwUHFZLyt3QTdWVk0zSDFaY0RzdFV6eDdJZDYwYnN2WnhDeHZHTEhyY1lzTUZlVmdtZ1dIMnNZSi9XS2E2TVdpWVpRVTVoTy9wMEhGbDB2R3RXQkpnRlVqNkhHU0hadDZnPSJ9XX0=" + } + }, + { + "ID": "151c0e11edbe5378", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "eca37d3f-d420-53e7-9997-1dcb14fb0d28" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MTY3OCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTc4In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiODdjNDE5NTgtN2U3Yi00OTRkLWE1MjktMjhiY2U2MDVhZTAyIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJwZVdSdUpmamFodG5mUnFyWkcyMVR1eVJkS1N0VG96cXJCR2dOenVnRGtSWDNCSTRzK2NCcGJ1TkE3MkU1T1BmTCtUVzNkRGNnWWdzcnIzRFJhMDlYRWF5bDF1elZPMk9seUZMUXYrZ1luSFVLOFNxTXdvc0VmQ3JIVDdKUXJLTk9MeHN2QldpdldMejhISGdUQ3hqbi9mVUhWc0trNG1wd1NmK05VZTBQTFgwZG5pNW9rWHlBb1BXRGZnanAxNFc2Q01UNHR1Y2xFTjJWWWZIdkt2QlgvcWpDY0E4ZXFyTnZaR09qTGk1NVlPdEFrd3dacEhMdUhYbE4zVnNUN0NjWUdETmxZQmJXU2FhWlJ5MlAvd3ZJNFlsbmtPMWxvV205N3RhNFV4TGZTNHhib3hqYzVUN1dqN004ZkVadHF4aTliTnJoSmpNYnJqcFhLcllpbDMxdEdGbHI5UGJXYUx4aEIyMmdtVjVLdE0vcEx4ajdGaEZWdnE0N0tWcndXQnpBdDFSOXVsR0FERDV5NzhaV3oyYVVZL0UrSkhhSWZ0T1dXQVlzcGJXQ1UwPSJ9XX0=" + } + }, + { + "ID": "c0f6c380c3654910", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "7e7330ff-962e-5856-8e14-500b56f59699" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MTczNyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTE0In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNzFlYjYzZDYtNTA5MC00MzkyLWFlZTctNzU2MzE0ODUyMDljIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJqN21KaTVQckcvZVRiV0UwZGw2YW9SSW00NEFsMTZtUzdJOGQwL0VJM3lHWUpENERpdVI3VEpKb3ZvSjArTG9aUGxBc1g5WGd0Nml2ZExnUWJGYzI5ZnJUNkVOc2FDM0doNXNIZzZFZ2Z3aitnK0p4akRlSEVVemhtVjFsN2NyaHUzWWFhNFBTN0NrOU5qejQwQ0RBUzNKWVhuU1dhWWo2aTgrdnJlYXhac3dWYU5Vc0l2TmdCLzAzMThaeTM0NWNmM0NGcXlXUWwwSGl2VGd0b1lpUE5CRndJMzFPeUxxNjBmV213dDFvTW0wR1ZrSDBVYUZ1RzBXQnB0S21qZUxPK1Z3OE10K2hwMnp1Y3IvRkdpQklxbU4vWHc3ZklDTkZvbHE1aVVTZVhvck90b0lhbVRaU0d3cG5QQ2NFazVrSFNiU29nL3d5SU1hNnVpbklSQWwwa2o3bnRldnRpZWlncWs5MDhNZW9vSEtBcks1Q2RBZS96RXU1QURxU3pHaWoySFljWWZpVWhRdm5BaUtHaXladThFS1NPOWJIQm9ocGQ4Z1NEdC96VkVBPSJ9XX0=" + } + }, + { + "ID": "dfe1398db01c8eb9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "49cc10ce-2fd1-5331-a44f-703aef0a1dfe" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MTc5OCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTE2In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiZGRhYjIyMDQtMmU2MC00MTVhLWFjYTktYWExOWEzNzlmMmU1IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJLVmN0d3dCMXZxQ0ZLVHl6Tlh1NVhTWEUrWGhyVklDc2xzV0VzdXAxS3YyMCtvRDk2VVJOeC9yL0VxYzZzbjVjUjNWK2pwQkU0R3k1bndDLzlnWklaYnI0WFNVZ1g2WWVPWUpkVmtRQTFzME1WQWIyK1lWTjFEUkpSckRIYmlxQmtjV0VFQnArQUNOTVFDa284U1d6dGVYWkRCYVo1Rm45RWZTdFNJUnFCdkRheEFRd3R0d2t2dVBOVElhN2lRZk5nVk5pb0Vla1QxdXVpcklNekNIcmUwSnNkMTZ5d2QxR0NzaHhidUVXbEdoSE16Y2RBK2ZXS2Rhc09URUNYYnJVMzVPTnEzb3V2bjUwSjhlWVdtR01GZDhLdERHSUZQVHZCbk9pUktZUWZMZHY5UVVCY1R2N3FGRnlZdjNya2dpcnhwbzVhUEhSRk4rczMzQXRLdXVjQnZLblNacXZjTHU2VjcxekxRZGNOeEs5Y3JBMmI3ajZrV3JxNTAvMlRoTGFVa1cwRDFuQmo1aS9NRDJkbUhNYzd0Q0pZckozbjlkWmhFaFlKVUZjWHhFPSJ9XX0=" + } + }, + { + "ID": "4d5fa2d30be0d2e0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "27758578-8439-5e71-8507-e58c44e230be" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MTg1NiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTA4In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiZTBmYWFjOGQtYzkwZi00MTBiLTkyNTQtOGMwNzJkY2Y5ZTQzIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJlNUVzeVRLNVBoazFJY0xXK2FJd1gza1VhQ1BnR2RrNzBMejFDR2JDa2VsWUQ3dWFCejN6aW5VZVl0VkZKOW5BNDZCRWFhYm9ZYVdxbGNFV1BNT0lxYkxWTndpeFdhQUlqV0JOMVpzS05GbGZISnE4bGZWNkdBdU1Yd3cwTWw2S3Bqd3JSdS8wOWpvUkVGZzE5dFVLZ1RHZVZlS2tNMXl3akwrZGhUbXJHb3Z3ZlN4YnZXNHRBdFZOYWtaVlNCMkViTFNIaXcrOFZkaTMyTTFnSUlaTVhON043VTNnQ0NvZjAyWnRKNWpmU1pJd1VhbjB0R05Fckh5STgrclE3cEhDcUVYeUtOVy9IL3gyeS9sQ29yUkh3S2l3bW5RMTFiRXQ0ZjlWWTV5azU4SUw0SEJUdyswS2lwbU0yVjNSanhmZ0h0WjJaQmZTK3pDeXJWczd6TnBJMEFzUzVGcFFpZ2tYVEVVS0VWM05Dbk1CeHJZMG1YUnlTbWxLWjFiMm1GaTFsdmlhMUhGcjJrcDhadGZRWGY0RnJRN1FKbEgrR25Ka0VsKzNvNHpXSW8wPSJ9XX0=" + } + }, + { + "ID": "198bd41081abf4e6", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "85779dfe-4b37-562f-a2e6-fd0a8becc8e0" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MTkxNiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTgxIn0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiZGNlMmQzNzAtMzc5NC00ZGJlLTgwMjYtYjk1ZWMzNTg0NjIxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJiYWYxamN4TmZDSFE4RkFBbEk2dmtUVUhnZFBRbTJsaE10cG9YMjJ6WHFIUEZNR0RlMngyalpZTmFWWjhVQXpuTm1uWDllWERSV3loWnFwWG0wU1kzdUlEQ3IvbHl5TUErT0k0VjRiWW5iQlphU2xnMmh3alczWkdPSXp2WVZXcHQ1UUZQeWlpaVI5NDl0VUprL3FMYnhMR0VsWk00bC9VVHVZVE82bzBrZzlrVDlCMjZIaFVEODV5NTRQWnAxOWRBMno1U2xES1BBWDhuM3VReXZRREJoUFpYZVM4bnZGZWlqTWI0VGk1WUlNb0J6cjM0RmNGSXNqSlQ2TFRoY29PdEMvbndjelRwSzZLQ1orVk5jOTNMWDFsZXFjQ2JBWDBLQzd4MFpRQnVueWdOVmg1bkJKdEJsc1p0QmJvYzN5S210N092S1J6WGpMVmRsdlUveTA5YkVJOWlWWk1iQ1JEbG9DU2lmUzg5WHJZaTljRWhHam9aVnY1WnBoQ2V6ekZBSkZIcmZ1cmVZK1ZWZmtMMTJjR3cyeGN0bjFqT1FYcUZDTzRYS0haSU44PSJ9XX0=" + } + }, + { + "ID": "c2516b7d28bb25cc", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2873" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQk1ITGU4VXE3RFQ1amd3KzEyNzB5YTRvY1FrcWhwSHgxT3NyUXN5ZHRmMGJQenhoQlkyUkZINjdlR2ZydGZPeXRnVVErdVQ2a1cxMDZtWnJEZUNyTVE3NTBBOTBhK0V6dUVsN2U0eDNST01taFVUR2RpYlFvbFdNOWUyVWJCc21yeHVYcHR0dFF3QlAxUUVpczk5WHZ4N1FEMkxQMTZ6QkJvYWtZY2g1RjVLUWF0VU14YUVaZUE0VmtlaW5ib1BNRjJBZWpzQ1NhYnFvdXIyQURLSStZMGlLK09SUkFZZ01ISGdzbEhTUHc1aXpvVzFrZXlEVjZZc2NtQWYrTVpPeE1IYzlQbE9SbDlQVEpIZWpMdURaQ1BSYnU2RzBMUEpLVEtVN3FHMSsraFJOcnpRR0lBZTBWd2NCN1l2ZHFxb0c4V2VrOFNoUy9FQTBQcVkvK3dBN1ZWTTNIMVpjRHN0VXp4N0lkNjBic3ZaeEN4dkdMSHJjWXNNRmVWZ21nV0gyc1lKL1dLYTZNV2lZWlFVNWhPL3AwSEZsMHZHdFdCSmdGVWo2SEdTSFp0Nmc9In0seyJJZCI6IjEiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnBlV1J1SmZqYWh0bmZScXJaRzIxVHV5UmRLU3RUb3pxckJHZ056dWdEa1JYM0JJNHMrY0JwYnVOQTcyRTVPUGZMK1RXM2REY2dZZ3NycjNEUmEwOVhFYXlsMXV6Vk8yT2x5RkxRditnWW5IVUs4U3FNd29zRWZDckhUN0pRcktOT0x4c3ZCV2l2V0x6OEhIZ1RDeGpuL2ZVSFZzS2s0bXB3U2YrTlVlMFBMWDBkbmk1b2tYeUFvUFdEZmdqcDE0VzZDTVQ0dHVjbEVOMlZZZkh2S3ZCWC9xakNjQThlcXJOdlpHT2pMaTU1WU90QWt3d1pwSEx1SFhsTjNWc1Q3Q2NZR0RObFlCYldTYWFaUnkyUC93dkk0WWxua08xbG9XbTk3dGE0VXhMZlM0eGJveGpjNVQ3V2o3TThmRVp0cXhpOWJOcmhKak1icmpwWEtyWWlsMzF0R0ZscjlQYldhTHhoQjIyZ21WNUt0TS9wTHhqN0ZoRlZ2cTQ3S1Zyd1dCekF0MVI5dWxHQURENXk3OFpXejJhVVkvRStKSGFJZnRPV1dBWXNwYldDVTA9In0seyJJZCI6IjIiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmo3bUppNVByRy9lVGJXRTBkbDZhb1JJbTQ0QWwxNm1TN0k4ZDAvRUkzeUdZSkQ0RGl1UjdUSkpvdm9KMCtMb1pQbEFzWDlYZ3Q2aXZkTGdRYkZjMjlmclQ2RU5zYUMzR2g1c0hnNkVnZndqK2crSnhqRGVIRVV6aG1WMWw3Y3JodTNZYWE0UFM3Q2s5Tmp6NDBDREFTM0pZWG5TV2FZajZpOCt2cmVheFpzd1ZhTlVzSXZOZ0IvMDMxOFp5MzQ1Y2YzQ0ZxeVdRbDBIaXZUZ3RvWWlQTkJGd0kzMU95THE2MGZXbXd0MW9NbTBHVmtIMFVhRnVHMFdCcHRLbWplTE8rVnc4TXQraHAyenVjci9GR2lCSXFtTi9YdzdmSUNORm9scTVpVVNlWG9yT3RvSWFtVFpTR3dwblBDY0VrNWtIU2JTb2cvd3lJTWE2dWluSVJBbDBrajdudGV2dGllaWdxazkwOE1lb29IS0FySzVDZEFlL3pFdTVBRHFTekdpajJIWWNZZmlVaFF2bkFpS0dpeVp1OEVLU085YkhCb2hwZDhnU0R0L3pWRUE9In0seyJJZCI6IjMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQktWY3R3d0IxdnFDRktUeXpOWHU1WFNYRStYaHJWSUNzbHNXRXN1cDFLdjIwK29EOTZVUk54L3IvRXFjNnNuNWNSM1YranBCRTRHeTVud0MvOWdaSVpicjRYU1VnWDZZZU9ZSmRWa1FBMXMwTVZBYjIrWVZOMURSSlJyREhiaXFCa2NXRUVCcCtBQ05NUUNrbzhTV3p0ZVhaREJhWjVGbjlFZlN0U0lScUJ2RGF4QVF3dHR3a3Z1UE5USWE3aVFmTmdWTmlvRWVrVDF1dWlySU16Q0hyZTBKc2QxNnl3ZDFHQ3NoeGJ1RVdsR2hITXpjZEErZldLZGFzT1RFQ1hiclUzNU9OcTNvdXZuNTBKOGVZV21HTUZkOEt0REdJRlBUdkJuT2lSS1lRZkxkdjlRVUJjVHY3cUZGeVl2M3JrZ2lyeHBvNWFQSFJGTitzMzNBdEt1dWNCdktuU1pxdmNMdTZWNzF6TFFkY054SzljckEyYjdqNmtXcnE1MC8yVGhMYVVrVzBEMW5CajVpL01EMmRtSE1jN3RDSllySjNuOWRaaEVoWUpVRmNYeEU9In0seyJJZCI6IjQiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmU1RXN5VEs1UGhrMUljTFcrYUl3WDNrVWFDUGdHZGs3MEx6MUNHYkNrZWxZRDd1YUJ6M3ppblVlWXRWRko5bkE0NkJFYWFib1lhV3FsY0VXUE1PSXFiTFZOd2l4V2FBSWpXQk4xWnNLTkZsZkhKcThsZlY2R0F1TVh3dzBNbDZLcGp3clJ1LzA5am9SRUZnMTl0VUtnVEdlVmVLa00xeXdqTCtkaFRtckdvdndmU3hidlc0dEF0Vk5ha1pWU0IyRWJMU0hpdys4VmRpMzJNMWdJSVpNWE43TjdVM2dDQ29mMDJadEo1amZTWkl3VWFuMHRHTkVySHlJOCtyUTdwSENxRVh5S05XL0gveDJ5L2xDb3JSSHdLaXdtblExMWJFdDRmOVZZNXlrNThJTDRIQlR3KzBLaXBtTTJWM1JqeGZnSHRaMlpCZlMrekN5clZzN3pOcEkwQXNTNUZwUWlna1hURVVLRVYzTkNuTUJ4clkwbVhSeVNtbEtaMWIybUZpMWx2aWExSEZyMmtwOFp0ZlFYZjRGclE3UUpsSCtHbkprRWwrM280eldJbzA9In0seyJJZCI6IjUiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmJhZjFqY3hOZkNIUThGQUFsSTZ2a1RVSGdkUFFtMmxoTXRwb1gyMnpYcUhQRk1HRGUyeDJqWllOYVZaOFVBem5ObW5YOWVYRFJXeWhacXBYbTBTWTN1SURDci9seXlNQStPSTRWNGJZbmJCWmFTbGcyaHdqVzNaR09JenZZVldwdDVRRlB5aWlpUjk0OXRVSmsvcUxieExHRWxaTTRsL1VUdVlUTzZvMGtnOWtUOUIyNkhoVUQ4NXk1NFBacDE5ZEEyejVTbERLUEFYOG4zdVF5dlFEQmhQWlhlUzhudkZlaWpNYjRUaTVZSU1vQnpyMzRGY0ZJc2pKVDZMVGhjb090Qy9ud2N6VHBLNktDWitWTmM5M0xYMWxlcWNDYkFYMEtDN3gwWlFCdW55Z05WaDVuQkp0QmxzWnRCYm9jM3lLbXQ3T3ZLUnpYakxWZGx2VS95MDliRUk5aVZaTWJDUkRsb0NTaWZTODlYcllpOWNFaEdqb1pWdjVacGhDZXp6RkFKRkhyZnVyZVkrVlZma0wxMmNHdzJ4Y3RuMWpPUVhxRkNPNFhLSFpJTjg9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "82" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:31 GMT" + ], + "X-Amzn-Requestid": [ + "46148e5c-6321-5dcd-bfff-eea8a3fa4302" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjQifSx7IklkIjoiMCJ9LHsiSWQiOiIyIn0seyJJZCI6IjMifSx7IklkIjoiMSJ9LHsiSWQiOiI1In1dfQ==" + } + }, + { + "ID": "edab0627b451b5ad", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:32 GMT" + ], + "X-Amzn-Requestid": [ + "936a4154-e72c-5768-96c2-21a027f069a7" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MjAzNiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTYzIn0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNmMwMzA1ZmItNTk5Yy00Mjk1LThkZWYtODg2Y2U2NWMzNDdiIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJFNWt6T0NOQkk5RVJ5cmxJQmt5KzB4bDhoRVZES21JUXltb082S2g1S2RQdXpGYkdpQkxLRVdJSE80c0NZcmROak91M2toTVlReDk1eUZKSkRHMytoSDdkYnpScHlBLzNtbzY3VDlUNVZxTXR3U1kxaTFrblVna3ZwdFBhTjBIdC9yS2I5Sklqb3orRkFnS3lGMm5JNGd5L1RBS1g3T1hzZjRNNm41LzE0VldXQVdqc0dwZEV5WGJhSEV4QW5Xc1FFYlNNWkpkZlF3NzhPekhseU1jM29oQmdubVFaT1ovcmV5b1pXa2Z1ZndVV3B4YW1GSGE3QmNxRkxSNDR2N1dhbW52V2gxNDVuQVdGRkg5YS9XbFBENVViUkVQYXNTV0xWNWh4MkFneG55TVgyK2JjNUlNWk1LWmJza0JqYUZCRUpJUUNHSysyMjhlTWsxT29TRFZuK3FtUHZjdmpVMHFwUHNuSFZJVCthR2hvMFVPTXYzWHptZXVMUllsaVl5MlBGVDFNZW1tQjVTVmlibnVDbHlhUzdxZ00ybEtwMVZTRmNLUmJ1R3NwWTY4PSJ9XX0=" + } + }, + { + "ID": "1f4eb40f0b3ece80", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:32 GMT" + ], + "X-Amzn-Requestid": [ + "35cbe016-9406-5334-86b2-80e254daddfb" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MjA5NSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTgxIn0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiOWU0MzdjMjQtNjk0OS00MzBkLThlNGItNjBmOWFkNWJlNzdmIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJWU2pRQkFzSHRMWVBSa3pFbVBNdkdqelNNd2JpeUdaVWx2cE0wK0FiRFJvLzMrVGlXanBBRTZZY21QaVZ4K1dwM3NPVE9TVWg5SW81UUFwQXJaR0F5a1ZUN1F6ZS9JVGdwbzNNZWtVWDdLWk9aTExGajN0alRsdU1vZFFLeEdiaXJoNnZ0TWU0a0c0dUlBbVJvUXVQUnI5eW01ei9pWjdLTDNKelkwMmk5MGQ5Q2xDQThheE5DbW45M0lHWkJyck5uMDkzSnVvWG1mWC9udzJucjRFL0cxMCtqdkt4L043ZHFaK3VOZzBBYmFKd2tWc1JwSzFhRDJ5cU1rU3F0RTBQbC9xQjIvYUlzcTAwWWhJSWUreXlUSWQzMTd5UExhcWpEZ2gvYVNCL1g3aDFBZXpmYS9RZE5HWVFnOUxOYlhvNUlTaUc5UVVsWnJEUCttNDVzUmV0bmlaVnRyVlA2bThTN0ZWYmpoQzVvbnMvL0RoVUJkb0Z1dElzNk5vQVZyNXA0VlhiNHVaZDBLRWNEZFM3a2Jqc1JoM0tkNWFNSWtsUmlQeVVzMUJwSXJRPSJ9XX0=" + } + }, + { + "ID": "f9ae0881356741a9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:32 GMT" + ], + "X-Amzn-Requestid": [ + "83baad84-1b9f-5b2d-abfa-cd70db43b5e2" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MjE1NiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTA4In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiZTY5ZDZhNDEtNzE3YS00NDQ4LTlkZjgtMjZhYjJkN2FmYzhiIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJ1ZnVWME1WUUlzYjZnUnJXdWdTV3VUczN6VG1Ga3BTeFo3dWErNEZqZFJkbm81ZE1lc29tWXNtZndTMFJxVGc5OVhoNTlodEtUcGF5WVY5eDBNck9oSEFGdnV5aTRnZnB4TUxFTTBuNCt1ZTU4YUlNc2FmWEVBUkg0Vk9BS2xkeEdOWHJIMnJKbGthd2xhRFJDR21Zd3FabVZWTHk0bDlFaUN2OS9qSVpzYVJpTmxySmdsaHRpWnBTcCs5RHZzTVRtYXFtSjBHaE9ETFhPMHVpclN1bDhTNkd2RGMzRURkRFJxNTVES3FocSsyUm1WOG1yeC9Jc0gvZnluZTVyd3g4VEdiZUhsNnFlSUx4UHMwR3d4VXNudnhvZVN1eXlhNk5veitCWW5ZSVI1WFpLeE1rWHJ3bVU4K3VDWENDaFNVTlFCV0l1UjZheENCNEl0SEhUeUw0UXhWaXVBQ25vcytBRHJMekk5QVJ5czFoY281YkRZY3FHODJNYXlpRER2TGVNcklKSnVuSjZ2aGRnN2xVSmx5QzUrcXppUmlyYno5bzU1cTV2eEY5UTFZPSJ9XX0=" + } + }, + { + "ID": "af896b7088a9f58e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:32 GMT" + ], + "X-Amzn-Requestid": [ + "fc6e86f5-4f7f-5070-bcd9-e6018fa39ebf" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MjIxNiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTc5In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiM2Q3ZDZiMmItOTZmMS00YzY0LTlmMzAtNjhjNmM0ZWEwNTcwIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJMZUJrd3BpS01HTzR3SVpyR3VrRVFLcEFHWk9RU0lNNUk0ME9nRlBQbWQrTHBpQUlzcURoOElMSnpBY0hvMHFqdFJzMWUycjhOeUpKWUx5b05WWE1VVHpad0ZRc3dLZXJUMVJWbXR4eVladEN0SUdzV1IvVDE3eE1mbW0yWFlCczVPaFlOODRXSHFiN0V2RkdULzBOdmlRZlBPOUVJdzJxdUxORlVDN05mdStYRWFUbDFtckxLY0d4djJKVENZUGNGeXN3NU4zWm0rdXYrcUNtVDBhMDVZZ2p3ampKQk81R0NjSC9vOHEvYjlNNnlRYk5rRlIyRWtaY1dDTm9kWTdHSHFOTC9nTFhPNGRYT05wR3VDQTVoQmhzV3UwUmhqRXkzQmhDL28xeXNmZysreDRMOXlYVCtXbFk0K01kWnIrSWhlaktnS1d1Y2d0dTZBV0NRWXNXQkNEZjY3U2QxelJCZUtOajVYZXFrVmFFTlUvSHF1VE5ibGh2QVBpNkRuRlA4b2pvVXk4WHEyQTZ6Ym5KTzZwZ0dPc0VaQ2dudW5wa0xNa0RCNVM3Q2lrPSJ9XX0=" + } + }, + { + "ID": "dc0211a83f03b4ad", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:32 GMT" + ], + "X-Amzn-Requestid": [ + "e9229919-863a-59c6-bf9a-f9ed46e66709" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MjI3NCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTcxIn0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNDdmYzkwZTctNTY4OC00ZjQxLTljMjctNmY0ODQ3OWJlNDg5IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJJWk1obUc4V1RMRVRXMzJxcWtQRTdyK3pPMXMxUnJ3bHh0TTFVZFZ1ZnAxSllCS2ZnYzlSZ0toVzYyRlRoNUhiSi9QTktYZW5kOTQ5T2UyNXk1V0dlaU9tbU9EbDFxcEtrRU9JMENqVEgxVVhKeU1mS3drNkRpVzllOXB0cG8vRzdDNnRybWlTRHE2ZTNxQS96aThtMUhhTDMyZXlIZ3c5a2d1M29KdkxFcHFzK2s2QTNBUUVISHhENkJTL1pvS0JmZGxsdlRaU3dNWDNNNXJTT05ZY0tLZTZiWVFPdlNKRGdVSUdGcHRmb3M1MUhyWEd6ZUVtNzBsVlAzOFVHVTRnZVcrMHk3T0pwQzZnckdST0hxN3p2MDlsUXBWRkJHN1VLNmhlOHdRcmE5cEN4TmdBdC9XN1NtMGxicDRranVZbTNld2dFT0szM0VGMWoraWxMNm1BQld0VFR0a09iU0hyK3NuL3dtSyt3YTZTQndhREl4Wk1WV0J3VjFiVWQzWXc0Zm5keHBHYXEzUXRwWTVlQzVvMDA3ZGJhbzRBN21jQ2hlamR1VnJBM1dnPSJ9XX0=" + } + }, + { + "ID": "12f57b58c9126841", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "749" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:32 GMT" + ], + "X-Amzn-Requestid": [ + "a087be5f-24e3-59cd-9e08-deabe43f7702" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MjMzOCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUxNTgyIn0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNjRlOTE4MzAtYmQyZi00ODM2LWFhY2EtNmVmYjZhYzg1MDlkIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJteEY3M2MxWDh1SmNoK2x5TmhOek1VODRERGFmSGZTdjRBaitBcWJCUHppRk5pdEpRYUllNDNrMktJTktQZ1ZiL240TjNqZzZHcmlUdU93RlJhRjQwZ3F3ZE41djBoV1U3dENXL2NxYWRNa2kwSGhIa2VmSEwzeWVXdnM3QW1TaDBpYUQySGJiLzF5V3VicnB5U1N4NVZJbXRKVlhrUld1VnFNS21CaWlrdWlTeG1IOW9yRWg4UFRHQWpHckdoYWtSM1hjWmxpU2dHenZxQVJpd3k2Zm1HVWIvZ0tkZHdhRWtxZlRPV0diRjR4dllZMmVHN2FLQjFzNHgyVHBNaUJiQkJxVHZnR2ZpSmVtUFN3RTFvWkVQcjRvNnY3RktONGRwY3VCc05aQk1GOWZ5TFFjZk1jSGIyWnFkUGdaOEtKY1pqQjlCVnpOQVRzTmtDOGNMVG9ybkRldnB0Nzk2Nnk2Snh3L1B4NDQzSlg0WkZDTm40cHZEQittYWNhK0dyTytrUGgxTkhHN2poQ3Nma3lhWDQ0TGU0U3laK3UvbzVZSzZid0VQclI4MzY0PSJ9XX0=" + } + }, + { + "ID": "c1437c2ade46f46e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2873" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkU1a3pPQ05CSTlFUnlybElCa3krMHhsOGhFVkRLbUlReW1vTzZLaDVLZFB1ekZiR2lCTEtFV0lITzRzQ1lyZE5qT3Uza2hNWVF4OTV5RkpKREczK2hIN2RielJweUEvM21vNjdUOVQ1VnFNdHdTWTFpMWtuVWdrdnB0UGFOMEh0L3JLYjlKSWpveitGQWdLeUYybkk0Z3kvVEFLWDdPWHNmNE02bjUvMTRWV1dBV2pzR3BkRXlYYmFIRXhBbldzUUViU01aSmRmUXc3OE96SGx5TWMzb2hCZ25tUVpPWi9yZXlvWldrZnVmd1VXcHhhbUZIYTdCY3FGTFI0NHY3V2FtbnZXaDE0NW5BV0ZGSDlhL1dsUEQ1VWJSRVBhc1NXTFY1aHgyQWd4bnlNWDIrYmM1SU1aTUtaYnNrQmphRkJFSklRQ0dLKzIyOGVNazFPb1NEVm4rcW1QdmN2alUwcXBQc25IVklUK2FHaG8wVU9NdjNYem1ldUxSWWxpWXkyUEZUMU1lbW1CNVNWaWJudUNseWFTN3FnTTJsS3AxVlNGY0tSYnVHc3BZNjg9In0seyJJZCI6IjEiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlZTalFCQXNIdExZUFJrekVtUE12R2p6U013Yml5R1pVbHZwTTArQWJEUm8vMytUaVdqcEFFNlljbVBpVngrV3Azc09UT1NVaDlJbzVRQXBBclpHQXlrVlQ3UXplL0lUZ3BvM01la1VYN0taT1pMTEZqM3RqVGx1TW9kUUt4R2Jpcmg2dnRNZTRrRzR1SUFtUm9RdVBScjl5bTV6L2laN0tMM0p6WTAyaTkwZDlDbENBOGF4TkNtbjkzSUdaQnJyTm4wOTNKdW9YbWZYL253Mm5yNEUvRzEwK2p2S3gvTjdkcVordU5nMEFiYUp3a1ZzUnBLMWFEMnlxTWtTcXRFMFBsL3FCMi9hSXNxMDBZaElJZSt5eVRJZDMxN3lQTGFxakRnaC9hU0IvWDdoMUFlemZhL1FkTkdZUWc5TE5iWG81SVNpRzlRVWxackRQK200NXNSZXRuaVpWdHJWUDZtOFM3RlZiamhDNW9ucy8vRGhVQmRvRnV0SXM2Tm9BVnI1cDRWWGI0dVpkMEtFY0RkUzdrYmpzUmgzS2Q1YU1Ja2xSaVB5VXMxQnBJclE9In0seyJJZCI6IjIiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnVmdVYwTVZRSXNiNmdScld1Z1NXdVRzM3pUbUZrcFN4Wjd1YSs0RmpkUmRubzVkTWVzb21Zc21md1MwUnFUZzk5WGg1OWh0S1RwYXlZVjl4ME1yT2hIQUZ2dXlpNGdmcHhNTEVNMG40K3VlNThhSU1zYWZYRUFSSDRWT0FLbGR4R05Yckgyckpsa2F3bGFEUkNHbVl3cVptVlZMeTRsOUVpQ3Y5L2pJWnNhUmlObHJKZ2xodGlacFNwKzlEdnNNVG1hcW1KMEdoT0RMWE8wdWlyU3VsOFM2R3ZEYzNFRGREUnE1NURLcWhxKzJSbVY4bXJ4L0lzSC9meW5lNXJ3eDhUR2JlSGw2cWVJTHhQczBHd3hVc252eG9lU3V5eWE2Tm96K0JZbllJUjVYWkt4TWtYcndtVTgrdUNYQ0NoU1VOUUJXSXVSNmF4Q0I0SXRISFR5TDRReFZpdUFDbm9zK0FEckx6STlBUnlzMWhjbzViRFljcUc4Mk1heWlERHZMZU1ySUpKdW5KNnZoZGc3bFVKbHlDNStxemlSaXJiejlvNTVxNXZ4RjlRMVk9In0seyJJZCI6IjMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkxlQmt3cGlLTUdPNHdJWnJHdWtFUUtwQUdaT1FTSU01STQwT2dGUFBtZCtMcGlBSXNxRGg4SUxKekFjSG8wcWp0UnMxZTJyOE55SkpZTHlvTlZYTVVUelp3RlFzd0tlclQxUlZtdHh5WVp0Q3RJR3NXUi9UMTd4TWZtbTJYWUJzNU9oWU44NFdIcWI3RXZGR1QvME52aVFmUE85RUl3MnF1TE5GVUM3TmZ1K1hFYVRsMW1yTEtjR3h2MkpUQ1lQY0Z5c3c1TjNabSt1ditxQ21UMGEwNVlnandqakpCTzVHQ2NIL284cS9iOU02eVFiTmtGUjJFa1pjV0NOb2RZN0dIcU5ML2dMWE80ZFhPTnBHdUNBNWhCaHNXdTBSaGpFeTNCaEMvbzF5c2ZnKyt4NEw5eVhUK1dsWTQrTWRacitJaGVqS2dLV3VjZ3R1NkFXQ1FZc1dCQ0RmNjdTZDF6UkJlS05qNVhlcWtWYUVOVS9IcXVUTmJsaHZBUGk2RG5GUDhvam9VeThYcTJBNnpibkpPNnBnR09zRVpDZ251bnBrTE1rREI1UzdDaWs9In0seyJJZCI6IjQiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQklaTWhtRzhXVExFVFczMnFxa1BFN3Irek8xczFScndseHRNMVVkVnVmcDFKWUJLZmdjOVJnS2hXNjJGVGg1SGJKL1BOS1hlbmQ5NDlPZTI1eTVXR2VpT21tT0RsMXFwS2tFT0kwQ2pUSDFVWEp5TWZLd2s2RGlXOWU5cHRwby9HN0M2dHJtaVNEcTZlM3FBL3ppOG0xSGFMMzJleUhndzlrZ3Uzb0p2TEVwcXMrazZBM0FRRUhIeEQ2QlMvWm9LQmZkbGx2VFpTd01YM001clNPTlljS0tlNmJZUU92U0pEZ1VJR0ZwdGZvczUxSHJYR3plRW03MGxWUDM4VUdVNGdlVysweTdPSnBDNmdyR1JPSHE3enYwOWxRcFZGQkc3VUs2aGU4d1FyYTlwQ3hOZ0F0L1c3U20wbGJwNGtqdVltM2V3Z0VPSzMzRUYxaitpbEw2bUFCV3RUVHRrT2JTSHIrc24vd21LK3dhNlNCd2FESXhaTVZXQndWMWJVZDNZdzRmbmR4cEdhcTNRdHBZNWVDNW8wMDdkYmFvNEE3bWNDaGVqZHVWckEzV2c9In0seyJJZCI6IjUiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQm14RjczYzFYOHVKY2grbHlOaE56TVU4NEREYWZIZlN2NEFqK0FxYkJQemlGTml0SlFhSWU0M2syS0lOS1BnVmIvbjROM2pnNkdyaVR1T3dGUmFGNDBncXdkTjV2MGhXVTd0Q1cvY3FhZE1raTBIaEhrZWZITDN5ZVd2czdBbVNoMGlhRDJIYmIvMXlXdWJycHlTU3g1VkltdEpWWGtSV3VWcU1LbUJpaWt1aVN4bUg5b3JFaDhQVEdBakdyR2hha1IzWGNabGlTZ0d6dnFBUml3eTZmbUdVYi9nS2Rkd2FFa3FmVE9XR2JGNHh2WVkyZUc3YUtCMXM0eDJUcE1pQmJCQnFUdmdHZmlKZW1QU3dFMW9aRVByNG82djdGS040ZHBjdUJzTlpCTUY5ZnlMUWNmTWNIYjJacWRQZ1o4S0pjWmpCOUJWek5BVHNOa0M4Y0xUb3JuRGV2cHQ3OTY2eTZKeHcvUHg0NDNKWDRaRkNObjRwdkRCK21hY2ErR3JPK2tQaDFOSEc3amhDc2ZreWFYNDRMZTRTeVordS9vNVlLNmJ3RVByUjgzNjQ9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "82" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:32 GMT" + ], + "X-Amzn-Requestid": [ + "9e74b983-72a5-57d4-b4e2-d977b279391b" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjEifSx7IklkIjoiMiJ9LHsiSWQiOiIzIn0seyJJZCI6IjUifSx7IklkIjoiMCJ9LHsiSWQiOiI0In1dfQ==" + } + }, + { + "ID": "74f0dfeb1aa004cb", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0JhdGNoaW5nLXRvcC0xJTNBYjIyY2U2ZjctY2QyZC00ZDdjLTlhMTAtNTQ5MWZkZmQ1OWUxJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:32 GMT" + ], + "X-Amzn-Requestid": [ + "cec15a0b-dce1-521e-b653-3aff1c3dedb0" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5jZWMxNWEwYi1kY2UxLTUyMWUtYjY1My0zYWZmMWMzZGVkYjA8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "c7f1db1c19fd205e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "89" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0JhdGNoaW5nLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:32 GMT" + ], + "X-Amzn-Requestid": [ + "b4f73431-b1cd-5acb-ab8e-54c571114404" + ] + }, + "Body": "" + } + }, + { + "ID": "962b83b14b6e99a9", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "117" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3QmF0Y2hpbmctdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:32 GMT" + ], + "X-Amzn-Requestid": [ + "3189fd36-085d-5380-bd5d-9dc2c8813c2e" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4zMTg5ZmQzNi0wODVkLTUzODAtYmQ1ZC05ZGMyYzg4MTNjMmU8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestCancelSendReceive.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestCancelSendReceive.replay new file mode 100644 index 000000000..5fda85cd9 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestCancelSendReceive.replay @@ -0,0 +1,487 @@ +{ + "Initial": "AQAAAA7gDLWnDmWZ5AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "736b6883dd108012", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "77" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdDYW5jZWxTZW5kUmVjZWl2ZS10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "341" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:43 GMT" + ], + "X-Amzn-Requestid": [ + "279a1368-f24f-587e-827c-739c32a85c1d" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3Q2FuY2VsU2VuZFJlY2VpdmUtdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjI3OWExMzY4LWYyNGYtNTg3ZS04MjdjLTczOWMzMmE4NWMxZDwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "fbf684fcc171ffb8", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "50" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "98" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:43 GMT" + ], + "X-Amzn-Requestid": [ + "b5c3b827-073a-5186-9dd0-d8d3c7dd5369" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn0=" + } + }, + { + "ID": "6cfa92280c8e565a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "128" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:44 GMT" + ], + "X-Amzn-Requestid": [ + "4cad72ce-d9f0-52bc-b05a-123a19186053" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn19" + } + }, + { + "ID": "abd47589ac57c0e9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "482" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3Q2FuY2VsU2VuZFJlY2VpdmUtc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:44 GMT" + ], + "X-Amzn-Requestid": [ + "c88ab4b9-37cc-510b-aaf1-d44df72413e4" + ] + }, + "Body": "" + } + }, + { + "ID": "b8b3ca3ae303269f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "298" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0NhbmNlbFNlbmRSZWNlaXZlLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "384" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:44 GMT" + ], + "X-Amzn-Requestid": [ + "156f1eee-5017-5231-a1b5-7e1a90ff8652" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3Q2FuY2VsU2VuZFJlY2VpdmUtdG9wLTE6MzRjMGYzOTEtOTM2Ny00ZjRkLWI5ZDItYzA2MmE1N2UyNzE5PC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjE1NmYxZWVlLTUwMTctNTIzMS1hMWI1LTdlMWE5MGZmODY1MjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "f96bb708825e4697", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "172" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0NhbmNlbFNlbmRSZWNlaXZlLXRvcC0xJTNBMzRjMGYzOTEtOTM2Ny00ZjRkLWI5ZDItYzA2MmE1N2UyNzE5JlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:44 GMT" + ], + "X-Amzn-Requestid": [ + "35c9bc80-423c-5400-9fbf-dc7482d43063" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4zNWM5YmM4MC00MjNjLTU0MDAtOWZiZi1kYzc0ODJkNDMwNjM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "c286af35d96b52a6", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "98" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0NhbmNlbFNlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:44 GMT" + ], + "X-Amzn-Requestid": [ + "66faf917-73b4-5f92-9cb7-99e3b35c4d7d" + ] + }, + "Body": "" + } + }, + { + "ID": "d2487902426391f0", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "126" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3Q2FuY2VsU2VuZFJlY2VpdmUtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:44 GMT" + ], + "X-Amzn-Requestid": [ + "2ec0f576-4300-547f-82d6-958283e8701c" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4yZWMwZjU3Ni00MzAwLTU0N2YtODJkNi05NTgyODNlODcwMWM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestDoubleAck.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestDoubleAck.replay new file mode 100644 index 000000000..72965ecad --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestDoubleAck.replay @@ -0,0 +1,1223 @@ +{ + "Initial": "AQAAAA7gDLWcLsDtEAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "ae9f55a00b6f6ac0", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdEb3VibGVBY2stdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "333" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:33 GMT" + ], + "X-Amzn-Requestid": [ + "19a736ad-fc20-5a45-9e6d-56593cfc0428" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3RG91YmxlQWNrLXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4xOWE3MzZhZC1mYzIwLTVhNDUtOWU2ZC01NjU5M2NmYzA0Mjg8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "9663c42a0476a050", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "42" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "90" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:33 GMT" + ], + "X-Amzn-Requestid": [ + "c395419a-acf6-5734-bda5-216e6c2be5fa" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + } + }, + { + "ID": "39f4db9d7f508e98", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "120" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "91" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:33 GMT" + ], + "X-Amzn-Requestid": [ + "96f1d3ea-2167-5a3c-8f2d-b31ee1bad8f2" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9fQ==" + } + }, + { + "ID": "d1dcfa469b5af977", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "466" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3RG91YmxlQWNrLXN1Yi0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNSYXdEb3VibGVBY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:33 GMT" + ], + "X-Amzn-Requestid": [ + "2a3ae734-7acc-5c9a-85c5-87c0ba11de54" + ] + }, + "Body": "" + } + }, + { + "ID": "246e86f9ae5875d5", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "282" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSZQcm90b2NvbD1zcXMmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBU05TVG9waWNSYXdEb3VibGVBY2stdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "376" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:33 GMT" + ], + "X-Amzn-Requestid": [ + "8206b559-be41-5117-8169-d5ad7e9cef7a" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3RG91YmxlQWNrLXRvcC0xOjVmYjc0OWJhLWY0MzktNDQ5Yi1hNGQwLTQzZTc2ZDUzNjRhNDwvU3Vic2NyaXB0aW9uQXJuPgogIDwvU3Vic2NyaWJlUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD44MjA2YjU1OS1iZTQxLTUxMTctODE2OS1kNWFkN2U5Y2VmN2E8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvU3Vic2NyaWJlUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "7dfe66f5a9e25f8b", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "206" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0RvdWJsZUFjay10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:33 GMT" + ], + "X-Amzn-Requestid": [ + "319f865f-c494-5553-8b87-e6ab0449fb3e" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmE4MjUwYTA5LWE5ZmQtNWRmMi1iYWJmLTZhZmQ2OTIwZTM5ZjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjMxOWY4NjVmLWM0OTQtNTU1My04Yjg3LWU2YWIwNDQ5ZmIzZTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "0afeaded6747f818", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "206" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MSZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0RvdWJsZUFjay10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:33 GMT" + ], + "X-Amzn-Requestid": [ + "69d9853a-bd6e-5327-abba-e5ce7db31d4a" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjVkZjY5NjA5LTI3NmMtNTgzMi05MzUyLWY2ZmRlN2IxZjY1ZjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjY5ZDk4NTNhLWJkNmUtNTMyNy1hYmJhLWU1Y2U3ZGIzMWQ0YTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "deae6cec6876ac90", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "206" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MiZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0RvdWJsZUFjay10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:33 GMT" + ], + "X-Amzn-Requestid": [ + "e2d13f11-25ce-50b7-ac21-5fe5e5133eda" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjMwYWUyZjdlLWY1ZTQtNTU2Yy05ZDg0LTRmOGEzNTM5M2IwMTwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmUyZDEzZjExLTI1Y2UtNTBiNy1hYzIxLTVmZTVlNTEzM2VkYTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "1a77694da9afc7c0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MywiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "739" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:33 GMT" + ], + "X-Amzn-Requestid": [ + "f9e7cc18-eac6-57a4-bac1-acec2a1b956a" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1MzkzNSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUzNzY5In0sIkJvZHkiOiIwIiwiTUQ1T2ZCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNZXNzYWdlSWQiOiJlNTk4N2NlMC02NDRjLTRiOTAtODZjYi0xMTJlNTgyMjczNjciLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmRrOThrQ2oybnduNWRuYXRyL0lNSVBHWmt4a2pJTlVxK3NaOW15TjJ3Vkc2QmVnUGYxeHZ2R3BGaWwzbUJtUFp2UXlNaSt5OWN0MnRtYmdHRTlXUDR1Rzk2R0FzUWpWZnJyMU80Z1JaT1VPYkNUa2dWZERsL3BLdU9RblZpNnFJdklJTmNrelVmaVlCWjlFMkpjYjZVVlRJZjkxZ2pqZmxObDNQaEJvaGcyUDJFSS9VQ0Q3RkI1TmYvWWNubkFGeU52NUIvdGZrZjY1RDB4ZjdwbTFxYVlhYS9YbHFhaHZNV2VVdkcwWFJiKzNyMUdGODJlY3MzcStpQjNUOGtnbXpiOWNZL3NucnhONWwwTE1nQzRreDNRMkRPV3MxdXZDcDROckpLdUZBM2RlQnBGOWhxVjhQVlc0SVVoVEgzZGs0MW5rQUd6dVZvaTdxTmNmNzgrTHk3eVBXRWw5L3hIRDR1MXo2TmdJMnB6T2ZMTElERmFaQ3AzSk5WbXcwSzI5YUhsRjNkYnpRVWZGUnd1cWduR0pnV3Y4dkdVbkU4cHZaU0VBSGlGRy9tVTg9In1dfQ==" + } + }, + { + "ID": "7d35bceae90a4e1e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MywiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "739" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:33 GMT" + ], + "X-Amzn-Requestid": [ + "1673425f-206f-53bc-99f5-22abe0b2c172" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1Mzk5MyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUzOTAyIn0sIkJvZHkiOiIyIiwiTUQ1T2ZCb2R5IjoiYzgxZTcyOGQ5ZDRjMmY2MzZmMDY3Zjg5Y2MxNDg2MmMiLCJNZXNzYWdlSWQiOiIxMjZjZjA0NC0wZTBhLTQ1ZmItOTQxOS01ZDE5ZDAzMmEwOWQiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmJ1d1FPcHphWHJGREhpNjQrQ1RTRi9nR1p0eEFCZEhUT3hVbEJGa0E0NVVXeHB2VjFMRFJnL1dMZHhDNXFZVmVRWGhZMHkzT29IM042dUttN1pWVUpJZVN2T1ZxdC8wWEdzSGtJUTE2bm80ZVpTR3pHbFNhRGtWMndlTG1LZmdCK1h2M2Nyd2YzSjlTU1hOSjVab0VwYjVRSCtLajV4bTlPcDlKRXlXM3FQc0s4MjNsazJwL2tiUERvMk5wdUY4RGgwaGRNUjY5TXN2RDZnWnNQSkcvUVJ4dU8vQjlGVU9oSWxER3JFVzQrdGlnNG5STElXMTg2dDlZMlhLdmNCZEVBQWQweDgxQ1R3NklOTEJndXVLYTd3ZXVyMWUyNFErK0dVdUVLWnFmdUpqYVdlaElnVUwvZ3ljQ0RLL2ZUWHo2c3VDM1E2RlhtRk5iNkFhU04vMXdmdlNzUnRYUTVmM1o2TElycHdUTnR5bjVaaDRKZ0p3bVp0SEtpRmthVkROMXpwSUJrOHpoTXEwOWhJL05XbFNvTDVYRVROeU9NeWVBU0VyR21SSW03cEU9In1dfQ==" + } + }, + { + "ID": "35e553e0e30d0085", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MywiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "739" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:34 GMT" + ], + "X-Amzn-Requestid": [ + "196c330f-2cab-5144-88f2-53fbec75b38a" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1NDA1NCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUzODQwIn0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNZXNzYWdlSWQiOiI4YWM3NjVkYi02NGRmLTQyMmMtYmMzNS1jNTlkZGE0ODE0ZTQiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjN2Z1VjWG9HNUo3M05Qc2FybTRCMnE5S0wvUVdCamFpLzNHK0dsUEl5QkEyQUcyQld1d3ozVkR5V0xnQjVnY0phV1d0OElsTVBzK1pmZDdBdXdhY3hWS3NHQnhTK2pNQVJaREtGaDIwVGJkbmg3aFBKaCsrZTNwSnlMY1JneUViN3dvM1VjdGdwZEVvWXN0MGtrVXh1akp2SEcwNVhRYnVSL0U1SjFJRmZrTEdna1BYZUtsQVhwaVVFQWpBQW92WTlSYVpTcUJEek1xU0FDZ3ZJSEtmeDRuaEt1aG9jUnlYVEU4bndtZlFyeENOLzM0aEJCNTk0ZjBCdVYwTEhwbE4xM2dMUnd6UmNvbjFwb3V6QTNSbkZPSklVRm5wa0FxZEx2WXJSMFZ2YmN1c2F3S0Q4VC9ldUpLRUNLUVhOampOUGpRM241KzZBaG1oL2ZQL3gvZjNNRjhKaFBqazdpc3VuNGd5QVJDMGtPZ21rd25KOENoeHhoek10a0FWWUNYTUVBNTA2MTk0UHdZL2RWNk1LWVJxWDF5SXJNUEY4bGkxK1Y3SXNCYXZ5SFE9In1dfQ==" + } + }, + { + "ID": "256464da38191453", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "1026" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmRrOThrQ2oybnduNWRuYXRyL0lNSVBHWmt4a2pJTlVxK3NaOW15TjJ3Vkc2QmVnUGYxeHZ2R3BGaWwzbUJtUFp2UXlNaSt5OWN0MnRtYmdHRTlXUDR1Rzk2R0FzUWpWZnJyMU80Z1JaT1VPYkNUa2dWZERsL3BLdU9RblZpNnFJdklJTmNrelVmaVlCWjlFMkpjYjZVVlRJZjkxZ2pqZmxObDNQaEJvaGcyUDJFSS9VQ0Q3RkI1TmYvWWNubkFGeU52NUIvdGZrZjY1RDB4ZjdwbTFxYVlhYS9YbHFhaHZNV2VVdkcwWFJiKzNyMUdGODJlY3MzcStpQjNUOGtnbXpiOWNZL3NucnhONWwwTE1nQzRreDNRMkRPV3MxdXZDcDROckpLdUZBM2RlQnBGOWhxVjhQVlc0SVVoVEgzZGs0MW5rQUd6dVZvaTdxTmNmNzgrTHk3eVBXRWw5L3hIRDR1MXo2TmdJMnB6T2ZMTElERmFaQ3AzSk5WbXcwSzI5YUhsRjNkYnpRVWZGUnd1cWduR0pnV3Y4dkdVbkU4cHZaU0VBSGlGRy9tVTg9In0seyJJZCI6IjEiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmJ1d1FPcHphWHJGREhpNjQrQ1RTRi9nR1p0eEFCZEhUT3hVbEJGa0E0NVVXeHB2VjFMRFJnL1dMZHhDNXFZVmVRWGhZMHkzT29IM042dUttN1pWVUpJZVN2T1ZxdC8wWEdzSGtJUTE2bm80ZVpTR3pHbFNhRGtWMndlTG1LZmdCK1h2M2Nyd2YzSjlTU1hOSjVab0VwYjVRSCtLajV4bTlPcDlKRXlXM3FQc0s4MjNsazJwL2tiUERvMk5wdUY4RGgwaGRNUjY5TXN2RDZnWnNQSkcvUVJ4dU8vQjlGVU9oSWxER3JFVzQrdGlnNG5STElXMTg2dDlZMlhLdmNCZEVBQWQweDgxQ1R3NklOTEJndXVLYTd3ZXVyMWUyNFErK0dVdUVLWnFmdUpqYVdlaElnVUwvZ3ljQ0RLL2ZUWHo2c3VDM1E2RlhtRk5iNkFhU04vMXdmdlNzUnRYUTVmM1o2TElycHdUTnR5bjVaaDRKZ0p3bVp0SEtpRmthVkROMXpwSUJrOHpoTXEwOWhJL05XbFNvTDVYRVROeU9NeWVBU0VyR21SSW03cEU9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "38" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:34 GMT" + ], + "X-Amzn-Requestid": [ + "fe33add4-5172-53cf-9d53-cd2091ac5101" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifSx7IklkIjoiMSJ9XX0=" + } + }, + { + "ID": "4f298062995c1ac7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "1026" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmRrOThrQ2oybnduNWRuYXRyL0lNSVBHWmt4a2pJTlVxK3NaOW15TjJ3Vkc2QmVnUGYxeHZ2R3BGaWwzbUJtUFp2UXlNaSt5OWN0MnRtYmdHRTlXUDR1Rzk2R0FzUWpWZnJyMU80Z1JaT1VPYkNUa2dWZERsL3BLdU9RblZpNnFJdklJTmNrelVmaVlCWjlFMkpjYjZVVlRJZjkxZ2pqZmxObDNQaEJvaGcyUDJFSS9VQ0Q3RkI1TmYvWWNubkFGeU52NUIvdGZrZjY1RDB4ZjdwbTFxYVlhYS9YbHFhaHZNV2VVdkcwWFJiKzNyMUdGODJlY3MzcStpQjNUOGtnbXpiOWNZL3NucnhONWwwTE1nQzRreDNRMkRPV3MxdXZDcDROckpLdUZBM2RlQnBGOWhxVjhQVlc0SVVoVEgzZGs0MW5rQUd6dVZvaTdxTmNmNzgrTHk3eVBXRWw5L3hIRDR1MXo2TmdJMnB6T2ZMTElERmFaQ3AzSk5WbXcwSzI5YUhsRjNkYnpRVWZGUnd1cWduR0pnV3Y4dkdVbkU4cHZaU0VBSGlGRy9tVTg9In0seyJJZCI6IjEiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmJ1d1FPcHphWHJGREhpNjQrQ1RTRi9nR1p0eEFCZEhUT3hVbEJGa0E0NVVXeHB2VjFMRFJnL1dMZHhDNXFZVmVRWGhZMHkzT29IM042dUttN1pWVUpJZVN2T1ZxdC8wWEdzSGtJUTE2bm80ZVpTR3pHbFNhRGtWMndlTG1LZmdCK1h2M2Nyd2YzSjlTU1hOSjVab0VwYjVRSCtLajV4bTlPcDlKRXlXM3FQc0s4MjNsazJwL2tiUERvMk5wdUY4RGgwaGRNUjY5TXN2RDZnWnNQSkcvUVJ4dU8vQjlGVU9oSWxER3JFVzQrdGlnNG5STElXMTg2dDlZMlhLdmNCZEVBQWQweDgxQ1R3NklOTEJndXVLYTd3ZXVyMWUyNFErK0dVdUVLWnFmdUpqYVdlaElnVUwvZ3ljQ0RLL2ZUWHo2c3VDM1E2RlhtRk5iNkFhU04vMXdmdlNzUnRYUTVmM1o2TElycHdUTnR5bjVaaDRKZ0p3bVp0SEtpRmthVkROMXpwSUJrOHpoTXEwOWhJL05XbFNvTDVYRVROeU9NeWVBU0VyR21SSW03cEU9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "38" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:34 GMT" + ], + "X-Amzn-Requestid": [ + "e40bdf77-289c-5e29-b4d7-bf83e8424ce7" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifSx7IklkIjoiMSJ9XX0=" + } + }, + { + "ID": "9fad8d5b58f1105a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "1554" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ChangeMessageVisibilityBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmRrOThrQ2oybnduNWRuYXRyL0lNSVBHWmt4a2pJTlVxK3NaOW15TjJ3Vkc2QmVnUGYxeHZ2R3BGaWwzbUJtUFp2UXlNaSt5OWN0MnRtYmdHRTlXUDR1Rzk2R0FzUWpWZnJyMU80Z1JaT1VPYkNUa2dWZERsL3BLdU9RblZpNnFJdklJTmNrelVmaVlCWjlFMkpjYjZVVlRJZjkxZ2pqZmxObDNQaEJvaGcyUDJFSS9VQ0Q3RkI1TmYvWWNubkFGeU52NUIvdGZrZjY1RDB4ZjdwbTFxYVlhYS9YbHFhaHZNV2VVdkcwWFJiKzNyMUdGODJlY3MzcStpQjNUOGtnbXpiOWNZL3NucnhONWwwTE1nQzRreDNRMkRPV3MxdXZDcDROckpLdUZBM2RlQnBGOWhxVjhQVlc0SVVoVEgzZGs0MW5rQUd6dVZvaTdxTmNmNzgrTHk3eVBXRWw5L3hIRDR1MXo2TmdJMnB6T2ZMTElERmFaQ3AzSk5WbXcwSzI5YUhsRjNkYnpRVWZGUnd1cWduR0pnV3Y4dkdVbkU4cHZaU0VBSGlGRy9tVTg9IiwiVmlzaWJpbGl0eVRpbWVvdXQiOjF9LHsiSWQiOiIxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJidXdRT3B6YVhyRkRIaTY0K0NUU0YvZ0dadHhBQmRIVE94VWxCRmtBNDVVV3hwdlYxTERSZy9XTGR4QzVxWVZlUVhoWTB5M09vSDNONnVLbTdaVlVKSWVTdk9WcXQvMFhHc0hrSVExNm5vNGVaU0d6R2xTYURrVjJ3ZUxtS2ZnQitYdjNjcndmM0o5U1NYTko1Wm9FcGI1UUgrS2o1eG05T3A5SkV5VzNxUHNLODIzbGsycC9rYlBEbzJOcHVGOERoMGhkTVI2OU1zdkQ2Z1pzUEpHL1FSeHVPL0I5RlVPaElsREdyRVc0K3RpZzRuUkxJVzE4NnQ5WTJYS3ZjQmRFQUFkMHg4MUNUdzZJTkxCZ3V1S2E3d2V1cjFlMjRRKytHVXVFS1pxZnVKamFXZWhJZ1VML2d5Y0NESy9mVFh6NnN1QzNRNkZYbUZOYjZBYVNOLzF3ZnZTc1J0WFE1ZjNaNkxJcnB3VE50eW41Wmg0SmdKd21adEhLaUZrYVZETjF6cElCazh6aE1xMDloSS9OV2xTb0w1WEVUTnlPTXllQVNFckdtUkltN3BFPSIsIlZpc2liaWxpdHlUaW1lb3V0IjoxfSx7IklkIjoiMiIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCM3ZnVWNYb0c1SjczTlBzYXJtNEIycTlLTC9RV0JqYWkvM0crR2xQSXlCQTJBRzJCV3V3ejNWRHlXTGdCNWdjSmFXV3Q4SWxNUHMrWmZkN0F1d2FjeFZLc0dCeFMrak1BUlpES0ZoMjBUYmRuaDdoUEpoKytlM3BKeUxjUmd5RWI3d28zVWN0Z3BkRW9Zc3Qwa2tVeHVqSnZIRzA1WFFidVIvRTVKMUlGZmtMR2drUFhlS2xBWHBpVUVBakFBb3ZZOVJhWlNxQkR6TXFTQUNndklIS2Z4NG5oS3Vob2NSeVhURThud21mUXJ4Q04vMzRoQkI1OTRmMEJ1VjBMSHBsTjEzZ0xSd3pSY29uMXBvdXpBM1JuRk9KSVVGbnBrQXFkTHZZclIwVnZiY3VzYXdLRDhUL2V1SktFQ0tRWE5qak5QalEzbjUrNkFobWgvZlAveC9mM01GOEpoUGprN2lzdW40Z3lBUkMwa09nbWt3bko4Q2h4eGh6TXRrQVZZQ1hNRUE1MDYxOTRQd1kvZFY2TUtZUnFYMXlJck1QRjhsaTErVjdJc0JhdnlIUT0iLCJWaXNpYmlsaXR5VGltZW91dCI6MX1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "332" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:34 GMT" + ], + "X-Amzn-Requestid": [ + "abc0c3a7-b5da-571a-85d4-a353750455d4" + ] + }, + "Body": "eyJGYWlsZWQiOlt7IkNvZGUiOiJSZWNlaXB0SGFuZGxlSXNJbnZhbGlkIiwiSWQiOiIwIiwiTWVzc2FnZSI6Ik1lc3NhZ2UgZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IGF2YWlsYWJsZSBmb3IgdmlzaWJpbGl0eSB0aW1lb3V0IGNoYW5nZSIsIlNlbmRlckZhdWx0Ijp0cnVlfSx7IkNvZGUiOiJSZWNlaXB0SGFuZGxlSXNJbnZhbGlkIiwiSWQiOiIxIiwiTWVzc2FnZSI6Ik1lc3NhZ2UgZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IGF2YWlsYWJsZSBmb3IgdmlzaWJpbGl0eSB0aW1lb3V0IGNoYW5nZSIsIlNlbmRlckZhdWx0Ijp0cnVlfV0sIlN1Y2Nlc3NmdWwiOlt7IklkIjoiMiJ9XX0=" + } + }, + { + "ID": "a617a94d98f6c356", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:34 GMT" + ], + "X-Amzn-Requestid": [ + "7d1ed4f9-d453-505e-b947-b40d148db290" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "b1be475b98936c01", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:34 GMT" + ], + "X-Amzn-Requestid": [ + "1ef159c4-8afa-5add-b216-39304a244813" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ac7f68ff9f079c01", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:35 GMT" + ], + "X-Amzn-Requestid": [ + "8a660a9c-d5c1-5b9c-807c-6a68151e5952" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "f7569f8da46c7e31", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "171" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "739" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:35 GMT" + ], + "X-Amzn-Requestid": [ + "c8421890-fd7a-55f3-9119-78643da5173d" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1NDA1NCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMiIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjUzODQwIn0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNZXNzYWdlSWQiOiI4YWM3NjVkYi02NGRmLTQyMmMtYmMzNS1jNTlkZGE0ODE0ZTQiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlNKTi9YVEl1NGp3UnR2Q1JBTUZyTm16MHZMMU1TVUc4RG93LzF5d2xaNEF5ZlJYTWdqaTBLcWJCNFRWVTBtNXVlM1VXbkN6L0VRcHdnUXp2RkNzZFZBeElIQy9Zc2QvdmlUOW13ZlluR0l3Q0ppNkJKUExvUWF2Rzk4eDNvS3ljRVpuZlBKdTZhNnVnblRCRGFNOXpENDljRG96dUdtN0xzTm5XK0Y1WlBrOHlrTWFBbUJsODFJQWRoWi93c0l5aTE4VEVoVFNBNFcwREZDSmhlOTdQbWxhWXU0TVllRXNCTC9ZZkk0OWlQYTB0ek16allra0UwbitzWDB3N3NBaS9tbUdVTkl4SjJFN2ZuZ0Y4NTNDQTZyNUlYeU9sRHRhSUZKdUdBZEJmaWdySUh5RzU4eXFDOUV4b2ZOTHdTNzJrZTNRalhMekhOME9OMTNldHJHTEpVWHBwNFFYWFpBMDRDenc1d0JORXIxK0NsZDFZZzFvdVJVRHRYRVBxNWUzWlN6bkYwSlZGam9DSFNnY1Y0ZlNmaytTYmYrbEtDUXJJb0Z0UXJ2RFBvWVk9In1dfQ==" + } + }, + { + "ID": "5e2d59a21d32be15", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "164" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0RvdWJsZUFjay10b3AtMSUzQTVmYjc0OWJhLWY0MzktNDQ5Yi1hNGQwLTQzZTc2ZDUzNjRhNCZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:35 GMT" + ], + "X-Amzn-Requestid": [ + "935ecc3e-eaf2-5d9a-899a-acca2a2d83f7" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD45MzVlY2MzZS1lYWYyLTVkOWEtODk5YS1hY2NhMmEyZDgzZjc8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "0938092c4c5d59ec", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "90" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0RvdWJsZUFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:35 GMT" + ], + "X-Amzn-Requestid": [ + "a66553ba-91d6-57e8-b3e1-334e5109c526" + ] + }, + "Body": "" + } + }, + { + "ID": "2ba480b0c4e3ca77", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "118" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3RG91YmxlQWNrLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:35 GMT" + ], + "X-Amzn-Requestid": [ + "4921c17c-16b2-5c8a-8460-a188d66dc2e7" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD40OTIxYzE3Yy0xNmIyLTVjOGEtODQ2MC1hMTg4ZDY2ZGMyZTc8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestErrorOnReceiveFromClosedSubscription.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestErrorOnReceiveFromClosedSubscription.replay new file mode 100644 index 000000000..e24e46963 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestErrorOnReceiveFromClosedSubscription.replay @@ -0,0 +1,487 @@ +{ + "Initial": "AQAAAA7gDLWlNxPbmQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "75d0e19c445e5d7c", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "96" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdFcnJvck9uUmVjZWl2ZUZyb21DbG9zZWRTdWJzY3JpcHRpb24tdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "360" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:42 GMT" + ], + "X-Amzn-Requestid": [ + "98fd6491-2442-5cd4-96ad-0465e4a4cf3a" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3RXJyb3JPblJlY2VpdmVGcm9tQ2xvc2VkU3Vic2NyaXB0aW9uLXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD45OGZkNjQ5MS0yNDQyLTVjZDQtOTZhZC0wNDY1ZTRhNGNmM2E8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "e552a33e77d34e30", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "117" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:42 GMT" + ], + "X-Amzn-Requestid": [ + "412b537e-08d5-5dd5-95ee-338ac83338ba" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSJ9" + } + }, + { + "ID": "1dcc205d16524697", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "147" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "118" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:42 GMT" + ], + "X-Amzn-Requestid": [ + "33abb550-fd50-5d46-8f00-d5a43db66829" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSJ9fQ==" + } + }, + { + "ID": "3be7d1d76101805f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "520" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3RXJyb3JPblJlY2VpdmVGcm9tQ2xvc2VkU3Vic2NyaXB0aW9uLXN1Yi0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNSYXdFcnJvck9uUmVjZWl2ZUZyb21DbG9zZWRTdWJzY3JpcHRpb24tc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:42 GMT" + ], + "X-Amzn-Requestid": [ + "3338b6ba-0d35-5342-9ff3-d64ecdd3c62d" + ] + }, + "Body": "" + } + }, + { + "ID": "e1b05715e9b3328b", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "336" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSZQcm90b2NvbD1zcXMmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBU05TVG9waWNSYXdFcnJvck9uUmVjZWl2ZUZyb21DbG9zZWRTdWJzY3JpcHRpb24tdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "403" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:42 GMT" + ], + "X-Amzn-Requestid": [ + "50d42164-a3ab-5289-b631-4190634d3167" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3RXJyb3JPblJlY2VpdmVGcm9tQ2xvc2VkU3Vic2NyaXB0aW9uLXRvcC0xOmY0Mzk0NGNmLWE1M2ItNGJjOS1iZTcxLTIxNTBkNTQxZjQ4NDwvU3Vic2NyaXB0aW9uQXJuPgogIDwvU3Vic2NyaWJlUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD41MGQ0MjE2NC1hM2FiLTUyODktYjYzMS00MTkwNjM0ZDMxNjc8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvU3Vic2NyaWJlUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "849c27fd9b860f28", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "191" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi10b3AtMSUzQWY0Mzk0NGNmLWE1M2ItNGJjOS1iZTcxLTIxNTBkNTQxZjQ4NCZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:43 GMT" + ], + "X-Amzn-Requestid": [ + "1bfdbf7e-0652-5e38-b722-df8ac6b4add6" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4xYmZkYmY3ZS0wNjUyLTVlMzgtYjcyMi1kZjhhYzZiNGFkZDY8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "5cd4c9b8ecf62929", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "117" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:43 GMT" + ], + "X-Amzn-Requestid": [ + "4f1bf238-0363-5875-b2ec-92ccc384bd1a" + ] + }, + "Body": "" + } + }, + { + "ID": "f19ba24ddb59d327", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "145" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3RXJyb3JPblJlY2VpdmVGcm9tQ2xvc2VkU3Vic2NyaXB0aW9uLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:43 GMT" + ], + "X-Amzn-Requestid": [ + "312fc13e-a88f-5c7d-a59e-a1ca68682f93" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4zMTJmYzEzZS1hODhmLTVjN2QtYTU5ZS1hMWNhNjg2ODJmOTM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestErrorOnSendToClosedTopic.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestErrorOnSendToClosedTopic.replay new file mode 100644 index 000000000..0543ca2c9 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestErrorOnSendToClosedTopic.replay @@ -0,0 +1,151 @@ +{ + "Initial": "AQAAAA7gDLWfLCHHqAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "70f552372af464ba", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "84" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdFcnJvck9uU2VuZFRvQ2xvc2VkVG9waWMtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "348" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:36 GMT" + ], + "X-Amzn-Requestid": [ + "bd1c1874-f70e-5b60-ad57-788037d17cc9" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3RXJyb3JPblNlbmRUb0Nsb3NlZFRvcGljLXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5iZDFjMTg3NC1mNzBlLTViNjAtYWQ1Ny03ODgwMzdkMTdjYzk8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "25df4bb0dd96960f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "133" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3RXJyb3JPblNlbmRUb0Nsb3NlZFRvcGljLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:36 GMT" + ], + "X-Amzn-Requestid": [ + "b65df97c-7caa-5753-892e-9988bc4ab0fa" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5iNjVkZjk3Yy03Y2FhLTU3NTMtODkyZS05OTg4YmM0YWIwZmE8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestMetadata.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestMetadata.replay new file mode 100644 index 000000000..96ba7a051 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestMetadata.replay @@ -0,0 +1,823 @@ +{ + "Initial": "AQAAAA7gDLWpC1sQUgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "db7524b2d4b53229", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "68" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdNZXRhZGF0YS10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "332" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:45 GMT" + ], + "X-Amzn-Requestid": [ + "5c607771-85e6-50a6-b371-1785450f50ec" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3TWV0YWRhdGEtdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjVjNjA3NzcxLTg1ZTYtNTBhNi1iMzcxLTE3ODU0NTBmNTBlYzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "c818cf46986f5c45", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "41" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "89" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:45 GMT" + ], + "X-Amzn-Requestid": [ + "2799c4fb-93f8-5863-9d67-a40f531116d2" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd01ldGFkYXRhLXN1Yi0xIn0=" + } + }, + { + "ID": "7dafc9adff9dca44", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "119" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "90" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:45 GMT" + ], + "X-Amzn-Requestid": [ + "8110daa3-985f-5036-a4f9-ba5758b6fe87" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd01ldGFkYXRhLXN1Yi0xIn19" + } + }, + { + "ID": "f46756775a105930", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "464" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3TWV0YWRhdGEtc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:45 GMT" + ], + "X-Amzn-Requestid": [ + "fc986ec2-adbe-5168-b9fb-0e366d57efd9" + ] + }, + "Body": "" + } + }, + { + "ID": "ee9276522e716198", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "280" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd01ldGFkYXRhLXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd01ldGFkYXRhLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "375" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:46 GMT" + ], + "X-Amzn-Requestid": [ + "cf2ee00a-8c90-56f0-9001-80fe4c7956ba" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3TWV0YWRhdGEtdG9wLTE6NjZjODk1MTUtOTAxNy00NmJiLWEyYjQtNDQ1YjNlYzA3ZjJkPC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmNmMmVlMDBhLThjOTAtNTZmMC05MDAxLTgwZmU0Yzc5NTZiYTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "8b3b5011f1476920", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "3733" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjEuQ0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:46 GMT" + ], + "X-Amzn-Requestid": [ + "941d76a7-5368-545a-86b5-165393822410" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjU0NGZlZTkyLTM4ZTAtNWE3MS1iNWIyLThlNjZmODBhZGEzYjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjk0MWQ3NmE3LTUzNjgtNTQ1YS04NmI1LTE2NTM5MzgyMjQxMDwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "94efd36afce120af", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2262" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:46 GMT" + ], + "X-Amzn-Requestid": [ + "e950778b-d7e4-5e25-ba4b-177f170e0094" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY2NjIxNSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjY2MTk3In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTUQ1T2ZNZXNzYWdlQXR0cmlidXRlcyI6ImYzZmJmZGUxZTgyNTI0ZGVjMDhlNGI1ZjY2MGExMDZjIiwiTWVzc2FnZUF0dHJpYnV0ZXMiOnsiMTIzNDUiOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6IjEyMzQ1In0sIl9fMHgwX19fXzB4MV9fX18weDJfX19fMHgzX19fXzB4NF9fX18weDVfX19fMHg2X19fXzB4N19fX18weDhfX19fMHg5X19fXzB4YV9fX18weGJfX19fMHhjX19fXzB4ZF9fX18weGVfX19fMHhmX18iOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6IiUwMCUwMSUwMiUwMyUwNCUwNSUwNiUwNyUwOCUwOSUwQSUwQiUwQyUwRCUwRSUwRiJ9LCJfXzB4MTBfX19fMHgxMV9fX18weDEyX19fXzB4MTNfX19fMHgxNF9fX18weDE1X19fXzB4MTZfX19fMHgxN19fX18weDE4X19fXzB4MTlfX19fMHgxYV9fX18weDFiX19fXzB4MWNfX19fMHgxZF9fX18weDFlX19fXzB4MWZfXyI6eyJEYXRhVHlwZSI6IlN0cmluZyIsIlN0cmluZ1ZhbHVlIjoiJTEwJTExJTEyJTEzJTE0JTE1JTE2JTE3JTE4JTE5JTFBJTFCJTFDJTFEJTFFJTFGIn0sIl9fMHgyMF9fX18weDIxX19fXzB4MjJfX19fMHgyM19fX18weDI0X19fXzB4MjVfX19fMHgyNl9fX18weDI3X19fXzB4MjhfX19fMHgyOV9fX18weDJhX19fXzB4MmJfX19fMHgyY19fLS5fXzB4MmZfXyI6eyJEYXRhVHlwZSI6IlN0cmluZyIsIlN0cmluZ1ZhbHVlIjoiJTIwJTIxJTIyJTIzJCUyNSYlMjclMjglMjklMkErJTJDLS4lMkYifSwiX18weDJlX19fXzB4MmVfX19fMHgyZl9fZm9vX18weDJmX18uX18weDJlX19fXzB4MmZfX2Jhcl9fMHgyZl9fLl9fMHgyZV9fX18weDJmX18uX18weDJlX19fXzB4MmZfX2Jhei5fXzB4MmVfX19fMHgyZl9fIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIuLiUyRmZvbyUyRi4uJTJGYmFyJTJGLi4lMkYuLiUyRmJhei4uJTJGIn0sIl9fMHgyZV9fX18weDJlX19fXzB4NWNfX2Zvb19fMHg1Y19fLl9fMHgyZV9fX18weDVjX19iYXJfXzB4NWNfXy5fXzB4MmVfX19fMHg1Y19fLl9fMHgyZV9fX18weDVjX19iYXouX18weDJlX19fXzB4NWNfXyI6eyJEYXRhVHlwZSI6IlN0cmluZyIsIlN0cmluZ1ZhbHVlIjoiLi4lNUNmb28lNUMuLiU1Q2JhciU1Qy4uJTVDLi4lNUNiYXouLiU1QyJ9LCJfXzB4MmVfX19fMHgyZV9fX18weDVjX19mb29fXzB4NWNfX19fMHg1Y19fYmFyX18weDVjX19fXzB4NWNfX19fMHg1Y19fYmF6Ijp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIuLiU1Q2ZvbyU1QyU1Q2JhciU1QyU1QyU1Q2JheiJ9LCJfXzB4M2FfX19fMHgzYl9fX18weDNjX19fXzB4M2RfX19fMHgzZV9fX18weDNmX18iOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6IjolM0IlM0M9JTNFJTNGIn0sIl9fMHg0MF9fIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiJAIn0sIl9fMHg1Yl9fX18weDVjX19fXzB4NWRfX19fMHg1ZV9fXyI6eyJEYXRhVHlwZSI6IlN0cmluZyIsIlN0cmluZ1ZhbHVlIjoiJTVCJTVDJTVEJTVFXyJ9fSwiTWVzc2FnZUlkIjoiOThhYzIyZDQtZTVhMy00ZThiLWJmOGEtYzE3MThhMTU3M2MwIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJ4cWhNaFBKV1FDLzlxTVIwcXRCR1ppc2RYNHNKS3pXZmhKTlZOTCtXRzltcm1zZlFQZXM2azhUUVN4a2diRlV1WkJaSVRHdlNiNmJFRk1ORWhDZzVONmtjOVRlVVRHM1I4WHg0eWI2K3pVdW00ek4vK3RPdmUveWJGbVpReDVja2RtREN1ZnJSV0ZGSDNOSEVxcEs4ZExqTkdEbHZaSW9nL1FIMHB6UVczS1ptaXpyMGFydUpDVmIyd0srUzRaTTdWU0F1dmFyVERTdkpDdmRKVHZwS3lmOFhmNFl3ZG1FdDE2ZitYbTZhUTZCeC9Bd2VHdHFacU9qWVVSQ24yM3Fsdk5wQnorOHAxeWJSZStoc2dqejNCY3ZuWUFTdXVZMnA0U0I2YlNUOVc5ZWhKM3IycndDR2hnR3RPcC96S2JOakZMNzZrMEtwcGN4dCtQNytXR1dzZk0yczB2Q0dyYzZXb0VZYXE1ZTF1MTVBdDVFZm11Rk0rWW1Pc0M5T0xDQWVrNlJYL1N2V2ZSSCsvZVhra3EwSVp3PT0ifV19" + } + }, + { + "ID": "f736fa1cbe9e9fab", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "543" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnhxaE1oUEpXUUMvOXFNUjBxdEJHWmlzZFg0c0pLeldmaEpOVk5MK1dHOW1ybXNmUVBlczZrOFRRU3hrZ2JGVXVaQlpJVEd2U2I2YkVGTU5FaENnNU42a2M5VGVVVEczUjhYeDR5YjYrelV1bTR6Ti8rdE92ZS95YkZtWlF4NWNrZG1EQ3VmclJXRkZIM05IRXFwSzhkTGpOR0RsdlpJb2cvUUgwcHpRVzNLWm1penIwYXJ1SkNWYjJ3SytTNFpNN1ZTQXV2YXJURFN2SkN2ZEpUdnBLeWY4WGY0WXdkbUV0MTZmK1htNmFRNkJ4L0F3ZUd0cVpxT2pZVVJDbjIzcWx2TnBCeis4cDF5YlJlK2hzZ2p6M0Jjdm5ZQVN1dVkycDRTQjZiU1Q5VzllaEozcjJyd0NHaGdHdE9wL3pLYk5qRkw3NmswS3BwY3h0K1A3K1dHV3NmTTJzMHZDR3JjNldvRVlhcTVlMXUxNUF0NUVmbXVGTStZbU9zQzlPTENBZWs2UlgvU3ZXZlJIKy9lWGtrcTBJWnc9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNSYXdNZXRhZGF0YS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:46 GMT" + ], + "X-Amzn-Requestid": [ + "fd5a534f-7ca7-5f33-b888-33bbbc4d4182" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "1c1f04e9c88a096b", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2487" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjEuQ0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:46 GMT" + ], + "X-Amzn-Requestid": [ + "99c6a33c-265e-5c46-a6e8-c3c8e6b45c0c" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmE3OWE4MmY4LTY5NzEtNTdkMi05NzZiLWUyMGNhOTliMzc5ODwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjk5YzZhMzNjLTI2NWUtNWM0Ni1hNmU4LWMzYzhlNmI0NWMwYzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "f1fadd7355110f29", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1501" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:46 GMT" + ], + "X-Amzn-Requestid": [ + "debacaff-b440-5fec-ba68-aa0b74aaa15d" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY2NjM0MyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjY2MzA5In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTUQ1T2ZNZXNzYWdlQXR0cmlidXRlcyI6ImRlOGJhNzBlMjkwNzY5Y2ExODU0M2RhOTI0MGRlMDI1IiwiTWVzc2FnZUF0dHJpYnV0ZXMiOnsiX18weDI2M2FfX19fMHgyNjNhX19fXzB4MjYzYV9fIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIlRTIlOTglQkElRTIlOTglQkElRTIlOTglQkEifSwiX18weDYwX18iOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6IiU2MCJ9LCJfXzB4N2JfX19fMHg3Y19fX18weDdkX19fXzB4N2VfX19fMHg3Zl9fIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIlN0IlN0MlN0R+JTdGIn0sImZvb19fMHgyMF9fYmFyX18weDIwX19iYXoiOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6ImZvbyUyMGJhciUyMGJheiJ9LCJmb29fXzB4MjJfX2Jhcl9fMHgyMl9fYmF6Ijp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiJmb28lMjJiYXIlMjJiYXoifSwiZm9vX18weDJmX19fXzB4MmZfX2Jhcl9fMHgyZl9fX18weDJmX19fXzB4MmZfX2JheiI6eyJEYXRhVHlwZSI6IlN0cmluZyIsIlN0cmluZ1ZhbHVlIjoiZm9vJTJGJTJGYmFyJTJGJTJGJTJGYmF6In0sImZvb19fMHgyZl9fYmFyX18weDJmX19iYXoiOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6ImZvbyUyRmJhciUyRmJheiJ9LCJmb29fXzB4NWNfX2Jhcl9fMHg1Y19fYmF6Ijp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiJmb28lNUNiYXIlNUNiYXoifX0sIk1lc3NhZ2VJZCI6ImNlY2Y0YjI0LTQyNGMtNGNlYS04N2IwLWRjYjkxNDkwZmFjNyIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCZTdSQnlURTI2Z1FrZENiREd2bEZJdlFQeEtTblVMTGZERVN4UXJQdEdnaytyRzlCRVdSOEFUcUtGY0o2QTNzd3I4N2FsbmM2SW9YQU95a3VsUmFFNkZOZ0xPTnJNMGhleHNFQ1pGTnVJdkgvU1hyckxhd1NseHlFQlBPRHM0YXd5OHRYV05zbi9QUVVZdklIWnYyRytVZ3lnNzJSTTNha3RrWTQ1WnF0Q3RVcVdZcmVCd1ZIMFBQdG1vcUEzbW5HU1pQS0RqUW05RHRjSjZCOFdKSlNkTE1URUFheEFVcVh3QmpnMVhGT3RQQnJqVHcrSFYwSGo4bWxVZ09pZEtCeDJvZStSeGhnazNsWG1GSU9kenFDaERmT0REVzkzblNlRU85eEl6dUN4elArU2tjU3B2NTJQRzRxWHpGWXI1cUVYVkpwMC81eFVvWHJzenhrYU5PVnV3ZlRNcmJJWEVISERvR0VKckIwL20vZFJRNFBvcUZvZDl4bWd6eVNSZUFIR2d5Q0ZjMHFLSHhxTnpsQk84bHF1dz09In1dfQ==" + } + }, + { + "ID": "87f375ca71daa8ab", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "543" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmU3UkJ5VEUyNmdRa2RDYkRHdmxGSXZRUHhLU25VTExmREVTeFFyUHRHZ2srckc5QkVXUjhBVHFLRmNKNkEzc3dyODdhbG5jNklvWEFPeWt1bFJhRTZGTmdMT05yTTBoZXhzRUNaRk51SXZIL1NYcnJMYXdTbHh5RUJQT0RzNGF3eTh0WFdOc24vUFFVWXZJSFp2MkcrVWd5ZzcyUk0zYWt0a1k0NVpxdEN0VXFXWXJlQndWSDBQUHRtb3FBM21uR1NaUEtEalFtOUR0Y0o2QjhXSkpTZExNVEVBYXhBVXFYd0JqZzFYRk90UEJyalR3K0hWMEhqOG1sVWdPaWRLQngyb2UrUnhoZ2szbFhtRklPZHpxQ2hEZk9ERFc5M25TZUVPOXhJenVDeHpQK1NrY1NwdjUyUEc0cVh6RllyNXFFWFZKcDAvNXhVb1hyc3p4a2FOT1Z1d2ZUTXJiSVhFSEhEb0dFSnJCMC9tL2RSUTRQb3FGb2Q5eG1nenlTUmVBSEdneUNGYzBxS0h4cU56bEJPOGxxdXc9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNSYXdNZXRhZGF0YS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:46 GMT" + ], + "X-Amzn-Requestid": [ + "2df6e6fa-6ec3-563e-ba4f-860eae29b88f" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "e41863b9b6e76d47", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd01ldGFkYXRhLXRvcC0xJTNBNjZjODk1MTUtOTAxNy00NmJiLWEyYjQtNDQ1YjNlYzA3ZjJkJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:46 GMT" + ], + "X-Amzn-Requestid": [ + "74825759-9362-5266-81d6-37ad5388122c" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD43NDgyNTc1OS05MzYyLTUyNjYtODFkNi0zN2FkNTM4ODEyMmM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "d09b344916961d06", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "89" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd01ldGFkYXRhLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:46 GMT" + ], + "X-Amzn-Requestid": [ + "a48f7c5c-df2a-5f99-9b78-1ca81fc06128" + ] + }, + "Body": "" + } + }, + { + "ID": "a61c48473e9844c9", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "117" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3TWV0YWRhdGEtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:46 GMT" + ], + "X-Amzn-Requestid": [ + "54d49888-1e58-56a0-9f4b-f87cdeb2f6ea" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD41NGQ0OTg4OC0xZTU4LTU2YTAtOWY0Yi1mODdjZGViMmY2ZWE8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNack.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNack.replay new file mode 100644 index 000000000..747efa1a3 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNack.replay @@ -0,0 +1,1693 @@ +{ + "Initial": "AQAAAA7gDLWUNR6zPwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "247ad0634af29cc1", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "64" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdOYWNrLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "328" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:25 GMT" + ], + "X-Amzn-Requestid": [ + "9cca7b35-1fe3-5367-9621-1bc1df36af0d" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3TmFjay10b3AtMTwvVG9waWNBcm4+CiAgPC9DcmVhdGVUb3BpY1Jlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+OWNjYTdiMzUtMWZlMy01MzY3LTk2MjEtMWJjMWRmMzZhZjBkPC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L0NyZWF0ZVRvcGljUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "829fd54bb0f9aabf", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "37" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "85" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:25 GMT" + ], + "X-Amzn-Requestid": [ + "946523c0-0446-596c-b2ca-4334c49326c0" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + } + }, + { + "ID": "d8cea124c70aabe0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "115" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "86" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:25 GMT" + ], + "X-Amzn-Requestid": [ + "0d539afe-dc35-5168-a0c7-fa0a1ce0cec4" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd05hY2stc3ViLTEifX0=" + } + }, + { + "ID": "8f9f0a1c309af744", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "456" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3TmFjay1zdWItMVwiXG5cdFx0fVxuXHRcdF1cblx0XHR9In0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NOU1RvcGljUmF3TmFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:25 GMT" + ], + "X-Amzn-Requestid": [ + "d7e9e83a-4cbd-534b-bc2c-88ce8c680ce7" + ] + }, + "Body": "" + } + }, + { + "ID": "4c173d417754cd5b", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "272" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd05hY2stc3ViLTEmUHJvdG9jb2w9c3FzJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3TmFjay10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "371" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:25 GMT" + ], + "X-Amzn-Requestid": [ + "41e4a891-63df-5904-bdb5-c865a30ac56e" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3TmFjay10b3AtMTplMGIxZmNjYy1lOWQ2LTQ1ZTYtOGMyYy0zYTUyZTAxMzg2ODA8L1N1YnNjcmlwdGlvbkFybj4KICA8L1N1YnNjcmliZVJlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+NDFlNGE4OTEtNjNkZi01OTA0LWJkYjUtYzg2NWEzMGFjNTZlPC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L1N1YnNjcmliZVJlc3BvbnNlPgo=" + } + }, + { + "ID": "30b534bfc75f6f68", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "436" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:25 GMT" + ], + "X-Amzn-Requestid": [ + "fe1daf36-9dff-57ec-aab2-cfc25d2acb86" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjhlMDA1NGJkLWU2YjgtNTQ2YS04M2UwLTM0NDkyNjZkOTgwMDwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmZlMWRhZjM2LTlkZmYtNTdlYy1hYWIyLWNmYzI1ZDJhY2I4NjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "adc4b0b057649e7a", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "436" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MSZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:25 GMT" + ], + "X-Amzn-Requestid": [ + "65c72309-841d-59a5-bfee-43fd44c855cf" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmRjODRhN2U5LTFiZTMtNWVkNC1hNGFhLWM3MWRkYjM2MDJiZTwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjY1YzcyMzA5LTg0MWQtNTlhNS1iZmVlLTQzZmQ0NGM4NTVjZjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "9182fbc4befd920a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "845" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:25 GMT" + ], + "X-Amzn-Requestid": [ + "393adb10-512e-5f12-8c97-bbe491fb00be" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY0NTk2NiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjQ1ODY0In0sIkJvZHkiOiIwIiwiTUQ1T2ZCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiOWFhNDY4N2M4Yjc1NjdiYWEzODBkOWYzMDBmZTI4M2EiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIwIn19LCJNZXNzYWdlSWQiOiJlYzVhNTAxMi0xOGQzLTQyYWQtYjRmYi0yMTQwN2Y3ZTRlMWYiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQktwRVJnTkltNmxUNE4wOU1jZzZKeERkRjRNbUIyWEg0LzZLWXFsOEZjT2VRMjFrUkhFMFdYa0Fvbjg4eDRmTkxqMllYdFQ3cFU5a3JwbGJTYmVqdnozK0FneTc5MlpxMUNoTC82czRpN0c0bmZvZCtPWm1QcEIzSkJkdTRYRTNCYjd0SHZKKzdhemRJT1BmWnBIWWY3SWJVYmxnM1pqbGtJaDk0NHVtOWhncG5CdFhGT0ZiOWFhMmJhVDRvMmZMcDZncmtLdU5MV2V5WTRVTU5ha21OaWpRT3k4cnhybjl4dG1mSzEvYmlNNWpTZ0M2YzRFblhQWTI2bGhDSDlMdW1KOWdDL083cW9CSHpCSEUrY1VldjdTQzlQMUQrTFlUR3NweFZsQml2NU00ZGNFd1lZbFY2dXg1Ui9URk5tQ0tJdU5MWDFrY2h6cy93alRMVTR0WUNsN0hWOGhGRU9CNE1ndmZ4VHlXOVE1alB3MW54ZW00YmcrY3RlVThwaDNTMGZOSXdvcHoxNlY4citIZVJzV256emc9PSJ9XX0=" + } + }, + { + "ID": "136d07a16fc85202", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "845" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:26 GMT" + ], + "X-Amzn-Requestid": [ + "8088d0f8-edae-55eb-a03f-b00c2d78ea47" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY0NjAyOCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjQ1OTI2In0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiMzE0Yzc3YjI0OTg5M2M2YjNjNzY1YTQyY2MwOGIyNDUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIxIn19LCJNZXNzYWdlSWQiOiJkZDQwY2Q2OS04MGYyLTQ5NDgtODcyNi04NWJhYmQzZTkwNTUiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlpwMEhMSGpxeThWRFhIeWZ1VkJzRmdHL0YrTjlra1QvcVRkMXJBTVhQbHh5aVRXOTM4U242eFRzakg0a2J1LzdTeGVHMTJDTmtVc2xTdTBwVHNuUlYrOVQxMW9hS2Qrb0owUSttb0syRU1BTDJzZjREV0lmUThYWWI1cVgvempYSmVBUnVMZzNDZnlCUVNtMFgrZ2h6d2wwL1lOakRzK01MTi9odHJjK3FyZGxlcStTRTNQVUpKNHJNTEY5MFFYQ1MyS0R0eEdlQkZyUlZpZnpkZ0NBSHdRZk9ROE0ya3MrbTVtWlFqdVJuNDdIQmtEb1NVRHZ0bzVMNnRlZzVLZkxYZUdkSWJoYVY4d3haZElmbW1JeEYyWjNyOTZZMlN3TStxaGlLV1JKS0p6enZxSlNvVURmcWJ1ZmRrb2tLUks1UVAwVmZRMVhrMXdkL083MHl4SmF0UkYrQ0ZkNm5XVTVxWUpCbzJsYjlITFBCajZiT2J3TUdzMVQwVVRnMlo3azUxVGh5bWFld29ZbWo5UGJpbE4rdnc9PSJ9XX0=" + } + }, + { + "ID": "318ed8be5a41ce13", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:26 GMT" + ], + "X-Amzn-Requestid": [ + "b5f22480-639a-5ef8-b35c-4474a34c9154" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "ccd0cc4935423ecf", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "561" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ChangeMessageVisibilityBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQktwRVJnTkltNmxUNE4wOU1jZzZKeERkRjRNbUIyWEg0LzZLWXFsOEZjT2VRMjFrUkhFMFdYa0Fvbjg4eDRmTkxqMllYdFQ3cFU5a3JwbGJTYmVqdnozK0FneTc5MlpxMUNoTC82czRpN0c0bmZvZCtPWm1QcEIzSkJkdTRYRTNCYjd0SHZKKzdhemRJT1BmWnBIWWY3SWJVYmxnM1pqbGtJaDk0NHVtOWhncG5CdFhGT0ZiOWFhMmJhVDRvMmZMcDZncmtLdU5MV2V5WTRVTU5ha21OaWpRT3k4cnhybjl4dG1mSzEvYmlNNWpTZ0M2YzRFblhQWTI2bGhDSDlMdW1KOWdDL083cW9CSHpCSEUrY1VldjdTQzlQMUQrTFlUR3NweFZsQml2NU00ZGNFd1lZbFY2dXg1Ui9URk5tQ0tJdU5MWDFrY2h6cy93alRMVTR0WUNsN0hWOGhGRU9CNE1ndmZ4VHlXOVE1alB3MW54ZW00YmcrY3RlVThwaDNTMGZOSXdvcHoxNlY4citIZVJzV256emc9PSIsIlZpc2liaWxpdHlUaW1lb3V0IjoxfV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NOU1RvcGljUmF3TmFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:26 GMT" + ], + "X-Amzn-Requestid": [ + "0356f963-dfcd-5a3f-a6a7-99971f1b4593" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "c9411c2ebc73e804", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "561" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ChangeMessageVisibilityBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlpwMEhMSGpxeThWRFhIeWZ1VkJzRmdHL0YrTjlra1QvcVRkMXJBTVhQbHh5aVRXOTM4U242eFRzakg0a2J1LzdTeGVHMTJDTmtVc2xTdTBwVHNuUlYrOVQxMW9hS2Qrb0owUSttb0syRU1BTDJzZjREV0lmUThYWWI1cVgvempYSmVBUnVMZzNDZnlCUVNtMFgrZ2h6d2wwL1lOakRzK01MTi9odHJjK3FyZGxlcStTRTNQVUpKNHJNTEY5MFFYQ1MyS0R0eEdlQkZyUlZpZnpkZ0NBSHdRZk9ROE0ya3MrbTVtWlFqdVJuNDdIQmtEb1NVRHZ0bzVMNnRlZzVLZkxYZUdkSWJoYVY4d3haZElmbW1JeEYyWjNyOTZZMlN3TStxaGlLV1JKS0p6enZxSlNvVURmcWJ1ZmRrb2tLUks1UVAwVmZRMVhrMXdkL083MHl4SmF0UkYrQ0ZkNm5XVTVxWUpCbzJsYjlITFBCajZiT2J3TUdzMVQwVVRnMlo3azUxVGh5bWFld29ZbWo5UGJpbE4rdnc9PSIsIlZpc2liaWxpdHlUaW1lb3V0IjoxfV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NOU1RvcGljUmF3TmFjay1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:26 GMT" + ], + "X-Amzn-Requestid": [ + "69edba09-577a-574c-9a8b-dafd97ace8e0" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "cad6f15fe2f13c80", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:26 GMT" + ], + "X-Amzn-Requestid": [ + "ca01f5ea-9de2-5557-86fd-951e5d34fafb" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "7c0d94d73f9523e1", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:26 GMT" + ], + "X-Amzn-Requestid": [ + "7d13559b-9b62-5975-a89b-356f5bb416d9" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "d614f4d21c732f1b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:27 GMT" + ], + "X-Amzn-Requestid": [ + "ffc2ff10-a1e6-5f50-8b35-9fe46131c0fc" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "08a939db81447831", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:27 GMT" + ], + "X-Amzn-Requestid": [ + "bfa2302f-a669-563f-b4e9-50db66be6993" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "6ce2a6f760902fd1", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "845" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:27 GMT" + ], + "X-Amzn-Requestid": [ + "4069eeec-e5bc-51a1-8d21-8e18256bae0d" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY0NTk2NiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMiIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjQ1ODY0In0sIkJvZHkiOiIwIiwiTUQ1T2ZCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiOWFhNDY4N2M4Yjc1NjdiYWEzODBkOWYzMDBmZTI4M2EiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIwIn19LCJNZXNzYWdlSWQiOiJlYzVhNTAxMi0xOGQzLTQyYWQtYjRmYi0yMTQwN2Y3ZTRlMWYiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnk4Z1crdzZXeTRJUGdGL0xia0JxcXJLaW1IOUZrZjlXSnVvd3kxcmZQWi9TM08zMnh0dkNyM2xjRGQ2MnZVeFRkcytXdiswZDRSNU5tUVVmemw0WU83UHlzSHo4MitnSlBrN0NVUWNSdy9mWUs4cFoyY1RNZFE0QVMyVzR4ZVlISFNWVFZ6UXFJd1BXdVR1Qm1udGs4WlplQXU4SFZwcFhWbTc2dElFVFB0SEZCSFhsSVFvYjcvaWpaVkZyempUdW5UeVJRam9DWjJyOC9sVXhPL3dhVGxkRllWMWgydVNNVXZqMmFaUFZhRVlXaFVNUHRUZkoyQ2VSc3ZRcTJHR1pMSXNtYmtmUmtCQVlYREFoRlErYUJYaHoxNmxFOHZZSkF1MjEwb21JWUFwYnlPNmVrMnZIYmk2am81SWQxeTE4WVl6RUN5eHJsaXhNdmJybGtyR1NaMjN4Vk9Tbit6aitZR2pBRFgrbWJlWmd6Z1ZmYWhBc282OWpudkdJZDRSSXppZm45VDFRU21WcTdoTlcwczMzemc9PSJ9XX0=" + } + }, + { + "ID": "62ad8a137731ba06", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:27 GMT" + ], + "X-Amzn-Requestid": [ + "49faae3d-0189-5018-9fd6-cec9c15e0fb4" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "9cfe0062ecfa2197", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "539" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnk4Z1crdzZXeTRJUGdGL0xia0JxcXJLaW1IOUZrZjlXSnVvd3kxcmZQWi9TM08zMnh0dkNyM2xjRGQ2MnZVeFRkcytXdiswZDRSNU5tUVVmemw0WU83UHlzSHo4MitnSlBrN0NVUWNSdy9mWUs4cFoyY1RNZFE0QVMyVzR4ZVlISFNWVFZ6UXFJd1BXdVR1Qm1udGs4WlplQXU4SFZwcFhWbTc2dElFVFB0SEZCSFhsSVFvYjcvaWpaVkZyempUdW5UeVJRam9DWjJyOC9sVXhPL3dhVGxkRllWMWgydVNNVXZqMmFaUFZhRVlXaFVNUHRUZkoyQ2VSc3ZRcTJHR1pMSXNtYmtmUmtCQVlYREFoRlErYUJYaHoxNmxFOHZZSkF1MjEwb21JWUFwYnlPNmVrMnZIYmk2am81SWQxeTE4WVl6RUN5eHJsaXhNdmJybGtyR1NaMjN4Vk9Tbit6aitZR2pBRFgrbWJlWmd6Z1ZmYWhBc282OWpudkdJZDRSSXppZm45VDFRU21WcTdoTlcwczMzemc9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNSYXdOYWNrLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:27 GMT" + ], + "X-Amzn-Requestid": [ + "764f8479-05e7-51a3-947b-e48dc530e530" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "e3603d84091db218", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:28 GMT" + ], + "X-Amzn-Requestid": [ + "d0f552cb-b8f1-5dcf-bf6b-323f78290263" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "e49d8200728deda0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:28 GMT" + ], + "X-Amzn-Requestid": [ + "bc0d7145-6a86-594d-8a63-11b1aa5ea6e1" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "4a22989f7d7f4709", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:29 GMT" + ], + "X-Amzn-Requestid": [ + "f1f94e45-4ca4-5cea-8111-2eb18c7d7346" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2dfb25e325bcc658", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:29 GMT" + ], + "X-Amzn-Requestid": [ + "2ae5ec44-fc2e-5801-8843-8cb03cf777ad" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "3d5f14be7c7e11d3", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:29 GMT" + ], + "X-Amzn-Requestid": [ + "3ee299b0-c590-52de-9c57-f94405496d72" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "1b34dcbd7d247921", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "845" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:30 GMT" + ], + "X-Amzn-Requestid": [ + "93abb27c-d831-5583-8545-d28818ebaa2f" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY0NjAyOCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMiIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjQ1OTI2In0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiMzE0Yzc3YjI0OTg5M2M2YjNjNzY1YTQyY2MwOGIyNDUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIxIn19LCJNZXNzYWdlSWQiOiJkZDQwY2Q2OS04MGYyLTQ5NDgtODcyNi04NWJhYmQzZTkwNTUiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlozTWhnbWhIdy9wQTd5eVl1TXM1WmZqVVJPU2hFekp4dnhwU0NaRFlzU1Y2akt4cHFLeHBpODd1U3h2V0ZseGVWTFZnQ0ZCQlFPUUZHMkFNZ1JQdVAyZ2owWWVrcWVlYk1LNnF3L0VaSWhnaUd2UGVaS2tDQnZZbWFZNHg2ZVNqc09tcHVPK0dHWGpXcmZzSDJDQzlGVmhoUGU1b1ozU2RLb1NNalAzS0h6MXE2bEFOZ21sSGxNVC90Z0JXYUVxdWNpaHY1bTFnWXNqN2JaUEUvK3ZCRHVTQTVxT1VZOWtYcHAzRjMvcVVtTWRRczlVdk8vd2xud3RGVFpldW80ckZEVXZ2ZDB2VTVrZ1lnQWkxNmpQVlZ2V1hodmg4dGY0S0hQbWlYMnRhZTFjSmg4SjFZcGhsdmtFcDdaY0xGdUF0b21GSEdydkRubFU1SFVmZEUzS1ZxbFhLaUd3ZFFrdk9HanJZVFZGVkZ3SFBMMGxSWGN1U3dFb3lsaWRqV3NxcTg3REx1Sy9wY01vZGdlYVdoamhGOFE9PSJ9XX0=" + } + }, + { + "ID": "7e9dc2a41571e455", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "539" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlozTWhnbWhIdy9wQTd5eVl1TXM1WmZqVVJPU2hFekp4dnhwU0NaRFlzU1Y2akt4cHFLeHBpODd1U3h2V0ZseGVWTFZnQ0ZCQlFPUUZHMkFNZ1JQdVAyZ2owWWVrcWVlYk1LNnF3L0VaSWhnaUd2UGVaS2tDQnZZbWFZNHg2ZVNqc09tcHVPK0dHWGpXcmZzSDJDQzlGVmhoUGU1b1ozU2RLb1NNalAzS0h6MXE2bEFOZ21sSGxNVC90Z0JXYUVxdWNpaHY1bTFnWXNqN2JaUEUvK3ZCRHVTQTVxT1VZOWtYcHAzRjMvcVVtTWRRczlVdk8vd2xud3RGVFpldW80ckZEVXZ2ZDB2VTVrZ1lnQWkxNmpQVlZ2V1hodmg4dGY0S0hQbWlYMnRhZTFjSmg4SjFZcGhsdmtFcDdaY0xGdUF0b21GSEdydkRubFU1SFVmZEUzS1ZxbFhLaUd3ZFFrdk9HanJZVFZGVkZ3SFBMMGxSWGN1U3dFb3lsaWRqV3NxcTg3REx1Sy9wY01vZGdlYVdoamhGOFE9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNSYXdOYWNrLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:30 GMT" + ], + "X-Amzn-Requestid": [ + "99dc61ff-59c5-59e7-81cd-010b991f064b" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "7022b15f8a341373", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "159" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd05hY2stdG9wLTElM0FlMGIxZmNjYy1lOWQ2LTQ1ZTYtOGMyYy0zYTUyZTAxMzg2ODAmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:30 GMT" + ], + "X-Amzn-Requestid": [ + "5953afc8-81bd-5540-9f0e-cf3c4167692a" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD41OTUzYWZjOC04MWJkLTU1NDAtOWYwZS1jZjNjNDE2NzY5MmE8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "a050b77c85ec16a9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "85" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05hY2stc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:30 GMT" + ], + "X-Amzn-Requestid": [ + "893dc50a-2545-5762-8a66-a5fee59fe8ce" + ] + }, + "Body": "" + } + }, + { + "ID": "94dd468e0266e00b", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "113" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3TmFjay10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:30 GMT" + ], + "X-Amzn-Requestid": [ + "d1d74d9a-cf33-5529-ab3a-2d6e0fe93943" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5kMWQ3NGQ5YS1jZjMzLTU1MjktYWIzYS0yZDZlMGZlOTM5NDM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay new file mode 100644 index 000000000..b20f4e599 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay @@ -0,0 +1,108 @@ +{ + "Initial": "AQAAAA7gDLWoOGrUoQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "68d4e813984e8ff4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "165" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vdXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L25vbmV4aXN0ZW50LXN1YnNjcmlwdGlvbiJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:45 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "f83dbf8e-d53f-5e44-99a7-df7a15d6aff5" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay new file mode 100644 index 000000000..c0b1e3d93 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay @@ -0,0 +1,99 @@ +{ + "Initial": "AQAAAA7gDLWoKe9/lAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "95dfe2a913c80a27", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "195" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9JlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQW5vbmV4aXN0ZW50dG9waWMmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 404, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "259" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:44 GMT" + ], + "X-Amzn-Requestid": [ + "54b4b045-4a31-53ab-af68-d0b18ad98062" + ] + }, + "Body": "PEVycm9yUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxFcnJvcj4KICAgIDxUeXBlPlNlbmRlcjwvVHlwZT4KICAgIDxDb2RlPk5vdEZvdW5kPC9Db2RlPgogICAgPE1lc3NhZ2U+VG9waWMgZG9lcyBub3QgZXhpc3Q8L01lc3NhZ2U+CiAgPC9FcnJvcj4KICA8UmVxdWVzdElkPjU0YjRiMDQ1LTRhMzEtNTNhYi1hZjY4LWQwYjE4YWQ5ODA2MjwvUmVxdWVzdElkPgo8L0Vycm9yUmVzcG9uc2U+Cg==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNonUTF8MessageBody.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNonUTF8MessageBody.replay new file mode 100644 index 000000000..63161e086 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestNonUTF8MessageBody.replay @@ -0,0 +1,655 @@ +{ + "Initial": "AQAAAA7gDLWgClpsjQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "21932777e0c2783f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "78" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdOb25VVEY4TWVzc2FnZUJvZHktdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "342" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:36 GMT" + ], + "X-Amzn-Requestid": [ + "2bd68785-b402-594c-9842-e77174e21100" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3Tm9uVVRGOE1lc3NhZ2VCb2R5LXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4yYmQ2ODc4NS1iNDAyLTU5NGMtOTg0Mi1lNzcxNzRlMjExMDA8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "372d007af8bee5a4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "51" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:36 GMT" + ], + "X-Amzn-Requestid": [ + "0a0cb5e4-ffb1-5209-b140-d5103f518b1f" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + } + }, + { + "ID": "f1de916492c027f1", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "129" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "100" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:36 GMT" + ], + "X-Amzn-Requestid": [ + "753cdaa4-1d6b-59fa-9315-ba50dd8be0ec" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9fQ==" + } + }, + { + "ID": "a7f8bc8b811ab518", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "484" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3Tm9uVVRGOE1lc3NhZ2VCb2R5LXN1Yi0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNSYXdOb25VVEY4TWVzc2FnZUJvZHktc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:36 GMT" + ], + "X-Amzn-Requestid": [ + "b01f13dd-6415-5f9a-a42e-7329a4f5968c" + ] + }, + "Body": "" + } + }, + { + "ID": "049ecae2990e8587", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "300" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd05vblVURjhNZXNzYWdlQm9keS1zdWItMSZQcm90b2NvbD1zcXMmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBU05TVG9waWNSYXdOb25VVEY4TWVzc2FnZUJvZHktdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "385" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:37 GMT" + ], + "X-Amzn-Requestid": [ + "bbd9bfc3-4d64-536f-8207-df378d840b23" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3Tm9uVVRGOE1lc3NhZ2VCb2R5LXRvcC0xOmUzNGQyOWIwLTJjNDMtNDcxYi04NzYyLTRiYmIzYzY3ZDZkZDwvU3Vic2NyaXB0aW9uQXJuPgogIDwvU3Vic2NyaWJlUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5iYmQ5YmZjMy00ZDY0LTUzNmYtODIwNy1kZjM3OGQ4NDBiMjM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvU3Vic2NyaWJlUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "1d480fcc051b2ca8", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "750" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9QUFFQ0F3UUZCZ2NJQ1FvTERBME9EeEFSRWhNVUZSWVhHQmthR3h3ZEhoOGdJU0lqSkNVbUp5Z3BLaXNzTFM0dk9qczhQVDQlMkZRRnRjWFY1ZllIdDhmWDUlMkZabTl2WEdKaGNseGlZWG91TGx4bWIyOWNMaTVjWW1GeVhDNHVYQzR1WEdKaGVpNHVYQzR1TDJadmJ5OHVMaTlpWVhJdkxpNHZMaTR2WW1GNkxpNHZabTl2TDJKaGNpOWlZWHBtYjI4aVltRnlJbUpoZWk0dVhHWnZiMXhjWW1GeVhGeGNZbUY2Wm05dkx5OWlZWEl2THk5aVlYcG1iMjhnWW1GeUlHSmhlakV5TXpRMTRwaTY0cGk2NHBpNnZiSSUzRCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:37 GMT" + ], + "X-Amzn-Requestid": [ + "1d015d8b-c2f7-5d0f-b4c9-3d7f02166543" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmIwNGZiMTk0LWEyMTYtNTczMS1hOWY3LWQxNjA2MmY3OWY3ZDwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjFkMDE1ZDhiLWMyZjctNWQwZi1iNGM5LTNkN2YwMjE2NjU0MzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "25def63902bac84b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "180" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1159" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:37 GMT" + ], + "X-Amzn-Requestid": [ + "b7f2634c-e7e5-5969-a4f4-03b82704d07f" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1NzIwOCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjU3MTg1In0sIkJvZHkiOiJBQUVDQXdRRkJnY0lDUW9MREEwT0R4QVJFaE1VRlJZWEdCa2FHeHdkSGg4Z0lTSWpKQ1VtSnlncEtpc3NMUzR2T2pzOFBUNC9RRnRjWFY1ZllIdDhmWDUvWm05dlhHSmhjbHhpWVhvdUxseG1iMjljTGk1Y1ltRnlYQzR1WEM0dVhHSmhlaTR1WEM0dUwyWnZieTh1TGk5aVlYSXZMaTR2TGk0dlltRjZMaTR2Wm05dkwySmhjaTlpWVhwbWIyOGlZbUZ5SW1KaGVpNHVYR1p2YjF4Y1ltRnlYRnhjWW1GNlptOXZMeTlpWVhJdkx5OWlZWHBtYjI4Z1ltRnlJR0poZWpFeU16UTE0cGk2NHBpNjRwaTZ2Ykk9IiwiTUQ1T2ZCb2R5IjoiMDBhYjg5OTZlODAxMWE3YTE0ZmI2ZmI5YWQ4M2M4MjAiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiZDk2Mjk2YWM2NzdhOWFjYTA1ZDQ5YWUwOTljNjU2YzAiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJiYXNlNjRlbmNvZGVkIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiJ0cnVlIn19LCJNZXNzYWdlSWQiOiI5NGZjODlkYS0zMDUxLTQ0OGQtOTg2Yy1hZWE0MTdkNzAyZTciLCJSZWNlaXB0SGFuZGxlIjoiQVFFQllyYUZCT2tES1JRYTJFT2RROWtDRWRPZ0MzZkJaUDAzV3V4OUgrY3VQVXZib0xOZXZZdDVEaldiTmlQVXNhTFVFVlZ4Q1BFSGpEVkZVVktrVGZPbTcyeFlIc1BRWGdvdFBrbE5lcm9tUzduNnl3SnpvU0JyRktiNGpGK1lPSG9aYkZESWd2dGhDamdTVFhnZ1hscFE2bkM3YVVJQS9HUkxUTFpHaVFkOCtmaHp1QnZCTWh4WXVDRGN6dGQ2K1NVS25UQ0RtQVZ5blBiU1JybGltU0dIUmJZeVlDK2ZRR2tHT1J1ems0Z3I1RjN4SVRLVmlLVHNRQm1zeTl2TDBkM2N4bXhjUktFVjdKWUM4YUFXcjR5US9oZDBsUklCZXZZTmU0YXNVMytkOFFGblZtMklNY1EyYjVzeDdYemFFcXlsUHNSSEhQdE9aT3F1aGIzVVgzdGhvNzlPOSs1NlVZZVhjV29lR0FubUE4UmNnb2JBdlpvc1V2Z2hrVXhxSm1McGQ1NVRsZURrTlVvWUw0TXg1Q2V6MXZ1c3UxVUk4eTRDNnp1eFVLK3hXOVU9In1dfQ==" + } + }, + { + "ID": "7e164be952f6fb2c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "573" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQllyYUZCT2tES1JRYTJFT2RROWtDRWRPZ0MzZkJaUDAzV3V4OUgrY3VQVXZib0xOZXZZdDVEaldiTmlQVXNhTFVFVlZ4Q1BFSGpEVkZVVktrVGZPbTcyeFlIc1BRWGdvdFBrbE5lcm9tUzduNnl3SnpvU0JyRktiNGpGK1lPSG9aYkZESWd2dGhDamdTVFhnZ1hscFE2bkM3YVVJQS9HUkxUTFpHaVFkOCtmaHp1QnZCTWh4WXVDRGN6dGQ2K1NVS25UQ0RtQVZ5blBiU1JybGltU0dIUmJZeVlDK2ZRR2tHT1J1ems0Z3I1RjN4SVRLVmlLVHNRQm1zeTl2TDBkM2N4bXhjUktFVjdKWUM4YUFXcjR5US9oZDBsUklCZXZZTmU0YXNVMytkOFFGblZtMklNY1EyYjVzeDdYemFFcXlsUHNSSEhQdE9aT3F1aGIzVVgzdGhvNzlPOSs1NlVZZVhjV29lR0FubUE4UmNnb2JBdlpvc1V2Z2hrVXhxSm1McGQ1NVRsZURrTlVvWUw0TXg1Q2V6MXZ1c3UxVUk4eTRDNnp1eFVLK3hXOVU9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:37 GMT" + ], + "X-Amzn-Requestid": [ + "db7146e3-a266-5066-b793-26176287c970" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "16f1004e16480fb3", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd05vblVURjhNZXNzYWdlQm9keS10b3AtMSUzQWUzNGQyOWIwLTJjNDMtNDcxYi04NzYyLTRiYmIzYzY3ZDZkZCZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:37 GMT" + ], + "X-Amzn-Requestid": [ + "c11f32d6-6df4-50b0-a470-5222ad1588fc" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5jMTFmMzJkNi02ZGY0LTUwYjAtYTQ3MC01MjIyYWQxNTg4ZmM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "b5fb99b34c9a880d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "99" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd05vblVURjhNZXNzYWdlQm9keS1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:37 GMT" + ], + "X-Amzn-Requestid": [ + "e73f6fde-341e-5048-afd7-0f2af4ff895e" + ] + }, + "Body": "" + } + }, + { + "ID": "7aea64fbbef095dd", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "127" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3Tm9uVVRGOE1lc3NhZ2VCb2R5LXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:37 GMT" + ], + "X-Amzn-Requestid": [ + "4ca6c7f9-40b3-5e97-94cc-a70d8052d6db" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD40Y2E2YzdmOS00MGIzLTVlOTctOTRjYy1hNzBkODA1MmQ2ZGI8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestSendReceive.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestSendReceive.replay new file mode 100644 index 000000000..e2bdfe092 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestSendReceive.replay @@ -0,0 +1,991 @@ +{ + "Initial": "AQAAAA7gDLWSOdcWyAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "d9992f7a1bb6330d", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "71" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdTZW5kUmVjZWl2ZS10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "335" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:23 GMT" + ], + "X-Amzn-Requestid": [ + "bfbaeaf8-b2af-584f-b869-8a0c727c09c9" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3U2VuZFJlY2VpdmUtdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmJmYmFlYWY4LWIyYWYtNTg0Zi1iODY5LThhMGM3MjdjMDljOTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "0e5a6be6c544b967", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "44" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "92" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:23 GMT" + ], + "X-Amzn-Requestid": [ + "d0c41873-b4a5-5b31-bcbc-78877476f881" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + } + }, + { + "ID": "ab2a90c60d698ff9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "122" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "93" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:23 GMT" + ], + "X-Amzn-Requestid": [ + "013672b2-75cd-51af-a38c-1246b51e921f" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn19" + } + }, + { + "ID": "f7c81b36cb7c8bd7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "470" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3U2VuZFJlY2VpdmUtc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:23 GMT" + ], + "X-Amzn-Requestid": [ + "f1d67c28-f7fe-509f-8363-1cdc372df32f" + ] + }, + "Body": "" + } + }, + { + "ID": "78bd85fbf0dca12a", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "286" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "378" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:23 GMT" + ], + "X-Amzn-Requestid": [ + "fc081040-9cf1-5177-85db-70b45c2220f1" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3U2VuZFJlY2VpdmUtdG9wLTE6NTkzNjgwYTAtZWI3MC00NmMxLThhYjctZDdmODUyOWU2ZGVjPC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmZjMDgxMDQwLTljZjEtNTE3Ny04NWRiLTcwYjQ1YzIyMjBmMTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "573f0cb2b00a5a54", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "443" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:23 GMT" + ], + "X-Amzn-Requestid": [ + "d939edda-76a3-5551-b5b7-8d2eb670c4d7" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjAyMzY1M2RhLTIzZGEtNTcxMi1hYzU2LTMzMmVlMzA5NTY5NDwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmQ5MzllZGRhLTc2YTMtNTU1MS1iNWI3LThkMmViNjcwYzRkNzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "a396d45263d4fab2", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "443" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MSZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:24 GMT" + ], + "X-Amzn-Requestid": [ + "05889fab-b508-56c5-81f4-ff5f75dca743" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjU0MmVkNTgwLTg3OTktNTk1NS04Y2RkLWI1NzQ0NzRkYzhkMzwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjA1ODg5ZmFiLWI1MDgtNTZjNS04MWY0LWZmNWY3NWRjYTc0MzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "3e833674dc312bf5", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "443" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MiZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:24 GMT" + ], + "X-Amzn-Requestid": [ + "d11532a7-3b8f-59f1-bbae-5253fb5bc877" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjQzMzYyYTY4LWY3Y2QtNWUwZC1iYzU4LTRhOWMzNzE5ZmY4YjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmQxMTUzMmE3LTNiOGYtNTlmMS1iYmFlLTUyNTNmYjViYzg3NzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "17919dfee46dc8b2", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:24 GMT" + ], + "X-Amzn-Requestid": [ + "aee2fce7-ea4a-5fc2-9656-9c132a9e5c72" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY0NDE3NSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjQ0MDA1In0sIkJvZHkiOiIwIiwiTUQ1T2ZCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiOWFhNDY4N2M4Yjc1NjdiYWEzODBkOWYzMDBmZTI4M2EiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIwIn19LCJNZXNzYWdlSWQiOiI0YmQyNzBkMS05MzM4LTQ2MjctOTgzNS01ZWVmNDU1Yjg4NzciLCJSZWNlaXB0SGFuZGxlIjoiQVFFQm4yaWFERWpzNFN0RmxEU0JRSHRtVlNIT0k4NDhwa0NVMzNPNmdUczJKZ3Mxejc1YzVraFAwd0pZZ3hUdTl5WUt1eGEzSEZNOW9WNUhWZjVUUHNMRGF0a2pYWlNRcm5TZ0FYMm9qeUJYOE5wOHc4cG9oVGpsazV6aTUwZFlNKzNWaXhuQXUvbkFkUWdoMXVqZ0VlQm94c0lrYkZ5R2NkL0F5bnBJRUdPVFQzWHNCUXhxOXJkWEVUcFpYSXlYT3hkakZXQXovTzhIbUdvYUFNUWN6YlEvVHpkb1JpclRrLzlqSDdTM2ttcVFoMUhzY3ZEWXNFWkZtdFdydlJOZW16VE02Ri9BYThIR1VRZzB3STNBVG1yWVM5TzJQWDgySTRVZGFJZThkWWdrc1BOeTM2VjhSeVFVY0ZzZnRMOXIvam1XNGs3Z2w2MFFoMTVSeFY5dlJhc3ZPWlBVRmFPTzJWTENSdHpNU2FQNmEwN0NWRVdHMzIvWng1K1FyNGxqUkYyRzJNRWQ4VGt3elRhM0F4b0VuMjlYKytGY25CYXVXdWxndi9wcXpvaHZqdzA9In1dfQ==" + } + }, + { + "ID": "02b18b7016bc8c28", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "566" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQm4yaWFERWpzNFN0RmxEU0JRSHRtVlNIT0k4NDhwa0NVMzNPNmdUczJKZ3Mxejc1YzVraFAwd0pZZ3hUdTl5WUt1eGEzSEZNOW9WNUhWZjVUUHNMRGF0a2pYWlNRcm5TZ0FYMm9qeUJYOE5wOHc4cG9oVGpsazV6aTUwZFlNKzNWaXhuQXUvbkFkUWdoMXVqZ0VlQm94c0lrYkZ5R2NkL0F5bnBJRUdPVFQzWHNCUXhxOXJkWEVUcFpYSXlYT3hkakZXQXovTzhIbUdvYUFNUWN6YlEvVHpkb1JpclRrLzlqSDdTM2ttcVFoMUhzY3ZEWXNFWkZtdFdydlJOZW16VE02Ri9BYThIR1VRZzB3STNBVG1yWVM5TzJQWDgySTRVZGFJZThkWWdrc1BOeTM2VjhSeVFVY0ZzZnRMOXIvam1XNGs3Z2w2MFFoMTVSeFY5dlJhc3ZPWlBVRmFPTzJWTENSdHpNU2FQNmEwN0NWRVdHMzIvWng1K1FyNGxqUkYyRzJNRWQ4VGt3elRhM0F4b0VuMjlYKytGY25CYXVXdWxndi9wcXpvaHZqdzA9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:24 GMT" + ], + "X-Amzn-Requestid": [ + "430cb116-cab8-5c7f-99bf-d1e20a6c9fcf" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "1bcf7951b50059ed", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:24 GMT" + ], + "X-Amzn-Requestid": [ + "61e55904-6e39-5cd7-9dd9-39f0aeed9f67" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY0NDI5MiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjQ0MTM1In0sIkJvZHkiOiIyIiwiTUQ1T2ZCb2R5IjoiYzgxZTcyOGQ5ZDRjMmY2MzZmMDY3Zjg5Y2MxNDg2MmMiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiYjcyZTE0MGU3MjY5ZWJjZTkxMDdiYWYxZWYyNDBiYWUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIyIn19LCJNZXNzYWdlSWQiOiIyMjAwMjQ3MC00YzIzLTRhODEtOTJhYy0yYzQ5ZjExZDgxZTIiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjNydXZNRnh5RHh5SElYajdWckh0cm5vdXo2Y240azRnamJvS0ZuTDEwTXZyZVJLbWtwYXZRN1hZUC9JMFJvcDEyOHM1SlZiNUZrdW12c2VqOHljSWFaMW1FZ0NaWG9GZWw5VTVBRFlORDZUNHprT3E2YnR1d3JFWVFCUm0rUVJtMURRRnk4aG1yZThIVVRGaUZDUlJHdFRsMlUvUXF2Uk5wRzZwV2RZM2pFY2JydTI1K0gvQzFTWkh4d3Awd0lpMEFMdGlBQ3J6TTBOUnpSN3lmb0szWmxadllJaTNBNjMyb2Z1V3J0aFI3dDV1VTU1V043R1pBWEpnVE5mUXFIRTVIRHJscGhiQVZBWW1lK0FFTlBvT1BvV2Z0Z3NQaFpMc3c5bDBMQ0JmOFRjaW5oUEg3eHplRWV3a1EyRjdoY2RnaU5WQ2dqTEJLMVVXektlOGpQWVRWT3QyNEIrWkdDY3M3cjVHV1VBYUdvZks2T3ZON3BNWXQ3MlErVGFJQnBLQWdVS3lXazA3bU9XOTBqMy9ZWDlTdXZtcHI2VlZTd2I3bVN1b2pDbHBnL0U9In1dfQ==" + } + }, + { + "ID": "79e798c39bf3f520", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:24 GMT" + ], + "X-Amzn-Requestid": [ + "aaa5d2a4-ebb2-5b63-9572-b2502b6698d3" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY0NDM1MSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjQ0MDc1In0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiMzE0Yzc3YjI0OTg5M2M2YjNjNzY1YTQyY2MwOGIyNDUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIxIn19LCJNZXNzYWdlSWQiOiJmODkwZjI2Mi1lOWE1LTQ1OWYtODk0OS04NTcxNDdiYTc0NzkiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmpORkwwNUJiUnZGbXlOUTZXMjJ3azNRMW1DcUkvUlh3c2RlRUp3bTltMVk4ckdzc0JsQld1Yk5ZSDk5QkVkQXM3LzVSVUkzLzdyRkp1ZFRGMHlESGJzQStGd1NxOWYzSjRPQzU1QXRJV3l1Y3RnZmI3dDZ4dGlwMVp0NVFTdWdGKy9RVTZqemRxQ29BWERwZTNoTXZuOTNyUlRsMUJFanAwMGdQSS85RDFYMDJNUGVxREFOek9ZdUQ1RlVrN3pvb2RKRmp1MXJORjRnV283dHp2N3lqcjJDc3VvdzZ2bjVZSThTdGF5ZVJKdnMrbi9rNWhSMUJ6QU5hZGYzQ1UyOHE2ai9LcU50STJrY3pZSTl4OU5KdnZmM0lXVWE1bWR4ekZJMGkwVHdlR3E4Z3NwazBtajcybVhRQ2JkTmh5VzBHU3FjNENzSDEzZjJsL09CRE0vTmFNMi8yZlZpZGkzY1FGWEtGU0c3ZGl2a3lINFo4OE14V3Q4M1dXVnZzL2FVQXE3TUtBb1ZWVG1remVobGVDWitJYzhaNzAwd0RjMXFRMXB1UU1OMGdoRVk9In1dfQ==" + } + }, + { + "ID": "9876a2ca5d20fd6c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "566" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjNydXZNRnh5RHh5SElYajdWckh0cm5vdXo2Y240azRnamJvS0ZuTDEwTXZyZVJLbWtwYXZRN1hZUC9JMFJvcDEyOHM1SlZiNUZrdW12c2VqOHljSWFaMW1FZ0NaWG9GZWw5VTVBRFlORDZUNHprT3E2YnR1d3JFWVFCUm0rUVJtMURRRnk4aG1yZThIVVRGaUZDUlJHdFRsMlUvUXF2Uk5wRzZwV2RZM2pFY2JydTI1K0gvQzFTWkh4d3Awd0lpMEFMdGlBQ3J6TTBOUnpSN3lmb0szWmxadllJaTNBNjMyb2Z1V3J0aFI3dDV1VTU1V043R1pBWEpnVE5mUXFIRTVIRHJscGhiQVZBWW1lK0FFTlBvT1BvV2Z0Z3NQaFpMc3c5bDBMQ0JmOFRjaW5oUEg3eHplRWV3a1EyRjdoY2RnaU5WQ2dqTEJLMVVXektlOGpQWVRWT3QyNEIrWkdDY3M3cjVHV1VBYUdvZks2T3ZON3BNWXQ3MlErVGFJQnBLQWdVS3lXazA3bU9XOTBqMy9ZWDlTdXZtcHI2VlZTd2I3bVN1b2pDbHBnL0U9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:24 GMT" + ], + "X-Amzn-Requestid": [ + "3cb9be40-7db8-58c0-93b1-deb4bd6c31c8" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "07e579f18e5e4067", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "566" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmpORkwwNUJiUnZGbXlOUTZXMjJ3azNRMW1DcUkvUlh3c2RlRUp3bTltMVk4ckdzc0JsQld1Yk5ZSDk5QkVkQXM3LzVSVUkzLzdyRkp1ZFRGMHlESGJzQStGd1NxOWYzSjRPQzU1QXRJV3l1Y3RnZmI3dDZ4dGlwMVp0NVFTdWdGKy9RVTZqemRxQ29BWERwZTNoTXZuOTNyUlRsMUJFanAwMGdQSS85RDFYMDJNUGVxREFOek9ZdUQ1RlVrN3pvb2RKRmp1MXJORjRnV283dHp2N3lqcjJDc3VvdzZ2bjVZSThTdGF5ZVJKdnMrbi9rNWhSMUJ6QU5hZGYzQ1UyOHE2ai9LcU50STJrY3pZSTl4OU5KdnZmM0lXVWE1bWR4ekZJMGkwVHdlR3E4Z3NwazBtajcybVhRQ2JkTmh5VzBHU3FjNENzSDEzZjJsL09CRE0vTmFNMi8yZlZpZGkzY1FGWEtGU0c3ZGl2a3lINFo4OE14V3Q4M1dXVnZzL2FVQXE3TUtBb1ZWVG1remVobGVDWitJYzhaNzAwd0RjMXFRMXB1UU1OMGdoRVk9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:24 GMT" + ], + "X-Amzn-Requestid": [ + "ddb6580f-b4c4-541f-91e9-38fb7410ad17" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "ccb4bb1e45e3f78e", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "166" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXRvcC0xJTNBNTkzNjgwYTAtZWI3MC00NmMxLThhYjctZDdmODUyOWU2ZGVjJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:24 GMT" + ], + "X-Amzn-Requestid": [ + "ab9b3cd6-0041-54ed-b4a5-5c22c095e56b" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5hYjliM2NkNi0wMDQxLTU0ZWQtYjRhNS01YzIyYzA5NWU1NmI8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "9af71dd403b3ff65", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "92" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:24 GMT" + ], + "X-Amzn-Requestid": [ + "288966a9-862b-5e3d-888f-065d46ff7973" + ] + }, + "Body": "" + } + }, + { + "ID": "0835d34315b507e9", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "120" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3U2VuZFJlY2VpdmUtdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:24 GMT" + ], + "X-Amzn-Requestid": [ + "8caa00a8-f25f-5163-8f89-605c328bc0e5" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD44Y2FhMDBhOC1mMjVmLTUxNjMtOGY4OS02MDVjMzI4YmMwZTU8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestSendReceiveJSON.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestSendReceiveJSON.replay new file mode 100644 index 000000000..c2cc471fa --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestSendReceiveJSON.replay @@ -0,0 +1,655 @@ +{ + "Initial": "AQAAAA7gDLWkHAyfaQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b02d93e10c873486", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "75" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdTZW5kUmVjZWl2ZUpTT04tdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "339" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:40 GMT" + ], + "X-Amzn-Requestid": [ + "fdabc7f0-f65d-56e2-a80b-a70436b9472f" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3U2VuZFJlY2VpdmVKU09OLXRvcC0xPC9Ub3BpY0Fybj4KICA8L0NyZWF0ZVRvcGljUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5mZGFiYzdmMC1mNjVkLTU2ZTItYTgwYi1hNzA0MzZiOTQ3MmY8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvQ3JlYXRlVG9waWNSZXNwb25zZT4K" + } + }, + { + "ID": "13774f5d14d7fc33", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "48" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:41 GMT" + ], + "X-Amzn-Requestid": [ + "235075d8-1431-559d-9666-152cd4d53997" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + } + }, + { + "ID": "4ebf8c9cd9321a7b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "126" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "97" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:41 GMT" + ], + "X-Amzn-Requestid": [ + "6492151a-509a-525d-876d-75ee907fae57" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9fQ==" + } + }, + { + "ID": "96da12f51c73f006", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "478" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3U2VuZFJlY2VpdmVKU09OLXN1Yi0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU05TVG9waWNSYXdTZW5kUmVjZWl2ZUpTT04tc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:41 GMT" + ], + "X-Amzn-Requestid": [ + "305790de-bc47-59b4-bb20-f02a7ca2b5be" + ] + }, + "Body": "" + } + }, + { + "ID": "858ffac71f507bbe", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "294" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlSlNPTi1zdWItMSZQcm90b2NvbD1zcXMmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBU05TVG9waWNSYXdTZW5kUmVjZWl2ZUpTT04tdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "382" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:41 GMT" + ], + "X-Amzn-Requestid": [ + "202f7f9d-47d9-5bc9-9c03-1f69873c7a04" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3U2VuZFJlY2VpdmVKU09OLXRvcC0xOjNkMmIxMDA2LWVmN2EtNGNkMC1hZTM4LWIzNTJmN2E2Y2YxNTwvU3Vic2NyaXB0aW9uQXJuPgogIDwvU3Vic2NyaWJlUmVzdWx0PgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4yMDJmN2Y5ZC00N2Q5LTViYzktOWMwMy0xZjY5ODczYzdhMDQ8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvU3Vic2NyaWJlUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "5138ab8495771f70", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "239" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9JTdCJTIyRm9vJTIyJTNBKyUyMkJhciUyMiU3RCZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlSlNPTi10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:41 GMT" + ], + "X-Amzn-Requestid": [ + "6a91dbca-b0d1-533b-98e8-bb3e7034a2f6" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjZjNzI0ZTJkLTQ5ZGMtNTg1NC1iOTUxLTJlZDk4OTM5ZDk5OTwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjZhOTFkYmNhLWIwZDEtNTMzYi05OGU4LWJiM2U3MDM0YTJmNjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "d1898dde82f17f8d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "177" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "756" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:41 GMT" + ], + "X-Amzn-Requestid": [ + "71755212-182d-5826-a6ba-32e6d8c8542c" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY2MTQ4NCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjYxNDQ2In0sIkJvZHkiOiJ7XCJGb29cIjogXCJCYXJcIn0iLCJNRDVPZkJvZHkiOiIzMzMzOTliYTJiNzZhMTk2NDMyNjA3ZjIzYjNlY2I5NSIsIk1lc3NhZ2VJZCI6Ijk0ZmM1NzcxLTM1MmYtNDZkMC04OGMyLTczZjljMDQwOGFiNSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCZjhkQWUzS0hBN2VjT3FoR3VaUTh5RmF5L0xBTGVOUURiWjM5ZU5Ec1JtSkhTYTBXWFB0c3J3WVBlWjhIZmI5UGhWTjQ1eEQydWd5SFpmOURDam8xWUdDYjhMRjRrZUdlalEvcXhtQnZqYkt5Ymxjc1cxaldHeERFVCtuSmc4c1hheFpIemplalNhMFJSWDFjTzVCY0dDbTNGMzBab1lPVXJBUTd0TVpzcUNwT3l4elVYV1JRMms2dnA2V3dPVWRydzkxRit6VDhRZ1lXSmx5VUlDNmw3RG85T2huSnlQVzV1eGtoK2tTcE9YS25CMnNzZWJMRWN4elZrOU1wZmhGQ016S2M3aEdRTm02TytyZ1AvRGYyYmR1OHZ2Yy9zUmpicklBU2x4cFNhb0NlMEpyOFRVeHVWMXdxTUhlRjlFYzl4R25rNWNpb1RKYjZUK1d1YmR1SEdkOVc0ZldSZTV4MWlMUFhwR0ZnREh1U2pTcmw1cTMxRjdzU3NaeUtGTkRTNVllN1JRTldRRjQzbHRyMzdpL0FyUWZXbUU0VFlzUFFXVGhnSEd4dmlvRT0ifV19" + } + }, + { + "ID": "312c2ea03cf42bec", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "570" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmY4ZEFlM0tIQTdlY09xaEd1WlE4eUZheS9MQUxlTlFEYlozOWVORHNSbUpIU2EwV1hQdHNyd1lQZVo4SGZiOVBoVk40NXhEMnVneUhaZjlEQ2pvMVlHQ2I4TEY0a2VHZWpRL3F4bUJ2amJLeWJsY3NXMWpXR3hERVQrbkpnOHNYYXhaSHpqZWpTYTBSUlgxY081QmNHQ20zRjMwWm9ZT1VyQVE3dE1ac3FDcE95eHpVWFdSUTJrNnZwNld3T1Vkcnc5MUYrelQ4UWdZV0pseVVJQzZsN0RvOU9obkp5UFc1dXhraCtrU3BPWEtuQjJzc2ViTEVjeHpWazlNcGZoRkNNektjN2hHUU5tNk8rcmdQL0RmMmJkdTh2dmMvc1JqYnJJQVNseHBTYW9DZTBKcjhUVXh1VjF3cU1IZUY5RWM5eEduazVjaW9USmI2VCtXdWJkdUhHZDlXNGZXUmU1eDFpTFBYcEdGZ0RIdVNqU3JsNXEzMUY3c1NzWnlLRk5EUzVZZTdSUU5XUUY0M2x0cjM3aS9BclFmV21FNFRZc1BRV1RoZ0hHeHZpb0U9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:41 GMT" + ], + "X-Amzn-Requestid": [ + "11528d99-7eb9-5594-81e5-ed6dbe5c699e" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "1b4ee8e2cd6605a7", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlSlNPTi10b3AtMSUzQTNkMmIxMDA2LWVmN2EtNGNkMC1hZTM4LWIzNTJmN2E2Y2YxNSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:41 GMT" + ], + "X-Amzn-Requestid": [ + "20aecfa1-221e-582c-8568-af55e2fbe9e1" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4yMGFlY2ZhMS0yMjFlLTU4MmMtODU2OC1hZjU1ZTJmYmU5ZTE8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "fa0edebcff995eb0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "96" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlSlNPTi1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:41 GMT" + ], + "X-Amzn-Requestid": [ + "78df3848-fcc9-55ec-b609-58bc3c2c59e6" + ] + }, + "Body": "" + } + }, + { + "ID": "79b3f8645ded060c", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "124" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3U2VuZFJlY2VpdmVKU09OLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:41 GMT" + ], + "X-Amzn-Requestid": [ + "5ab9d02e-8fa8-5dc7-abaa-b0da4f4d7c0a" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD41YWI5ZDAyZS04ZmE4LTVkYzctYWJhYS1iMGRhNGY0ZDdjMGE8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestSendReceiveTwo.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestSendReceiveTwo.replay new file mode 100644 index 000000000..ce18c1d44 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSNSTopicRaw/TestSendReceiveTwo.replay @@ -0,0 +1,1675 @@ +{ + "Initial": "AQAAAA7gDLWhJycArgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "0ef9bf753921c1b0", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "74" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJk5hbWU9U05TVG9waWNSYXdTZW5kUmVjZWl2ZVR3by10b3AtMSZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "338" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:37 GMT" + ], + "X-Amzn-Requestid": [ + "b6233ef6-c184-56f4-baa2-5e0201655c99" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3U2VuZFJlY2VpdmVUd28tdG9wLTE8L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmI2MjMzZWY2LWMxODQtNTZmNC1iYWEyLTVlMDIwMTY1NWM5OTwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "ba478ac047d9f5a6", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "47" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "95" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:38 GMT" + ], + "X-Amzn-Requestid": [ + "3d55e9e6-1ad2-5291-bdca-8912da30d680" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + } + }, + { + "ID": "80a4cf9c775a13ae", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "125" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:38 GMT" + ], + "X-Amzn-Requestid": [ + "6507e6fc-a3e7-5e88-965e-860863055a99" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn19" + } + }, + { + "ID": "039d036295c8255e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "476" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3U2VuZFJlY2VpdmVUd28tc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:38 GMT" + ], + "X-Amzn-Requestid": [ + "7394c443-ec92-5527-b6ba-a4b72c70a136" + ] + }, + "Body": "" + } + }, + { + "ID": "1ecd8f09b40dd18c", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "292" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "381" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:38 GMT" + ], + "X-Amzn-Requestid": [ + "142d3963-6911-5800-96a5-5997a9f3226d" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3U2VuZFJlY2VpdmVUd28tdG9wLTE6ZGM1NjdlNzMtYWE4Yy00NzNhLWIzMTQtZDhlYjFiNjQzOTU1PC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjE0MmQzOTYzLTY5MTEtNTgwMC05NmE1LTU5OTdhOWYzMjI2ZDwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "5123d1ae4bbdce12", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "47" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "95" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:38 GMT" + ], + "X-Amzn-Requestid": [ + "35d1dd8d-42fd-5e49-b7b3-bd79821fca58" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + } + }, + { + "ID": "d026a138e4238864", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "125" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:38 GMT" + ], + "X-Amzn-Requestid": [ + "68a37339-54da-5dcd-a66a-13cd943839dc" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn19" + } + }, + { + "ID": "631e78d786f30cbf", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "476" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3U2VuZFJlY2VpdmVUd28tc3ViLTJcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:38 GMT" + ], + "X-Amzn-Requestid": [ + "f9c56d81-77a0-587b-a292-0d75b7429c6a" + ] + }, + "Body": "" + } + }, + { + "ID": "935baefc96e20032", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "292" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZBdHRyaWJ1dGVzLmVudHJ5LjEua2V5PVJhd01lc3NhZ2VEZWxpdmVyeSZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXRvcC0xJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "381" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "b41affb0-1c40-5a86-b5ed-9f44dca3c0eb" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNOU1RvcGljUmF3U2VuZFJlY2VpdmVUd28tdG9wLTE6YTQ1NDhhNDQtMTdmNS00Zjk2LWFiMzUtYTE1YWU5YTk0ODQwPC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmI0MWFmZmIwLTFjNDAtNWE4Ni1iNWVkLTlmNDRkY2EzYzBlYjwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "d013c125f598f361", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "446" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "6afeb5f3-143b-5885-aabe-d507d4d862e8" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmM4ZjVhNGM3LTViZTYtNTVhYy1hODU0LWM0MzM5YjA1NmZjMTwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjZhZmViNWYzLTE0M2ItNTg4NS1hYWJlLWQ1MDdkNGQ4NjJlODwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "c833eb0a2d106797", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "446" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MSZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "b3e71c14-1b52-5f50-bc16-7ce0dbb1953d" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPjY0NGIwYTQxLThkOTAtNWI4Ni04NjdjLTZhYjU0ZDczMjFlYjwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPmIzZTcxYzE0LTFiNTItNWY1MC1iYzE2LTdjZTBkYmIxOTUzZDwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "7b2539fce2c33101", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "446" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9MiZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5DTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "87fb7e6a-27e4-508e-ad45-1e9ee7077ae3" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8TWVzc2FnZUlkPmEwYzAwMjY0LTQ5NWEtNWVlZS05MzM1LTYyOTA4OWI5NDQ4MzwvTWVzc2FnZUlkPgogICAgICAgIDxJZD4wPC9JZD4KICAgICAgPC9tZW1iZXI+CiAgICA8L1N1Y2Nlc3NmdWw+CiAgPC9QdWJsaXNoQmF0Y2hSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjg3ZmI3ZTZhLTI3ZTQtNTA4ZS1hZDQ1LTFlOWVlNzA3N2FlMzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9QdWJsaXNoQmF0Y2hSZXNwb25zZT4K" + } + }, + { + "ID": "41e17b848f15aa84", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "176" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "f7f7044b-1b49-5c59-9139-64bfdbaae848" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1OTM3NyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjU5MzQ2In0sIkJvZHkiOiIyIiwiTUQ1T2ZCb2R5IjoiYzgxZTcyOGQ5ZDRjMmY2MzZmMDY3Zjg5Y2MxNDg2MmMiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiYjcyZTE0MGU3MjY5ZWJjZTkxMDdiYWYxZWYyNDBiYWUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIyIn19LCJNZXNzYWdlSWQiOiI1YjAyMDQzNS1hZjE3LTQ2MDEtOWMxOC05NzRkYjljYjVlMGYiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlJSdXJNWmFIaUxNMUdOVGJDZzYrV1dZVnA0d25wYlJiUGVmdDRSbmczcHZzanlYQmFVV0dtUmZRUzBsS1Zwcnk5YUhjbGUvRFRsTDN3NmtEV3pDelpMTVhZVWRYVFBqSzJGS256c2l3cnJONE44N1RwMGtoOWhydGpJMEsxTGVCUFVwc1lGSHhoSzJYQXdaY0xKY3RReXdvMWQ2eGJucHJ1QVc5S1NycXJCbFBWMnJFS3JENjBJL29acmJFU3A1MUJ2ek9VWnEvYVJjc2xINllCcVpjOEhuOC9YUVhtUHV3N01ZLzZBMFVlbUtwUGV5QlJDNk53TnBiRVVTbjNvQStVRnpIZFc4bklKWFBMSUQ0alppSzJQd3hJcnc1djhSOHBKK1JmK2VjVjBLUDVyRnVOWkx4NHBxLzlpdXdRT0t6MzE4N245a2IxLzNSUVpsejFHaFUrUVBHdUhGNGR3ellFMUJIeDEwaUl5NGRWSDBUTEJYUHpYaE9WU2JFMWs4WjJyMzhhbTdJWmRVdU5qTFlvV3B2akoxdXhseWFydytyMEJjYmtnMXNGT2c9In1dfQ==" + } + }, + { + "ID": "d7576dd1518449c8", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "176" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "b4ec3000-a2cb-5e15-9704-50f462285a04" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1OTQzOCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjU5MjIxIn0sIkJvZHkiOiIwIiwiTUQ1T2ZCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiOWFhNDY4N2M4Yjc1NjdiYWEzODBkOWYzMDBmZTI4M2EiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIwIn19LCJNZXNzYWdlSWQiOiI3ZTAwMjA2Yi0wMzJmLTRiMjgtOWUwYS04OTU3ODNkNWZjYTEiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkNISEgvNGFIRSs0Ym1kWFVDTUJtK3hGZFAxMDFnS25GWlZRZWhhZVJRaVhTUWFTWktrRE5VWkU3bzB3bWoreE42OXBQV1pUQTJaSGtHLzJKU1dmemRsWkdqV1B3YzJnamhBYlRzZ3RGTnE1SlBXeXBWbWpLMVlDcTNtRkNkbGs4RmtuMjN1WHR2M252ZHJaN0xLV21pL0xxSTdoakRnY2JXa3c0QmtVZjZQT1IrWDRiTXJQN200dDJtVkJZcWd2NHk3dk5OTEc3akZHRXh1QnZRUnowdUFLUmZzOTJZcUVmWXo1S1k3aVlBQXFVd2M3d3YvWW9WT3JBMHNiSGw0MitjMWNKdVZ6V25EWFJhTzZnT3RaYjJRSTBFS3dDck14N1A4eHdQZjExcEVrK3V3Yk81Q05DcWxtRVdWSG1iNWRHNzdkbUNsc1ErYnM1eVZXV0ZUL0VsYWx6OUFnNFZuUXRyN1Z1R2NVanlTeEV0UUVFMmlITzd0YllZajlDMVI1ZS9UK1MrUitaWUZPS1RPSkpUdkIxSndsWGNmY09NcnVmd0hqUmpNK3Bxd1U9In1dfQ==" + } + }, + { + "ID": "20279980e91d19a9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "569" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlJSdXJNWmFIaUxNMUdOVGJDZzYrV1dZVnA0d25wYlJiUGVmdDRSbmczcHZzanlYQmFVV0dtUmZRUzBsS1Zwcnk5YUhjbGUvRFRsTDN3NmtEV3pDelpMTVhZVWRYVFBqSzJGS256c2l3cnJONE44N1RwMGtoOWhydGpJMEsxTGVCUFVwc1lGSHhoSzJYQXdaY0xKY3RReXdvMWQ2eGJucHJ1QVc5S1NycXJCbFBWMnJFS3JENjBJL29acmJFU3A1MUJ2ek9VWnEvYVJjc2xINllCcVpjOEhuOC9YUVhtUHV3N01ZLzZBMFVlbUtwUGV5QlJDNk53TnBiRVVTbjNvQStVRnpIZFc4bklKWFBMSUQ0alppSzJQd3hJcnc1djhSOHBKK1JmK2VjVjBLUDVyRnVOWkx4NHBxLzlpdXdRT0t6MzE4N245a2IxLzNSUVpsejFHaFUrUVBHdUhGNGR3ellFMUJIeDEwaUl5NGRWSDBUTEJYUHpYaE9WU2JFMWs4WjJyMzhhbTdJWmRVdU5qTFlvV3B2akoxdXhseWFydytyMEJjYmtnMXNGT2c9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "b186670a-a257-51ec-bbdc-07fe62b4d5fd" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "fe302f8f89830c88", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "176" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "9f98daba-f39e-5aa4-a673-ba4e337daeb5" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1OTU1NSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjU5Mjc2In0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiMzE0Yzc3YjI0OTg5M2M2YjNjNzY1YTQyY2MwOGIyNDUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIxIn19LCJNZXNzYWdlSWQiOiI1MmFlN2VjMS02YTBjLTRlYWYtYmRhZi02YmJmOGI2NjllNjEiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjlORzByUUd3OEM2ZnNCdFgzNGkxbW1NWEhmM3NQOW1tdGxldVU3ZTdUM21QS3FXTy9FbWxqVHhWZDM2U1BIN0k5K3RVeWRPREZyY21hRzRIWDcvRG43VkpDbzZramszTWxkNjA0b2JvNXY3b2VpODAvRE5YalhrNDNVVXAvS2RLYjlBZFg1Mzhjd05yQlphU3liYUY3SjRCaG9YSkc0RWtyTEF3TU9yZXFJeWlJY1FkWU80UlFIWkdGV0dEMkNMNmUwMVg2U3A5TUZlZkxFV2wzTWg2dG41ak1hTUtjaEdqWnhZVit5UTZNdFR5bmc4Qnl0M284Z2dRWHdBcGNhbzJML1RyaXlPK0R0NUE2VXMxWTBWTVUyS2NKNDlSRUdGTDNURUFoSy82SXJNTElKRVl2YTZhYkxqamRZZEVGNWFaT0VsQ200MTZQQmpqdFhEdFR4TUhqaVBMZ3JuYys4M0tKUXcxRmFWMXZGQlZuYWl4cHMvOGljWWMwUnJ2NUYrc01FNUtvbHdzM0J5Nmw3Vmp0SXVtYXlkcDBFL09ZYkh3bnF6NUZKTGFnMkE9In1dfQ==" + } + }, + { + "ID": "786d1e564ea0fe2f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "569" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkNISEgvNGFIRSs0Ym1kWFVDTUJtK3hGZFAxMDFnS25GWlZRZWhhZVJRaVhTUWFTWktrRE5VWkU3bzB3bWoreE42OXBQV1pUQTJaSGtHLzJKU1dmemRsWkdqV1B3YzJnamhBYlRzZ3RGTnE1SlBXeXBWbWpLMVlDcTNtRkNkbGs4RmtuMjN1WHR2M252ZHJaN0xLV21pL0xxSTdoakRnY2JXa3c0QmtVZjZQT1IrWDRiTXJQN200dDJtVkJZcWd2NHk3dk5OTEc3akZHRXh1QnZRUnowdUFLUmZzOTJZcUVmWXo1S1k3aVlBQXFVd2M3d3YvWW9WT3JBMHNiSGw0MitjMWNKdVZ6V25EWFJhTzZnT3RaYjJRSTBFS3dDck14N1A4eHdQZjExcEVrK3V3Yk81Q05DcWxtRVdWSG1iNWRHNzdkbUNsc1ErYnM1eVZXV0ZUL0VsYWx6OUFnNFZuUXRyN1Z1R2NVanlTeEV0UUVFMmlITzd0YllZajlDMVI1ZS9UK1MrUitaWUZPS1RPSkpUdkIxSndsWGNmY09NcnVmd0hqUmpNK3Bxd1U9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "3a75a5ce-1689-5f33-b6aa-c53ad66a421e" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "0f73dbef897d2600", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "176" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "b87fdb29-d15f-585f-b66e-bbdd11bcbc4e" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1OTYxNyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjU5MjIyIn0sIkJvZHkiOiIwIiwiTUQ1T2ZCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiOWFhNDY4N2M4Yjc1NjdiYWEzODBkOWYzMDBmZTI4M2EiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIwIn19LCJNZXNzYWdlSWQiOiJhNDhkZTM4Yy1lYTNiLTQzODMtYmFmMC05NTZjNzIzMmM4YmEiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQitvS2RGMGtZN3VPcTd6Q0dhbWQ4N2ZzZUs4Y2dWMjUvRTF4UVJwbTg5aTdYSCsrQ2d6NjkzTFdza3lnM2ttQ2RGWldLZ3lWVFd3ai9CNWhrVU1lSkNYU3RWYzg5RnZwVUlLbGo0WG5HeGFpWHBqbEh0NmJRL2VHZ2M3aHVOZVdWbzNqUHFSQkFoaTBXWjg5a1JYSm5KSHgyalhRZU1TOHNVZksyc2YrYU05NldGUUMyNlpJS0pnQVVRN09GMkNnc1c5VVJqYjVhOUZESHhCd0JxSFM5Q3lrSnZPelV3eVQ5TWgyZ1NFRnluVkt4N05iQS9qY3ZLRllRc2FzdGxFZDBva2JuR0NJQWVmVzZ4cE5jSzlTS1VLRHJpNHFvNUJrTy81a1ZhUnRsSksxNFpoUkorZVdkUXBYcmk2Zy9CcVYwTXpjbkorbUl5RTZPOCsyc1RocVJMczhMTG52RHhjM1hEaEpSV09Meit3N1dzeVB0a0lKNjY3YUhzZktzdkYxbU9FY0xxbXRhRmpSN2xZa2FsSjNYcndMSEdOcmtQcDhiaHpIbkd0WnV3MFE9In1dfQ==" + } + }, + { + "ID": "c89a13964737d4ac", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "569" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQitvS2RGMGtZN3VPcTd6Q0dhbWQ4N2ZzZUs4Y2dWMjUvRTF4UVJwbTg5aTdYSCsrQ2d6NjkzTFdza3lnM2ttQ2RGWldLZ3lWVFd3ai9CNWhrVU1lSkNYU3RWYzg5RnZwVUlLbGo0WG5HeGFpWHBqbEh0NmJRL2VHZ2M3aHVOZVdWbzNqUHFSQkFoaTBXWjg5a1JYSm5KSHgyalhRZU1TOHNVZksyc2YrYU05NldGUUMyNlpJS0pnQVVRN09GMkNnc1c5VVJqYjVhOUZESHhCd0JxSFM5Q3lrSnZPelV3eVQ5TWgyZ1NFRnluVkt4N05iQS9qY3ZLRllRc2FzdGxFZDBva2JuR0NJQWVmVzZ4cE5jSzlTS1VLRHJpNHFvNUJrTy81a1ZhUnRsSksxNFpoUkorZVdkUXBYcmk2Zy9CcVYwTXpjbkorbUl5RTZPOCsyc1RocVJMczhMTG52RHhjM1hEaEpSV09Meit3N1dzeVB0a0lKNjY3YUhzZktzdkYxbU9FY0xxbXRhRmpSN2xZa2FsSjNYcndMSEdOcmtQcDhiaHpIbkd0WnV3MFE9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "54c62a5a-6127-5c46-9e40-4aaea1c42857" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "4cb76e388f3c11a3", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "176" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "89a75da9-ba34-5952-97f6-3d5d7ad78b82" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1OTcwNyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjU5MzQwIn0sIkJvZHkiOiIyIiwiTUQ1T2ZCb2R5IjoiYzgxZTcyOGQ5ZDRjMmY2MzZmMDY3Zjg5Y2MxNDg2MmMiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiYjcyZTE0MGU3MjY5ZWJjZTkxMDdiYWYxZWYyNDBiYWUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIyIn19LCJNZXNzYWdlSWQiOiI4MDEwZGRmMS02ZjhmLTQ4Y2UtODkxOS1hNDIwZmIxNTRlYmMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlRJdmpTWmw0S2cvTWRNbFdjTzlqcCtnYndmM253TzRqOXI5WHBmdzV2VTNKRC9VUXJDZkVpeTR3Zk0vYTNaTzFSdGVKS3I3V2xDc09rYWh2dHFjMXhuWWYwZUZhN2crM3haR2N5WXdMWVh0MFkrbTFkSUxJZDQycTEwYVlsTE0yRVFWMW9DUkJZMlpqVDJKV0ZKbFJ3NE5xMDlPWlQ4clZ1L09yamJuRE44WlZ2eDRVNmpDcllKNEZKOVlXZDZLQ1AxeGF5T1RZN014NzcwYTk4UVVvVHNHaE44WXMwU0UzZkdQcm5PZDZWdDVqcTk1RmlGNitidzR3dlhNcGw4R0YzUWdCVXlkc3dnMm9hYzg3a2JMUmgvQzI3S1loVXdOUTAvU05CcHhlYU04MGh6ampndnppYnArL25yWGRBTk9wTm04SlJqZTJIZzgxclBmSkdTYUxsQjQxckxqS3krWTJOeGZZamRuUHVuYnJIcmwycXEwSGZhTTFHRUVxWWRiWHNaQk1YRlBMdDRPVlFYQ1JSaUsvWXpyN1pVa3BhckFNbDhtZGVldEhLT009In1dfQ==" + } + }, + { + "ID": "76ca24dd1d7543d7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "569" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjlORzByUUd3OEM2ZnNCdFgzNGkxbW1NWEhmM3NQOW1tdGxldVU3ZTdUM21QS3FXTy9FbWxqVHhWZDM2U1BIN0k5K3RVeWRPREZyY21hRzRIWDcvRG43VkpDbzZramszTWxkNjA0b2JvNXY3b2VpODAvRE5YalhrNDNVVXAvS2RLYjlBZFg1Mzhjd05yQlphU3liYUY3SjRCaG9YSkc0RWtyTEF3TU9yZXFJeWlJY1FkWU80UlFIWkdGV0dEMkNMNmUwMVg2U3A5TUZlZkxFV2wzTWg2dG41ak1hTUtjaEdqWnhZVit5UTZNdFR5bmc4Qnl0M284Z2dRWHdBcGNhbzJML1RyaXlPK0R0NUE2VXMxWTBWTVUyS2NKNDlSRUdGTDNURUFoSy82SXJNTElKRVl2YTZhYkxqamRZZEVGNWFaT0VsQ200MTZQQmpqdFhEdFR4TUhqaVBMZ3JuYys4M0tKUXcxRmFWMXZGQlZuYWl4cHMvOGljWWMwUnJ2NUYrc01FNUtvbHdzM0J5Nmw3Vmp0SXVtYXlkcDBFL09ZYkh3bnF6NUZKTGFnMkE9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "4c4df479-835f-56e6-b044-948d43bccbcb" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "31a6f131b7b9aef7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "176" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "4b0973cb-445d-5ad2-9693-133f84be1ec3" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFKUVI2UURHUTdQQVRNU1lFWSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY1OTc5NyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjU5Mjc0In0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiMzE0Yzc3YjI0OTg5M2M2YjNjNzY1YTQyY2MwOGIyNDUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIxIn19LCJNZXNzYWdlSWQiOiI2OTM2MjM1NS0zYjQyLTQ5MmQtOTlkZC0xMDkyNjQyNTk3MmMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmx0WFRPTmRjL2ljV2FCTVJuNWExQU93VUdpVVBrWU4yR09xTUJFRlYveS9wTjFrZkxEdEMvSGc2NDU3ay9JOVZEckJFMW1pd1RBTElCVXFBUU56TStMb25hNGRUSHNhdGNYZTZyZzVoZXhDNFhQd2lmcmRpU1pUaEZPOWFua3dUYTdIZmwvRzdFdnZRelMzSVJPZm4vT2pnYWh4TkxlSlVkTFJBcm5TekhzZlNqSHJaeTZ2TnlIWEZ6RzVIKzBISmppWTZJTk5LZTRCdFZhY1dkaXdja3R5WnIzUmIxaGczSFJFcXozUW03QXFnbDltWEhKWEhBTzhsc0t6clJDT3B5dGsrN2F4YkRobEtSdjQyaEJrWldZYk50OHBlbE1uQ3NGYlRXdEt4dnZ2YXN4VDV3emJ3anJUbG51ZVA1RG00d2lIcEh0R25zQTJkM08zdWo2WVdRYUcrUDgvZGp4Y0I2NnR2RjAvSWVrRVc3Vll2S3VIekE0UXFmK1hmRTlwVU1XNTJIWng5T2JYdUl3S2VBQlRpdUc0VzErL1c1blR2Z2VXV3U5NHZpMjA9In1dfQ==" + } + }, + { + "ID": "4e70467ac5476165", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "569" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlRJdmpTWmw0S2cvTWRNbFdjTzlqcCtnYndmM253TzRqOXI5WHBmdzV2VTNKRC9VUXJDZkVpeTR3Zk0vYTNaTzFSdGVKS3I3V2xDc09rYWh2dHFjMXhuWWYwZUZhN2crM3haR2N5WXdMWVh0MFkrbTFkSUxJZDQycTEwYVlsTE0yRVFWMW9DUkJZMlpqVDJKV0ZKbFJ3NE5xMDlPWlQ4clZ1L09yamJuRE44WlZ2eDRVNmpDcllKNEZKOVlXZDZLQ1AxeGF5T1RZN014NzcwYTk4UVVvVHNHaE44WXMwU0UzZkdQcm5PZDZWdDVqcTk1RmlGNitidzR3dlhNcGw4R0YzUWdCVXlkc3dnMm9hYzg3a2JMUmgvQzI3S1loVXdOUTAvU05CcHhlYU04MGh6ampndnppYnArL25yWGRBTk9wTm04SlJqZTJIZzgxclBmSkdTYUxsQjQxckxqS3krWTJOeGZZamRuUHVuYnJIcmwycXEwSGZhTTFHRUVxWWRiWHNaQk1YRlBMdDRPVlFYQ1JSaUsvWXpyN1pVa3BhckFNbDhtZGVldEhLT009In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "711050db-d401-53a8-9438-302f14e2479b" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "8c4fc2eda6a0ad68", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "569" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmx0WFRPTmRjL2ljV2FCTVJuNWExQU93VUdpVVBrWU4yR09xTUJFRlYveS9wTjFrZkxEdEMvSGc2NDU3ay9JOVZEckJFMW1pd1RBTElCVXFBUU56TStMb25hNGRUSHNhdGNYZTZyZzVoZXhDNFhQd2lmcmRpU1pUaEZPOWFua3dUYTdIZmwvRzdFdnZRelMzSVJPZm4vT2pnYWh4TkxlSlVkTFJBcm5TekhzZlNqSHJaeTZ2TnlIWEZ6RzVIKzBISmppWTZJTk5LZTRCdFZhY1dkaXdja3R5WnIzUmIxaGczSFJFcXozUW03QXFnbDltWEhKWEhBTzhsc0t6clJDT3B5dGsrN2F4YkRobEtSdjQyaEJrWldZYk50OHBlbE1uQ3NGYlRXdEt4dnZ2YXN4VDV3emJ3anJUbG51ZVA1RG00d2lIcEh0R25zQTJkM08zdWo2WVdRYUcrUDgvZGp4Y0I2NnR2RjAvSWVrRVc3Vll2S3VIekE0UXFmK1hmRTlwVU1XNTJIWng5T2JYdUl3S2VBQlRpdUc0VzErL1c1blR2Z2VXV3U5NHZpMjA9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "80648515-084a-5ee6-9707-e5e1c8a97af7" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "8fc67a6dbe3c1094", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "169" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXRvcC0xJTNBYTQ1NDhhNDQtMTdmNS00Zjk2LWFiMzUtYTE1YWU5YTk0ODQwJlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:39 GMT" + ], + "X-Amzn-Requestid": [ + "cf5cb590-56bf-5631-abfb-d564965cac5c" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5jZjVjYjU5MC01NmJmLTU2MzEtYWJmYi1kNTY0OTY1Y2FjNWM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "4d1019bcbe640e11", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:40 GMT" + ], + "X-Amzn-Requestid": [ + "abd4af6a-b953-5e10-b5d0-cf9e79b7ea01" + ] + }, + "Body": "" + } + }, + { + "ID": "911d32cccf99e37d", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "169" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FTTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXRvcC0xJTNBZGM1NjdlNzMtYWE4Yy00NzNhLWIzMTQtZDhlYjFiNjQzOTU1JlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:40 GMT" + ], + "X-Amzn-Requestid": [ + "c0702596-dc75-521d-a7a3-45621c915870" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5jMDcwMjU5Ni1kYzc1LTUyMWQtYTdhMy00NTYyMWM5MTU4NzA8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "8285a2cc7bef3a09", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TTlNUb3BpY1Jhd1NlbmRSZWNlaXZlVHdvLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:40 GMT" + ], + "X-Amzn-Requestid": [ + "6f804374-e18e-5410-bdfd-2380216a7001" + ] + }, + "Body": "" + } + }, + { + "ID": "917661f7744ac927", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVNOU1RvcGljUmF3U2VuZFJlY2VpdmVUd28tdG9wLTEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:40 GMT" + ], + "X-Amzn-Requestid": [ + "fa462dbb-514f-5d85-ae99-4d4f91ab57e8" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5mYTQ2MmRiYi01MTRmLTVkODUtYWU5OS00ZDRmOTFhYjU3ZTg8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestAs/aws_test.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestAs/aws_test.replay new file mode 100644 index 000000000..0045c850d --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestAs/aws_test.replay @@ -0,0 +1,575 @@ +{ + "Initial": "AQAAAA7gDLW5EeORZQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "c4c44249a1bb8f90", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "41" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY0FzX2F3c190ZXN0LXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "89" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:01 GMT" + ], + "X-Amzn-Requestid": [ + "51db419c-326d-593d-87b3-2168f294ba73" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0FzX2F3c190ZXN0LXRvcC0xIn0=" + } + }, + { + "ID": "43792d53b6163fc7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "119" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0FzX2F3c190ZXN0LXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "90" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:01 GMT" + ], + "X-Amzn-Requestid": [ + "e0413e5e-a7c7-5644-bf53-5eaa673e850a" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY0FzX2F3c190ZXN0LXRvcC0xIn19" + } + }, + { + "ID": "138bc4af023edbbb", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "464" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljQXNfYXdzX3Rlc3QtdG9wLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0FzX2F3c190ZXN0LXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:01 GMT" + ], + "X-Amzn-Requestid": [ + "d6c07b56-b4e7-59af-981b-1ba2741e3ae1" + ] + }, + "Body": "" + } + }, + { + "ID": "21fc262a805da5bb", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "130" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6IngifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NRU1RvcGljQXNfYXdzX3Rlc3QtdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "132" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:01 GMT" + ], + "X-Amzn-Requestid": [ + "7b286cec-8481-5f14-8b39-0c1844785c5a" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiOWRkNGU0NjEyNjhjODAzNGY1Yzg1NjRlMTU1YzY3YTYiLCJNZXNzYWdlSWQiOiJiODM2YmFjYi0yMGUzLTQxNmItYTFlYi05MjA2ZTYwM2JiMGYifV19" + } + }, + { + "ID": "31cf5cca89731afd", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0FzX2F3c190ZXN0LXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "739" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:01 GMT" + ], + "X-Amzn-Requestid": [ + "af4e019b-cc41-558f-9f91-616f0cb806c1" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY4MTgzMSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjgxNzI2In0sIkJvZHkiOiJ4IiwiTUQ1T2ZCb2R5IjoiOWRkNGU0NjEyNjhjODAzNGY1Yzg1NjRlMTU1YzY3YTYiLCJNZXNzYWdlSWQiOiJiODM2YmFjYi0yMGUzLTQxNmItYTFlYi05MjA2ZTYwM2JiMGYiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlZYWnQ3WDgwRk5kU1VDYldwZ2hRNTY3eXdCQ0h1ZmVtdWhkR0pqSlBUQThWa2RoMDBzMk5IQUdGd1Y0ZnZ1aC9FU1lQWXBSSWRsUnlYTmRpR3BicGNpcFRJejR4SWRWZm5YUXkyQUlFc0ZUeHl1NHhlTjBmWGpaUWxsMG1nTWhzMGtYZnhGaHFQVEM5MktGVXFSZUovRHpJclVDdFJhTXVoeEd5S2ZGREJkTFdtaDFtbENmamtTdWt0cUxMMWhZaFl3U1pXYlcweklqb3dCL1lJT1k3VEtiODF5Y1VnbzF2WFU3MXV2UjQ0aWZtakppdFlNZ2tnaVNxb1RkbmVWNlNpZ21LRFBOZ0VBa0hUbmVQNVNiNU5VRUQyWGZCNHZpQ0FaT1oxdE12Tk93b2ZwZENBSlU0ak95L2hkNEx5bXRKZmhSblRXOW1TL29MZTRTLzJJMDF0QWRjSmtrOHlaTnh0SXNNYy9vVzI4VGxFbHUrVXNZS3BxaFRMME1lcG1VM1VGNnYxSVNOQjhUU2o3a0d1aW1XckNOTnpNZkZJOFV0M2RuMUtkMk1zMm89In1dfQ==" + } + }, + { + "ID": "d64a9ebb5e56bf0c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "117" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6IiJ9XSwiUXVldWVVcmwiOiJodHRwczovL3VzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9ub25leGlzdGVudC1xdWV1ZSJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:01 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "38626289-b206-594c-b9f0-027d72ff7a02" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + }, + { + "ID": "86ba0a418fa9837f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "563" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlZYWnQ3WDgwRk5kU1VDYldwZ2hRNTY3eXdCQ0h1ZmVtdWhkR0pqSlBUQThWa2RoMDBzMk5IQUdGd1Y0ZnZ1aC9FU1lQWXBSSWRsUnlYTmRpR3BicGNpcFRJejR4SWRWZm5YUXkyQUlFc0ZUeHl1NHhlTjBmWGpaUWxsMG1nTWhzMGtYZnhGaHFQVEM5MktGVXFSZUovRHpJclVDdFJhTXVoeEd5S2ZGREJkTFdtaDFtbENmamtTdWt0cUxMMWhZaFl3U1pXYlcweklqb3dCL1lJT1k3VEtiODF5Y1VnbzF2WFU3MXV2UjQ0aWZtakppdFlNZ2tnaVNxb1RkbmVWNlNpZ21LRFBOZ0VBa0hUbmVQNVNiNU5VRUQyWGZCNHZpQ0FaT1oxdE12Tk93b2ZwZENBSlU0ak95L2hkNEx5bXRKZmhSblRXOW1TL29MZTRTLzJJMDF0QWRjSmtrOHlaTnh0SXNNYy9vVzI4VGxFbHUrVXNZS3BxaFRMME1lcG1VM1VGNnYxSVNOQjhUU2o3a0d1aW1XckNOTnpNZkZJOFV0M2RuMUtkMk1zMm89In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0FzX2F3c190ZXN0LXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:01 GMT" + ], + "X-Amzn-Requestid": [ + "f69da8e0-1465-5830-bba2-c814d49ccb7e" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "f5e3e6c4306b6387", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "165" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vdXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L25vbmV4aXN0ZW50LXN1YnNjcmlwdGlvbiJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:02 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "762ce6f4-c812-5de0-9d3e-860008e85eae" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + }, + { + "ID": "a8790f5ac7d4efbe", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "89" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0FzX2F3c190ZXN0LXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:02 GMT" + ], + "X-Amzn-Requestid": [ + "4668a50f-d783-51c2-a54c-c5fb1779328c" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..8c5bdc99d --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,575 @@ +{ + "Initial": "AQAAAA7gDLW6CGI0rAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "51ae95f213f159cc", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "72" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "120" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:02 GMT" + ], + "X-Amzn-Requestid": [ + "97ab93e9-6836-5ab8-bdae-f31da8cc5134" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC10b3AtMSJ9" + } + }, + { + "ID": "f8d548f46aa3c30a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "150" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "121" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:02 GMT" + ], + "X-Amzn-Requestid": [ + "197c4b14-eb3d-543f-b311-2be02bc7dfb3" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC10b3AtMSJ9fQ==" + } + }, + { + "ID": "5292901295f0405e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "526" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljQXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXRvcC0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU1FTVG9waWNBc192ZXJpZnlfQXNfcmV0dXJuc19mYWxzZV93aGVuX3Bhc3NlZF9uaWwtdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:02 GMT" + ], + "X-Amzn-Requestid": [ + "4aa71914-107a-59cd-becc-79e0d0800241" + ] + }, + "Body": "" + } + }, + { + "ID": "b5772f5ab5451e42", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "161" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6IngifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NRU1RvcGljQXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "132" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:02 GMT" + ], + "X-Amzn-Requestid": [ + "048b4d54-c026-5cae-a605-2da000dc8722" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiOWRkNGU0NjEyNjhjODAzNGY1Yzg1NjRlMTU1YzY3YTYiLCJNZXNzYWdlSWQiOiJiMjQ2NzAyMC03ODU2LTQ5ZTMtYTdlYi05M2FhMWVmNTAyZDYifV19" + } + }, + { + "ID": "6cd07b3590cceeda", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "201" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "783" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:02 GMT" + ], + "X-Amzn-Requestid": [ + "534381c3-8ea6-5680-a3b7-e1374e5ced0c" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY4MjY0MCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjgyNTc0In0sIkJvZHkiOiJ4IiwiTUQ1T2ZCb2R5IjoiOWRkNGU0NjEyNjhjODAzNGY1Yzg1NjRlMTU1YzY3YTYiLCJNZXNzYWdlSWQiOiJiMjQ2NzAyMC03ODU2LTQ5ZTMtYTdlYi05M2FhMWVmNTAyZDYiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmx3MUExRnZmUDNDMFlQb1p5UmxvS2RqSWRENmFlbWRiOG53Y3JqWWsrVEE1QmxsbFNndUlnZWxjRnUvb2xDdWhmMUJuK3RPL2NKSVdPZnBLTDR2S3dBVkRTZkRyRmw1ODNrc1BFUVBaMFlhOGRHUzZRMTJja1NTQndDbDRVdW5CYmlaaU9KOXorZGtLN2ZLdEJTR3pPdjUyT2VhbzJ0MFpwTXNnNVN3bDNxY21ybjVYM1NuMlJtbGZvVTZFNnFpU1VsRnRzbzZNRUZXaVgrbVVHMytKVUtQbjJYWWcwMGcvN0xJcFBXWm95dlRjVXh4NXlxVEp4SDAwWDJ2WkpFamUxT3h1alNwc042bWR2dVUwWFY5U0lxME95OElYLzl6YmwrOEh3aW43Q2RFUzhGbWZiT3ZDQXVVd1dUa1lEa3FyQ2Vlc0dTUWtiblZoU2dIbVluSlc0eS83bzBmc0d2cGhKcG1vSGI0ZTRreWZFOWdzOGJ6cDJ2RG8wR3FJTHpZNGhSWE4vcmdXVzN6S25aalFueUhud0JGTG9hdUtNQ0JabUJMOWI1WnB3WTh0R3BmbHBxekJ5N1dVSjZQd05IeHVlWFJQSG03aGJ0WGtpZTB3UjdxTlBnPT0ifV19" + } + }, + { + "ID": "fbec4e02bfe5afe0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "638" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmx3MUExRnZmUDNDMFlQb1p5UmxvS2RqSWRENmFlbWRiOG53Y3JqWWsrVEE1QmxsbFNndUlnZWxjRnUvb2xDdWhmMUJuK3RPL2NKSVdPZnBLTDR2S3dBVkRTZkRyRmw1ODNrc1BFUVBaMFlhOGRHUzZRMTJja1NTQndDbDRVdW5CYmlaaU9KOXorZGtLN2ZLdEJTR3pPdjUyT2VhbzJ0MFpwTXNnNVN3bDNxY21ybjVYM1NuMlJtbGZvVTZFNnFpU1VsRnRzbzZNRUZXaVgrbVVHMytKVUtQbjJYWWcwMGcvN0xJcFBXWm95dlRjVXh4NXlxVEp4SDAwWDJ2WkpFamUxT3h1alNwc042bWR2dVUwWFY5U0lxME95OElYLzl6YmwrOEh3aW43Q2RFUzhGbWZiT3ZDQXVVd1dUa1lEa3FyQ2Vlc0dTUWtiblZoU2dIbVluSlc0eS83bzBmc0d2cGhKcG1vSGI0ZTRreWZFOWdzOGJ6cDJ2RG8wR3FJTHpZNGhSWE4vcmdXVzN6S25aalFueUhud0JGTG9hdUtNQ0JabUJMOWI1WnB3WTh0R3BmbHBxekJ5N1dVSjZQd05IeHVlWFJQSG03aGJ0WGtpZTB3UjdxTlBnPT0ifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NRU1RvcGljQXNfdmVyaWZ5X0FzX3JldHVybnNfZmFsc2Vfd2hlbl9wYXNzZWRfbmlsLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:02 GMT" + ], + "X-Amzn-Requestid": [ + "646c5608-72c4-592e-b259-36fcb23e22a2" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "1f2ac7f52686da10", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "117" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6IiJ9XSwiUXVldWVVcmwiOiJodHRwczovL3VzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9ub25leGlzdGVudC1xdWV1ZSJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:02 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "3715e0d3-7575-56a7-bbdf-8027b58fad2b" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + }, + { + "ID": "b3a308872fe9ac7a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "165" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vdXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L25vbmV4aXN0ZW50LXN1YnNjcmlwdGlvbiJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:02 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "3d55362f-ba99-5f19-9261-56db7a634495" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + }, + { + "ID": "ed628313d0026bcb", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "120" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0FzX3ZlcmlmeV9Bc19yZXR1cm5zX2ZhbHNlX3doZW5fcGFzc2VkX25pbC10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:02 GMT" + ], + "X-Amzn-Requestid": [ + "22243e55-8e1e-5ad5-b52a-5ea14ee46159" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestBatching.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestBatching.replay new file mode 100644 index 000000000..ba6ca855c --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestBatching.replay @@ -0,0 +1,1207 @@ +{ + "Initial": "AQAAAA7gDLW2FSJAYwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "e257bf78ba9d8156", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "38" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "86" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:58 GMT" + ], + "X-Amzn-Requestid": [ + "9eb9e94c-7f39-5947-93df-89b8bfcf1116" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + } + }, + { + "ID": "a5eef57603ffd5e3", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "116" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "87" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:58 GMT" + ], + "X-Amzn-Requestid": [ + "89cf03bb-6f47-59b9-9290-634fafb111e8" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn19" + } + }, + { + "ID": "549cbc60b51e1565", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "458" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljQmF0Y2hpbmctdG9wLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:58 GMT" + ], + "X-Amzn-Requestid": [ + "3541fe0a-e11c-5661-9cf2-9efe21eade30" + ] + }, + "Body": "" + } + }, + { + "ID": "9177a859296bd6c5", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "332" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn0seyJJZCI6IjEiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn0seyJJZCI6IjIiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn0seyJJZCI6IjMiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn0seyJJZCI6IjQiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn0seyJJZCI6IjUiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "712" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "586e9a8a-26e0-50b2-944a-fa7ee616b8e3" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiNWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMiLCJNZXNzYWdlSWQiOiIyNDk4YzA2NS1hMDhjLTRmYjQtOTJiZS01MzY4YTE1OGNlNDUifSx7IklkIjoiMSIsIk1ENU9mTWVzc2FnZUJvZHkiOiI1ZWI2M2JiYmUwMWVlZWQwOTNjYjIyYmI4ZjVhY2RjMyIsIk1lc3NhZ2VJZCI6ImI2MTAwMWM3LTk0OGQtNDlhNi1hNWY0LTg1NjhkYzFiNzJmZCJ9LHsiSWQiOiIyIiwiTUQ1T2ZNZXNzYWdlQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNmYwYzkwNmItODBlMC00OTdhLThiNmYtYWYyMzMzN2QyMDdiIn0seyJJZCI6IjMiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiNWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMiLCJNZXNzYWdlSWQiOiI3NmY0YzFhNS02MDhlLTRlMjctYjBmMC1hMzZkZjg5MzVjYTYifSx7IklkIjoiNCIsIk1ENU9mTWVzc2FnZUJvZHkiOiI1ZWI2M2JiYmUwMWVlZWQwOTNjYjIyYmI4ZjVhY2RjMyIsIk1lc3NhZ2VJZCI6IjQ4NGZmYTAxLWUwNWQtNDc0MC1iMDQyLTYwMjJlYmU1ZjYxMyJ9LHsiSWQiOiI1IiwiTUQ1T2ZNZXNzYWdlQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiMDVlYWU3OTYtNjgyZC00ZGNhLWJhYTAtNmQ2NGM4NDk0NmMwIn1dfQ==" + } + }, + { + "ID": "be792a92d1c146d4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "332" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn0seyJJZCI6IjEiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn0seyJJZCI6IjIiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn0seyJJZCI6IjMiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn0seyJJZCI6IjQiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn0seyJJZCI6IjUiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "712" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "33bc49f0-c91e-55a0-933f-290409e97df1" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiNWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMiLCJNZXNzYWdlSWQiOiI0MWZiYjcwNC0zM2FlLTQ2YjAtOTY5My1lNTdhYTY5MjNlYTcifSx7IklkIjoiMSIsIk1ENU9mTWVzc2FnZUJvZHkiOiI1ZWI2M2JiYmUwMWVlZWQwOTNjYjIyYmI4ZjVhY2RjMyIsIk1lc3NhZ2VJZCI6IjExNzc4MTIyLTBjM2MtNDNjMC1iZjdhLTcwY2EyY2YyMWY2MCJ9LHsiSWQiOiIyIiwiTUQ1T2ZNZXNzYWdlQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNDRmMDIwNGUtMGY4ZS00MDZiLWEyZTYtNDA4YTY4OGNkMTdiIn0seyJJZCI6IjMiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiNWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMiLCJNZXNzYWdlSWQiOiJmNzA2ZGFkNy05YjA5LTQ5MmQtYjRjYy1kOWI0NzhiNDY5ZjMifSx7IklkIjoiNCIsIk1ENU9mTWVzc2FnZUJvZHkiOiI1ZWI2M2JiYmUwMWVlZWQwOTNjYjIyYmI4ZjVhY2RjMyIsIk1lc3NhZ2VJZCI6ImMxNjdmOGRhLTA2YWQtNDBhOS1iYzdkLWRjZGM0MTFjMmIyZCJ9LHsiSWQiOiI1IiwiTUQ1T2ZNZXNzYWdlQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNmQ3NTkyYmMtZjZjOS00MGFhLWIzOTctZGIzOTZhZGZjM2I0In1dfQ==" + } + }, + { + "ID": "c3492715e00243c1", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "b0e1c592-82ab-546a-ba08-a566425c5c3b" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTEyMyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc5MDU5In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNDRmMDIwNGUtMGY4ZS00MDZiLWEyZTYtNDA4YTY4OGNkMTdiIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJXTWU2c3lJbW1JR1dqRDRBdDkwS2g4dVlvMGVoQmZaK2Z1dlRmRk45b1lhcWlsQUd2NVlMd1FiNmVoZzIvR1lZWTg0ZXNWTDMvaU1sZS9HSHEzdS9rdmU2UGEzbWN4MlB3Z1ZMWFBodUNlS3lxMXRwYlRhREQvSUx5Q0MyT1puV1hWbE40aU4yb1NMSFVlNkNkU3FoQUpqbS8zeUdubmFNc0ZUaU1nNE9ad1lCQzNPQVZ3R3ZnQkVHcWx6UGgzWDk3N0pxL29WcXZXTTBvK3Z4VktQbm9pUlZpUGp6bWt3d0NzQ20xcGV5ZnJWN0wvaWNUaURjYTRxNUxiTU5KTFhJSnVEcnNxT3Q0UFdtcktFcUNiemlUTlFEMFUwdWU2WDY3RGpjUk81YTRnUVF1WDZzWVdneXg4VnNOOTZ6MTZZb1J6TnhWSXZkQmxSRjdRd2NCanJMMVdoZVBFTmdZMUxMWkJTU1NvWS9jMGdQemVmYllDWkphQVVCSUdFRm1Pdnk5RHd0bzA5cDB1dTQ5YWhFbWpiMjhnPT0ifV19" + } + }, + { + "ID": "f08ef4c9c61003c0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "2d49cc07-6732-50e6-9c2c-acf3a7c5b8b7" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTE4MSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc4OTg5In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNmYwYzkwNmItODBlMC00OTdhLThiNmYtYWYyMzMzN2QyMDdiIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJicDc4OTJmdDdsVnNnbERkMG9zM3dYL1RkWG8ycnQwdnltOFc3cHdBYnZMMEMwNW1WUkt6SXBVMWVzK3FDWHdic1F3RjBNQzZtdmYzZG1RSW9KUkptR3RHVW5zL001b3puOGhaRUlqM2pqdDgwVldKa1VVUG9pellwUzk1T0hCQ0NSWTRMeW1Halp2bUJxNWFjVmZ2dHRjQmlCbVVtWVhZcGlLa2tXZXZ5U2pySXNJRVJGTGFONVdQUFNQMmFJM0RVYWNHMFBwT2JnQzA5Q1F6UllxdmduMjlyeVptRVlNYSt6RG92WFNzOE1sSmtFM0NuOTJGcExZYlZOb0FPVXZ4ZUFhM28ybk5uWm1jMUk5K2ZSNHNMSXJNWkZrZmJ1WWtWYjBVYllJWk40dk04OVBMcUJGbWE0Yk05eFdmZkxVT21vSjZyQWIwQTdqc2VOYk5hd2RTei9kUDRxZm1Za3pCSG5hMlhYTWpLelVRaVZYcEJQNmRzWE9nZUxQN2pBZEcyRzM3VEQ2YktFZXROcmlYKzhVOE1RPT0ifV19" + } + }, + { + "ID": "a85178955eabd400", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "f87452a5-ba69-5809-8dd0-32517a9e6058" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTI0MCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc4OTg5In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNDg0ZmZhMDEtZTA1ZC00NzQwLWIwNDItNjAyMmViZTVmNjEzIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJBUEF2aGZXY2R2bWJrUG9oMTlJNHkwTTNTajRUNG56MjUvTGJUU1NXd3dsMXdFbmhmeUdwR05HdmxpQk4vajJnS3NMTUVlQlVIY25GcHpFeDVWejYwOEFuSkpGZjk2SmVMenJFN2g0WXVBUE9pdVBjelR0RVovenRIWTVtNDdEWk0wczh3ZzBuQVdHZTltMWRKaGFnYitMcEk5UC9GRUlDOTY4elY3TFptcXZuNDdNcWpDbHRTSVppMThrSDlBUjBlTDYzV1JoZkJ3VlNXNzYxQzNta2t3U2VOZ3JWcEtMMmh4aTh2aXBTYlloTXdyNGhZVWpvVWs3SlhOSEUzUmRMdGV0UFhwT1FOaGZ6R1BzYTJtZUdlSXBqUmE0OHJzbThpWXp4SWZPNi9rMlVYZjl4NkVjcUJSWEhIWjZYaUN1TFJhMjJ5UmpqQnpzNWdJZk8xWDBrSjNvSDRhWjZJak5Hd0ZhakhNbVl1ck9zTDV5Y0dwUEwxVDVrMUVKNHhOVXAzZU1NQ2FqWFZodHpPWHV5VU1veG93PT0ifV19" + } + }, + { + "ID": "6ed3955ffc5040e4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "3085c037-75ba-585f-a152-a0c3b54da00e" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTI5OSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc4OTk3In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNzZmNGMxYTUtNjA4ZS00ZTI3LWIwZjAtYTM2ZGY4OTM1Y2E2IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUI1UWQ0U3FlZzBQcU4yRjVHZzZWakt3c0pUdS9CdVVHYXJ2NkFnc0Y2NTh5OTVzUHFobkh6amtZTzlIU2JZamFJVmU5d2Jsc2lJNWp5ay96dWYwdWVCaEdiZlRNSE9TMXVjYnZ6QXNxZWVzT1RmWTAxMjRSQ3NNOXFWa2s4WlJkR08vWVVGT3pxVTJyTUJ1aGlqeDRXMU91U1duVDJDaUpxWjF1Y1dwNzRmdmlvRHMrTFBxZHpJN1lMSStNOGZQM1padGJ3alJBVElJRnpPWDE1cEJDZkNiTUNLaGJXZkF3SEhnRzhoWDFHamRsZ1pZWU1Udm5PM1pQSWorZXN0enZveXZqNmYrc05uS3FxVVh0RjU5aXRrRHE5bjFtRHpLSXA5VHE5Q1ZWaGlCMTNoWFJ3Y0hmQTBGazB1VkhJWDMyZG83Nmg1VnYvbFp2TGV2bHdYTFVOdHhzZEdaTFJUNFRVSTZ1eEVHWFNOTWltUE9TTE51TnpYZ0J5b0NiL2tPVXhCR2NlaktndE8xQlpOdytVWFB0L0JBPT0ifV19" + } + }, + { + "ID": "65dc565a6cc7dc04", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "1537ead2-7a09-50ec-8235-8a26bafe08bd" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTM2MSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc4OTk3In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiMDVlYWU3OTYtNjgyZC00ZGNhLWJhYTAtNmQ2NGM4NDk0NmMwIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJWSzNBb2JpRHNYSDBTRE14endHdWJzdHN1RnJvaCt3MC9ZbDBwTUYxVHBRZVR6SG5MeHBIbTlyZGU3UzB4czgyWjhvVTJQcHlqdDVNQnBpMnlKcnNYMy9rME5wajZFQUVkdTdmZCt1Ymp6ZkxHbHZYYjVDQytLWkV4YmExMi93VnZ4dHVuV004WWJSdUkwUTNjODN4OG5oZExJVHdNczR1QkErTGJURUp0UnptVDlZZVA5NUFnOEVVQmljZ2tUQmJVOWhCZnhiaDF6VTU3QzRtZExwajdqb0NrVXZNeXQxK1Q1U1FSQ1M4cXZJemlnOTRJOVpjL01hYllpNGp5WkVOWXpMVFZ0L2xKL0NGK0p5ejdaNXBpcCtoYVNnOG92Q1N3NjZhR0M0Rlp0TElDVVBCRUJPMG54VWY0NmVaWnQ3a2RIaFkwUFlQMGgwYjh3N2JrZm1keXRQRlJvMlRlUHY0T2VmOFRHZm90YnBqUjAxTDZJeHZoUVNJZGlDUGcvV055bERiajlGWmF1UHZqVWdKdkNlb2N3PT0ifV19" + } + }, + { + "ID": "fbdbcc654a2a1824", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "c8553b36-eda1-5dc1-b598-5bc22d56f590" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTQxOSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc4OTg5In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiMjQ5OGMwNjUtYTA4Yy00ZmI0LTkyYmUtNTM2OGExNThjZTQ1IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJyS2tjcUJ1L1BKSkZNTzZheGsxU0xqdHhyc2lvZER3Vk8yNlR0bFhEM2E4cnZjTEpOZmVVcytnbTZLbjVhcFZIUk41VllCbytGaUxrcWxPNHhEL0tteG5pWmtLMFJzM051ZVpPcURyVHNqa21FT0txSExUVnVTSG1ZMC8rV0d6VFgxcU5aU2JhckxaMVByVFIrSmhkUHgvcXQrL0k5OUU0ejcwS3dzY0Z0ZzR4WjFhMEdud1ViYmZnVHRpMWlUMmFsY1VWK0QxeHBxc09XUzQwTXZCODFhbmVWQUJVa2YxcUIxSFdJN0dzMmNWV3JZQXBQZUJ2YW9pU1ROVDVkNlNJVkVPUjByWk5pcHJwcytINUNzTW5aYVE4bGwvNm0ra0FpMlM3M3dTS3lOMlpydUVROTFQektvM1BJRjlHT1dvY25hY0VKSjlYKzRSZTFodEN6QnRUeTNLYUZQZDhleWF4VFpSVERBZkhFWHlacXNjaFhwMFpSY1poTDMyZWErRk1LUklqWEM2a3BoUDVVNVNCNjJxRXFBPT0ifV19" + } + }, + { + "ID": "a5383fd933b94bd7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "1598e31d-e0f5-59ca-9a8a-83e92002619b" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTQ4MCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc4OTk2In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiYjYxMDAxYzctOTQ4ZC00OWE2LWE1ZjQtODU2OGRjMWI3MmZkIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUI1NHU5R1RUTm9meUxqUmVpV0YzZXVneFNaQmZtVTYrSHdxc3RUY01meEMrN1VlOU5sLzFpeHRLZDNaMk5qak9ncEJQY2lIZDFXN1ZaaXJxQk1YaFhOZGxHT211MGVyVzFMSUxMcFFrNlUxNkkvaWVFcTVTN2kvV21xNnI5TFJJMFgxdFFidWNaZzJCclNtckRjdUN4QUIxYmwzclk5bkw5Mm0xeEY1NmZRLzdoVjNOdnB6TVFPYWJSS1p0MmhnMmVBS2R4M2RBUlEwUk0vR3p6N3gxQk5ibUZkK1VNRzIrcHplMWIvQ3Q2SzFvVGY5ZDQrSTMzZjZkRGcyZHV2YW5QSlZCdmxiTWMzSzN4NXp2UGMvWGw5NDNkL2ZIT3dJMWZraTZHWitWaGF0THFjdW9remRmNHU1RTFycDNlOW5aMGcyZ0ltQUpSZG1Ya28rS0hmS3VSdHNuZUVHWG1JcG5OYmdVcjZmNkloRkZVa3FZNjI1bG5YVDhKV1ZUTXFJRFZMZDVTbkgyWGN0Q1pBRWpzMkdWLy9RPT0ifV19" + } + }, + { + "ID": "a6a7bc776bddc1bf", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2750" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQldNZTZzeUltbUlHV2pENEF0OTBLaDh1WW8wZWhCZlorZnV2VGZGTjlvWWFxaWxBR3Y1WUx3UWI2ZWhnMi9HWVlZODRlc1ZMMy9pTWxlL0dIcTN1L2t2ZTZQYTNtY3gyUHdnVkxYUGh1Q2VLeXExdHBiVGFERC9JTHlDQzJPWm5XWFZsTjRpTjJvU0xIVWU2Q2RTcWhBSmptLzN5R25uYU1zRlRpTWc0T1p3WUJDM09BVndHdmdCRUdxbHpQaDNYOTc3SnEvb1ZxdldNMG8rdnhWS1Bub2lSVmlQanpta3d3Q3NDbTFwZXlmclY3TC9pY1RpRGNhNHE1TGJNTkpMWElKdURyc3FPdDRQV21yS0VxQ2J6aVROUUQwVTB1ZTZYNjdEamNSTzVhNGdRUXVYNnNZV2d5eDhWc045NnoxNllvUnpOeFZJdmRCbFJGN1F3Y0JqckwxV2hlUEVOZ1kxTExaQlNTU29ZL2MwZ1B6ZWZiWUNaSmFBVUJJR0VGbU92eTlEd3RvMDlwMHV1NDlhaEVtamIyOGc9PSJ9LHsiSWQiOiIxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJicDc4OTJmdDdsVnNnbERkMG9zM3dYL1RkWG8ycnQwdnltOFc3cHdBYnZMMEMwNW1WUkt6SXBVMWVzK3FDWHdic1F3RjBNQzZtdmYzZG1RSW9KUkptR3RHVW5zL001b3puOGhaRUlqM2pqdDgwVldKa1VVUG9pellwUzk1T0hCQ0NSWTRMeW1Halp2bUJxNWFjVmZ2dHRjQmlCbVVtWVhZcGlLa2tXZXZ5U2pySXNJRVJGTGFONVdQUFNQMmFJM0RVYWNHMFBwT2JnQzA5Q1F6UllxdmduMjlyeVptRVlNYSt6RG92WFNzOE1sSmtFM0NuOTJGcExZYlZOb0FPVXZ4ZUFhM28ybk5uWm1jMUk5K2ZSNHNMSXJNWkZrZmJ1WWtWYjBVYllJWk40dk04OVBMcUJGbWE0Yk05eFdmZkxVT21vSjZyQWIwQTdqc2VOYk5hd2RTei9kUDRxZm1Za3pCSG5hMlhYTWpLelVRaVZYcEJQNmRzWE9nZUxQN2pBZEcyRzM3VEQ2YktFZXROcmlYKzhVOE1RPT0ifSx7IklkIjoiMiIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCQVBBdmhmV2Nkdm1ia1BvaDE5STR5ME0zU2o0VDRuejI1L0xiVFNTV3d3bDF3RW5oZnlHcEdOR3ZsaUJOL2oyZ0tzTE1FZUJVSGNuRnB6RXg1Vno2MDhBbkpKRmY5NkplTHpyRTdoNFl1QVBPaXVQY3pUdEVaL3p0SFk1bTQ3RFpNMHM4d2cwbkFXR2U5bTFkSmhhZ2IrTHBJOVAvRkVJQzk2OHpWN0xabXF2bjQ3TXFqQ2x0U0laaTE4a0g5QVIwZUw2M1dSaGZCd1ZTVzc2MUMzbWtrd1NlTmdyVnBLTDJoeGk4dmlwU2JZaE13cjRoWVVqb1VrN0pYTkhFM1JkTHRldFBYcE9RTmhmekdQc2EybWVHZUlwalJhNDhyc204aVl6eElmTzYvazJVWGY5eDZFY3FCUlhISFo2WGlDdUxSYTIyeVJqakJ6czVnSWZPMVgwa0ozb0g0YVo2SWpOR3dGYWpITW1ZdXJPc0w1eWNHcFBMMVQ1azFFSjR4TlVwM2VNTUNhalhWaHR6T1h1eVVNb3hvdz09In0seyJJZCI6IjMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjVRZDRTcWVnMFBxTjJGNUdnNlZqS3dzSlR1L0J1VUdhcnY2QWdzRjY1OHk5NXNQcWhuSHpqa1lPOUhTYllqYUlWZTl3YmxzaUk1anlrL3p1ZjB1ZUJoR2JmVE1IT1MxdWNidnpBc3FlZXNPVGZZMDEyNFJDc005cVZrazhaUmRHTy9ZVUZPenFVMnJNQnVoaWp4NFcxT3VTV25UMkNpSnFaMXVjV3A3NGZ2aW9EcytMUHFkekk3WUxJK004ZlAzWlp0YndqUkFUSUlGek9YMTVwQkNmQ2JNQ0toYldmQXdISGdHOGhYMUdqZGxnWllZTVR2bk8zWlBJaitlc3R6dm95dmo2ZitzTm5LcXFVWHRGNTlpdGtEcTluMW1EektJcDlUcTlDVlZoaUIxM2hYUndjSGZBMEZrMHVWSElYMzJkbzc2aDVWdi9sWnZMZXZsd1hMVU50eHNkR1pMUlQ0VFVJNnV4RUdYU05NaW1QT1NMTnVOelhnQnlvQ2Iva09VeEJHY2VqS2d0TzFCWk53K1VYUHQvQkE9PSJ9LHsiSWQiOiI0IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJWSzNBb2JpRHNYSDBTRE14endHdWJzdHN1RnJvaCt3MC9ZbDBwTUYxVHBRZVR6SG5MeHBIbTlyZGU3UzB4czgyWjhvVTJQcHlqdDVNQnBpMnlKcnNYMy9rME5wajZFQUVkdTdmZCt1Ymp6ZkxHbHZYYjVDQytLWkV4YmExMi93VnZ4dHVuV004WWJSdUkwUTNjODN4OG5oZExJVHdNczR1QkErTGJURUp0UnptVDlZZVA5NUFnOEVVQmljZ2tUQmJVOWhCZnhiaDF6VTU3QzRtZExwajdqb0NrVXZNeXQxK1Q1U1FSQ1M4cXZJemlnOTRJOVpjL01hYllpNGp5WkVOWXpMVFZ0L2xKL0NGK0p5ejdaNXBpcCtoYVNnOG92Q1N3NjZhR0M0Rlp0TElDVVBCRUJPMG54VWY0NmVaWnQ3a2RIaFkwUFlQMGgwYjh3N2JrZm1keXRQRlJvMlRlUHY0T2VmOFRHZm90YnBqUjAxTDZJeHZoUVNJZGlDUGcvV055bERiajlGWmF1UHZqVWdKdkNlb2N3PT0ifSx7IklkIjoiNSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCcktrY3FCdS9QSkpGTU82YXhrMVNManR4cnNpb2REd1ZPMjZUdGxYRDNhOHJ2Y0xKTmZlVXMrZ202S241YXBWSFJONVZZQm8rRmlMa3FsTzR4RC9LbXhuaVprSzBSczNOdWVaT3FEclRzamttRU9LcUhMVFZ1U0htWTAvK1dHelRYMXFOWlNiYXJMWjFQclRSK0poZFB4L3F0Ky9JOTlFNHo3MEt3c2NGdGc0eFoxYTBHbndVYmJmZ1R0aTFpVDJhbGNVVitEMXhwcXNPV1M0ME12QjgxYW5lVkFCVWtmMXFCMUhXSTdHczJjVldyWUFwUGVCdmFvaVNUTlQ1ZDZTSVZFT1IwclpOaXBycHMrSDVDc01uWmFROGxsLzZtK2tBaTJTNzN3U0t5TjJacnVFUTkxUHpLbzNQSUY5R09Xb2NuYWNFSko5WCs0UmUxaHRDekJ0VHkzS2FGUGQ4ZXlheFRaUlREQWZIRVh5WnFzY2hYcDBaUmNaaEwzMmVhK0ZNS1JJalhDNmtwaFA1VTVTQjYycUVxQT09In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "82" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "6ab41d33-5e65-5734-8a99-7dc79e929f65" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjIifSx7IklkIjoiNCJ9LHsiSWQiOiI1In0seyJJZCI6IjEifSx7IklkIjoiMyJ9LHsiSWQiOiIwIn1dfQ==" + } + }, + { + "ID": "301eb91d3c3f6e08", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "34d2a388-6e85-55f6-8173-c37cae724da7" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTU5NyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc5MDU4In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNDFmYmI3MDQtMzNhZS00NmIwLTk2OTMtZTU3YWE2OTIzZWE3IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUIrU21wb1R6YitqUXJtaUV4L0p3RDhmcUozT0NZbmZwazBPUlhLV3ZIZHAyS3prY01EZlk5WlJOUWVxcjEreEpMeXpJNDUrSnRFaXUyalJ2SnlmVWR6R05BUGwzc291ZWR6eTBQOFphRS9abzNVM1FPUzkwZ0tnWTNsRlhkMis4SG1aTlhkZHBWOEk4aXNKOXJBU3g2OVhGc2RUdHUza3E1cjF1Tk04Z0sxaXFmaE5IU0UwQTdFOFk3MjJ6OU9SSHA3a0FHK1FnVmFSN3Z4NW5rMkhhbUlpemxQczhFMkxGUkgxL2dZRE13dldoTGhraE9YVEw0UHE3SlpVSFhPZ2NONGE1elZabnFscmFndExBeEFKcmcrU0hEQ2FMRnhzN0R4bGRoL3p3bTMwZUFFekhqMVpINHhMOENUYTV4alZidTU1cVVjcG9md3pyNm0ydlA0Uk9kVUNHYlRDVjRQeVo4R2NDeUVsYzJENm5rK0JlQUhNOVNPdU8xOVkzekdBcU1NQXVsTzRjVURjUzdYb0Y1UnM4b013PT0ifV19" + } + }, + { + "ID": "328850292044ced0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "6ce58521-be20-5dc9-bf6d-e5d57ed73598" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTY1NyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc5MDYyIn0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiZjcwNmRhZDctOWIwOS00OTJkLWI0Y2MtZDliNDc4YjQ2OWYzIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUI1bVlUcjR3dE8yNWMvSzU2aXE5ZHZ3WjNRNXBBOE1rWXZuaWpFenhNQ0ZhOTFCdmI5WU9tWSt6MlhQVjNsOGR4R3VLdDFUNEtDdGNYNXFiNTN3aUpobFVDSFR3U3NoK0FDU0dhMmZiZzZiT01rT1oybmU3MkpGWCtNNFEyalRGZEhwZXhrTzZoMzE5Vyt4ZlNmZ1BOelc1NkJ3ZGptSzZOSlBMOXlvMG1Ya3EzZXNFcFhXMFZKSXNBTm5PdkpzeUpSdG5NeUlQNGVkaE5KT0JpM0NDREhVemxMNXZ2d3hjWU12MjdJcEFWcEdsc1orV2x2TEVaM0hFN0lra2piVEl4cGp6TEw4TFFIWE1mR1JwWHVXZmlKVHBGZFhmNTM3akFMM1BtZW9XQXFqd2RXdVJ1QXVveFQzaUk0OHpSN2RJWGFXeTFhZlVOR0lBQytTWC9LUWJjdXVBLzhQcXFSSG9rVTNtbTVHN2QrcnRIOVZpaTVXUlFxQkpHVUJKLzV0S2JGQWNmWVlQWWNuM1JOYkhaSnlTMDF3PT0ifV19" + } + }, + { + "ID": "7f0941cfcc165f2c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "708cf900-43c1-5ad9-b13e-99f48336f288" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTcxOSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc5MDU5In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiMTE3NzgxMjItMGMzYy00M2MwLWJmN2EtNzBjYTJjZjIxZjYwIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJGeVIyYzQ2ck9IYlkwakpxVnNlYldXZTF6aFhlWDc3YURrOEJnWjNLODFmTFluYkxUdXIyVGE2emVNU3JkOWMrdGpMUWZXQWZaU2pwNnNBRDNvYVo3bmUyRWsxZFZGVWJvR3VHZ085Rzd5alp2TmQwd1VtOHlTempUNVJ4KytpWVk2VnUvQ0xMWHR5ZU9qTndXZWF1VFRxb1R1Z2tFWnRSWndadHVXOEtKQmh2VmM0dVhVU2kyYmpWOEQxSTVLSjJFeno4VS9xaUQ5R1ZFZUVlV0gzSnBGNDRxcU10TzArTmNCV21xRmtUY29ZY3RXdHd5a3VueURnZTNoZG5sRlhRVDJFNUVkaWVqM3pzS3hybkFyaWVLYm4wM203R3dwT1BtM0F3ejg4Ukk2VnZWTGc3NjUxQVVKZ1R5Uys0blp4NjV3WmI1ZkdwTktsbXpsRGc0dEtLZWYxRjFpSUtHS0dsTDgzT3VITHdvZVg3S3dwTkwxMm9nZHFNOXdxYmg4YVNrdlFVd3gvNWFEYUp1N2JEYTJ4eFF3PT0ifV19" + } + }, + { + "ID": "77ac219ef16ab5e9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "3a41de9b-3c95-59d7-8787-be6ffc624186" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTc4MCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc5MDU4In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiYzE2N2Y4ZGEtMDZhZC00MGE5LWJjN2QtZGNkYzQxMWMyYjJkIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJuTnZDclU3ZVRKNThNZmZZTWQ5Q3FiRUxCeFpkS1BSWkQwWEJ4WldmUnpRcnNXb0MzMW9NSXVlT0RMa3liVmw3VFdqaFpSMVlkQjRmbW9qeE5qSG5hN0lvc2c0MlkzV0JvVzRoQjBCQXVGVmZBa0RpTHQ1dUJUYkNsOU5nOHNHUkI1TjJyTlk5U3BJTmtJZitkWUZLOHVvRStJaHFtcUcvM00wSGVQM0pTVWlpZFZnamRRVG5qbldnWjJBRTJaZ0kvWmFmSnJ6UDJmWk9RTFpRVWRmK3dVa2pnMjFvQzBvUWcwOXZZNXRna1VHSUNTS1lBKzhqK25YSExIY2ltZm1LMStBZjJyR2x5OGdKY1FobmJwc3E5WnV3b3lVYXk0aVZuSDMyWU5UbkUwNmZUWkhISDJ4ZnFqc1hYVUFoTGJ4R09pZ0N1SHJIK3JFMUFaQWo1Q3FwSUZxd1ljcVl1cURkcmNxS0RnR2ZUT2M2dTQxYmovVmYwKzA3VlM5YTBKSThIZGdMVFlyUHZwbm1rUFVzRWErSzh3PT0ifV19" + } + }, + { + "ID": "edbb81a54417942e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "729" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "9ce1687c-fffd-5d6a-ab1d-08883f0a803c" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3OTg1OCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc5MDU5In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTWVzc2FnZUlkIjoiNmQ3NTkyYmMtZjZjOS00MGFhLWIzOTctZGIzOTZhZGZjM2I0IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUI2eGk2bmNLN1hBZTEyKy9xYmFBUkthY21JSkQzdW15cW5naUViUkM2NWFsM3RsRk5vNEtCVDlGVzV2U2JoN3pSYjhXdEtzblJUdVRQTmUxblFXa3NoclFEZGpDTzI2Z2h3RkhUcXNrNXc1cGorV1dvZzNxTVI1MWdqYUlMek1lVG8wbDk4Q0JGT1BzUkV6cEp4MzVlYmxxd0svSXJMcHhLcEFsR3lUS3NFWTZaRlFTKzEwTVBiaEE2WWM0c1NKbm05dWxseTFBbWc3WEN1RG5rb09HUTZqVHk0VDFabmJmb1dkRUFPbEFoM215VXFNVlVCM0JobUVTbkRGbUdyNWlqamhHNFI4RE95NG11dTJCUS80WTRkTU5TN0UxMm5Qd3ZIc3ErTThqZ0dkb2FZbng3S25yY2tkUzlWR1FTT0cxelo5Y2lQSTVlMkR6MHMvRUkwN2JLcUFNTkhNaURiNlBJQjljMUVnVitzSy9QemhLSWN0ZjNnblUzWDFHMFRYWW5KanlneWVNa2pOSk1BMW00cm04cmpBPT0ifV19" + } + }, + { + "ID": "b41c427c2c3c5065", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2750" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjU0dTlHVFROb2Z5TGpSZWlXRjNldWd4U1pCZm1VNitId3FzdFRjTWZ4Qys3VWU5TmwvMWl4dEtkM1oyTmpqT2dwQlBjaUhkMVc3VlppcnFCTVhoWE5kbEdPbXUwZXJXMUxJTExwUWs2VTE2SS9pZUVxNVM3aS9XbXE2cjlMUkkwWDF0UWJ1Y1pnMkJyU21yRGN1Q3hBQjFibDNyWTluTDkybTF4RjU2ZlEvN2hWM052cHpNUU9hYlJLWnQyaGcyZUFLZHgzZEFSUTBSTS9Heno3eDFCTmJtRmQrVU1HMitwemUxYi9DdDZLMW9UZjlkNCtJMzNmNmREZzJkdXZhblBKVkJ2bGJNYzNLM3g1enZQYy9YbDk0M2QvZkhPd0kxZmtpNkdaK1ZoYXRMcWN1b2t6ZGY0dTVFMXJwM2U5blowZzJnSW1BSlJkbVhrbytLSGZLdVJ0c25lRUdYbUlwbk5iZ1VyNmY2SWhGRlVrcVk2MjVsblhUOEpXVlRNcUlEVkxkNVNuSDJYY3RDWkFFanMyR1YvL1E9PSJ9LHsiSWQiOiIxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUIrU21wb1R6YitqUXJtaUV4L0p3RDhmcUozT0NZbmZwazBPUlhLV3ZIZHAyS3prY01EZlk5WlJOUWVxcjEreEpMeXpJNDUrSnRFaXUyalJ2SnlmVWR6R05BUGwzc291ZWR6eTBQOFphRS9abzNVM1FPUzkwZ0tnWTNsRlhkMis4SG1aTlhkZHBWOEk4aXNKOXJBU3g2OVhGc2RUdHUza3E1cjF1Tk04Z0sxaXFmaE5IU0UwQTdFOFk3MjJ6OU9SSHA3a0FHK1FnVmFSN3Z4NW5rMkhhbUlpemxQczhFMkxGUkgxL2dZRE13dldoTGhraE9YVEw0UHE3SlpVSFhPZ2NONGE1elZabnFscmFndExBeEFKcmcrU0hEQ2FMRnhzN0R4bGRoL3p3bTMwZUFFekhqMVpINHhMOENUYTV4alZidTU1cVVjcG9md3pyNm0ydlA0Uk9kVUNHYlRDVjRQeVo4R2NDeUVsYzJENm5rK0JlQUhNOVNPdU8xOVkzekdBcU1NQXVsTzRjVURjUzdYb0Y1UnM4b013PT0ifSx7IklkIjoiMiIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCNW1ZVHI0d3RPMjVjL0s1NmlxOWR2d1ozUTVwQThNa1l2bmlqRXp4TUNGYTkxQnZiOVlPbVkrejJYUFYzbDhkeEd1S3QxVDRLQ3RjWDVxYjUzd2lKaGxVQ0hUd1NzaCtBQ1NHYTJmYmc2Yk9Na09aMm5lNzJKRlgrTTRRMmpURmRIcGV4a082aDMxOVcreGZTZmdQTnpXNTZCd2RqbUs2TkpQTDl5bzBtWGtxM2VzRXBYVzBWSklzQU5uT3ZKc3lKUnRuTXlJUDRlZGhOSk9CaTNDQ0RIVXpsTDV2dnd4Y1lNdjI3SXBBVnBHbHNaK1dsdkxFWjNIRTdJa2tqYlRJeHBqekxMOExRSFhNZkdScFh1V2ZpSlRwRmRYZjUzN2pBTDNQbWVvV0FxandkV3VSdUF1b3hUM2lJNDh6UjdkSVhhV3kxYWZVTkdJQUMrU1gvS1FiY3V1QS84UHFxUkhva1UzbW01RzdkK3J0SDlWaWk1V1JRcUJKR1VCSi81dEtiRkFjZllZUFljbjNSTmJIWkp5UzAxdz09In0seyJJZCI6IjMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkZ5UjJjNDZyT0hiWTBqSnFWc2ViV1dlMXpoWGVYNzdhRGs4QmdaM0s4MWZMWW5iTFR1cjJUYTZ6ZU1TcmQ5Yyt0akxRZldBZlpTanA2c0FEM29hWjduZTJFazFkVkZVYm9HdUdnTzlHN3lqWnZOZDB3VW04eVN6alQ1UngrK2lZWTZWdS9DTExYdHllT2pOd1dlYXVUVHFvVHVna0VadFJad1p0dVc4S0pCaHZWYzR1WFVTaTJialY4RDFJNUtKMkV6ejhVL3FpRDlHVkVlRWVXSDNKcEY0NHFxTXRPMCtOY0JXbXFGa1Rjb1ljdFd0d3lrdW55RGdlM2hkbmxGWFFUMkU1RWRpZWozenNLeHJuQXJpZUtibjAzbTdHd3BPUG0zQXd6ODhSSTZWdlZMZzc2NTFBVUpnVHlTKzRuWng2NXdaYjVmR3BOS2xtemxEZzR0S0tlZjFGMWlJS0dLR2xMODNPdUhMd29lWDdLd3BOTDEyb2dkcU05d3FiaDhhU2t2UVV3eC81YURhSnU3YkRhMnh4UXc9PSJ9LHsiSWQiOiI0IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJuTnZDclU3ZVRKNThNZmZZTWQ5Q3FiRUxCeFpkS1BSWkQwWEJ4WldmUnpRcnNXb0MzMW9NSXVlT0RMa3liVmw3VFdqaFpSMVlkQjRmbW9qeE5qSG5hN0lvc2c0MlkzV0JvVzRoQjBCQXVGVmZBa0RpTHQ1dUJUYkNsOU5nOHNHUkI1TjJyTlk5U3BJTmtJZitkWUZLOHVvRStJaHFtcUcvM00wSGVQM0pTVWlpZFZnamRRVG5qbldnWjJBRTJaZ0kvWmFmSnJ6UDJmWk9RTFpRVWRmK3dVa2pnMjFvQzBvUWcwOXZZNXRna1VHSUNTS1lBKzhqK25YSExIY2ltZm1LMStBZjJyR2x5OGdKY1FobmJwc3E5WnV3b3lVYXk0aVZuSDMyWU5UbkUwNmZUWkhISDJ4ZnFqc1hYVUFoTGJ4R09pZ0N1SHJIK3JFMUFaQWo1Q3FwSUZxd1ljcVl1cURkcmNxS0RnR2ZUT2M2dTQxYmovVmYwKzA3VlM5YTBKSThIZGdMVFlyUHZwbm1rUFVzRWErSzh3PT0ifSx7IklkIjoiNSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCNnhpNm5jSzdYQWUxMisvcWJhQVJLYWNtSUpEM3VteXFuZ2lFYlJDNjVhbDN0bEZObzRLQlQ5Rlc1dlNiaDd6UmI4V3RLc25SVHVUUE5lMW5RV2tzaHJRRGRqQ08yNmdod0ZIVHFzazV3NXBqK1dXb2czcU1SNTFnamFJTHpNZVRvMGw5OENCRk9Qc1JFenBKeDM1ZWJscXdLL0lyTHB4S3BBbEd5VEtzRVk2WkZRUysxME1QYmhBNlljNHNTSm5tOXVsbHkxQW1nN1hDdURua29PR1E2alR5NFQxWm5iZm9XZEVBT2xBaDNteVVxTVZVQjNCaG1FU25ERm1HcjVpampoRzRSOERPeTRtdXUyQlEvNFk0ZE1OUzdFMTJuUHd2SHNxK004amdHZG9hWW54N0tucmNrZFM5VkdRU09HMXpaOWNpUEk1ZTJEejBzL0VJMDdiS3FBTU5ITWlEYjZQSUI5YzFFZ1Yrc0svUHpoS0ljdGYzZ25VM1gxRzBUWFluSmp5Z3llTWtqTkpNQTFtNHJtOHJqQT09In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "82" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:59 GMT" + ], + "X-Amzn-Requestid": [ + "4e96900c-e211-5bef-899c-f0f822e696b9" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifSx7IklkIjoiMSJ9LHsiSWQiOiIzIn0seyJJZCI6IjQifSx7IklkIjoiNSJ9LHsiSWQiOiIyIn1dfQ==" + } + }, + { + "ID": "89fdb52d4d5cc272", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "86" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0JhdGNoaW5nLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:00 GMT" + ], + "X-Amzn-Requestid": [ + "5ece4c5c-44db-5798-95f7-2ca8842cdace" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestCancelSendReceive.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestCancelSendReceive.replay new file mode 100644 index 000000000..6b56b0f03 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestCancelSendReceive.replay @@ -0,0 +1,279 @@ +{ + "Initial": "AQAAAA7gDLW4IgeqywAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "1b1a4df1ba0cec4c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "47" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "95" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:00 GMT" + ], + "X-Amzn-Requestid": [ + "16af9b85-3c96-5e2f-9fed-fb71fc6e89e1" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXRvcC0xIn0=" + } + }, + { + "ID": "06f31db968081f43", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "125" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:00 GMT" + ], + "X-Amzn-Requestid": [ + "c99869cd-2b15-5c05-954b-0939ebed6bcb" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXRvcC0xIn19" + } + }, + { + "ID": "a226c3723f72d2fe", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "476" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljQ2FuY2VsU2VuZFJlY2VpdmUtdG9wLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:00 GMT" + ], + "X-Amzn-Requestid": [ + "e5a14765-5684-5445-840c-2791967c938b" + ] + }, + "Body": "" + } + }, + { + "ID": "9e60e51029aefeae", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "95" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0NhbmNlbFNlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:01 GMT" + ], + "X-Amzn-Requestid": [ + "9c3c4231-0505-5e8c-9d9b-22c5c5fd0942" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestDoubleAck.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestDoubleAck.replay new file mode 100644 index 000000000..3831a4cad --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestDoubleAck.replay @@ -0,0 +1,975 @@ +{ + "Initial": "AQAAAA7gDLWtO2v83wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "fc1a63fe67f9a460", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "39" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "87" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "eca298c1-d422-5cbf-8bcf-f83514cc06ae" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9" + } + }, + { + "ID": "f4d3af76aa1154fb", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "117" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "88" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "9bb3c8d1-9292-56ed-b07d-a825527c1cfc" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9fQ==" + } + }, + { + "ID": "154bf4b4183760e0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "460" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljRG91YmxlQWNrLXRvcC0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU1FTVG9waWNEb3VibGVBY2stdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "d3b1a702-2f04-5501-96f6-c7f6efeaef10" + ] + }, + "Body": "" + } + }, + { + "ID": "6e5f639a0fbd118c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "128" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6IjAifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NRU1RvcGljRG91YmxlQWNrLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "132" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "7191d4e9-98fb-5616-877e-b41d5815fc07" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNZXNzYWdlSWQiOiJlMGI4NDM1YS0xYTIzLTQ5ZmItODYzNS1kMjFiMWJjYmE0YTMifV19" + } + }, + { + "ID": "d731f9f0ab83ea2f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "128" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6IjEifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NRU1RvcGljRG91YmxlQWNrLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "132" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "9fb7e5f4-aa1c-5728-89eb-85006af29d39" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNZXNzYWdlSWQiOiI1NWE2YWJkZS0wYTdiLTRlNjMtODc4MC03NjQzM2M5NmI4M2UifV19" + } + }, + { + "ID": "e14337a43e971f11", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "128" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6IjIifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NRU1RvcGljRG91YmxlQWNrLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "132" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "38338dc8-769b-52a0-8196-ed3cb67588b1" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiYzgxZTcyOGQ5ZDRjMmY2MzZmMDY3Zjg5Y2MxNDg2MmMiLCJNZXNzYWdlSWQiOiI0NGVlNTViYy1mNmZkLTQ0MjMtOTZhYS0xNjExOWJjODdhZWYifV19" + } + }, + { + "ID": "80c6011163b59e4b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MywiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1424" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "4834a99f-b98f-5f82-abe2-c96b7961f593" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3MDYyNSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjcwNDMwIn0sIkJvZHkiOiIwIiwiTUQ1T2ZCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNZXNzYWdlSWQiOiJlMGI4NDM1YS0xYTIzLTQ5ZmItODYzNS1kMjFiMWJjYmE0YTMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQm5lVmgvRGprcGFVTEtvVzEvUjNuSnFlSkZHby9TbEVuZ2pOL05jNG1iNkxHRkdOaVpMUkpQbFJqMzZHVGpGNkZlcGV5QjZsNVU3MWQ1Y053L2JIbmJUQytBOW5nQTA0MnZFT0YrT2ZwQ2cwa2ZHWlcwbTkvaXc0Z3YyNHMvWGJlTTUweDBMR0Y4Uy85NFMrWEVXcEdyeGNaR2tKZXRKbjJPS0UyaWE0bVRkUmd0U3JXVTdPYnBhbnFIWnNOcHBSYTk4K0xtcytXaisvN1FKeCs5d2FGMlVxYWNGRERZaVMwQXQxYmNHYmh3MmNBMVYvNy9heitEWlFmcDR5L2tOeFE2NWY5VUdsaDE4NURZUTk2SVBLSW54YTVtR0lZT0hNbElaczFYaDNnR3VkUkdqdmxIODN0NjJtRXRxVGdqRWFQbzhQNUNOaENWWWFRM2RzODNPN1dYd1NYTFJqVU5iYldhcWZxMElXRVdYcm1LeHVOaitYY1pEK0U3UHdJT0dCQ29Gb0E0dHpYMXNkd2pCV1d3S0tWd2c9PSJ9LHsiQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3MDYyNSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjcwNTYzIn0sIkJvZHkiOiIyIiwiTUQ1T2ZCb2R5IjoiYzgxZTcyOGQ5ZDRjMmY2MzZmMDY3Zjg5Y2MxNDg2MmMiLCJNZXNzYWdlSWQiOiI0NGVlNTViYy1mNmZkLTQ0MjMtOTZhYS0xNjExOWJjODdhZWYiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjhXdURoT0U3SXZhajNOTmRoYmJ2R1cwWUEvWkQ4SE5OY0pjcnREdndKYkVzTkdDbFVSRWIybktZQ1BleEp5S0gwT1BscG5OS29iS3VRQ3UvQ0hURld6K3BwWTVCTWxNOGtUa3RKRHhEczUvZ1dQV2wrWnRiZW1FMk13Y3BUZWVheGhjYjRlSXI5TmtQQ2tlaDlZWXVyYll3cFUxQVFEU2srTkNxenYrRGhiL3RGYlVtU052SXlCT1BKNXFqZnZibDAraXo5SXJOS2VWS3llVHlRdDFLUzczS1RuL1ZabVJFTWx0emdhVDY4VEF5TXBiREcvU2ZNRlRGZE50MzNFVUNSSm9LZEExNllCMmhQYzRYR2xzRlZtY3d2dVNDY1VwblVqaFZCbFJ4cCtxOC9JSHkvMk1icjA5a21GdHRNTXpRQUFma0Nra1QyNzNxei91YmpFTk9TS1VadmdaQkQ4NTE2K0JUbCtBZnR3MkhkV09scVN2dUlPQ0ZDVUZiOTJTZjEwZko1Tmx0V3ZtendTNGdEZjNjcXc9PSJ9XX0=" + } + }, + { + "ID": "e2954f88f0a8e6a5", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MywiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "719" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "1b4a5181-0887-5b6d-8e49-3175c869b17c" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3MDY4NyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjcwNDk3In0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNZXNzYWdlSWQiOiI1NWE2YWJkZS0wYTdiLTRlNjMtODc4MC03NjQzM2M5NmI4M2UiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjc0dmErVmFhNUpPY1JHcjloc21PUEQ4UWxXaTBKMzk3WTk0N1NDQnJpL0lHOFBGZlpXQS81bGx1UGpvTkhjSVA1S1BESVhJQXI0cGRTbDdyREF0a0FtUHRWcGM4dWlYejFlSStNN2VCbXl4cG9zMEZxMlJjbUtIMXZkMENvam1Xd0UxV3gvWitLZFUzbW55UnNWNUlhemI5em0rUmpCNkZ1bU0vWFhEVmJFVUw4cnc0REdjN2Z3ODhVNGxiQURSbGJXMytyQi9BMHA4NW5lYndYNUxITFVsbW5aUkNhdEVKc1RVVE1PQVd3Z1UyUTFoVFZheXRqMWJXU0ZPKzMyQlVqSGhLQ2hMV3FhbFY5OENsem9sYzVQV3NEb3Jlb21ydkZ6NUFJV2tiNDJVby9HbkYrSEJjYXkyRjRacG5nTEo4QjdnM0lORjZGNGJYRG02S1djWEsvaFh4QkRnOUphVDdoODRMMk1HeUVLMm9ETnA3Rk05YUlsZ3FEZzdLOE1ITS81NDEvejhKckwrZkZueURBdDl6WUE9PSJ9XX0=" + } + }, + { + "ID": "8960f2552a9772ee", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "983" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQm5lVmgvRGprcGFVTEtvVzEvUjNuSnFlSkZHby9TbEVuZ2pOL05jNG1iNkxHRkdOaVpMUkpQbFJqMzZHVGpGNkZlcGV5QjZsNVU3MWQ1Y053L2JIbmJUQytBOW5nQTA0MnZFT0YrT2ZwQ2cwa2ZHWlcwbTkvaXc0Z3YyNHMvWGJlTTUweDBMR0Y4Uy85NFMrWEVXcEdyeGNaR2tKZXRKbjJPS0UyaWE0bVRkUmd0U3JXVTdPYnBhbnFIWnNOcHBSYTk4K0xtcytXaisvN1FKeCs5d2FGMlVxYWNGRERZaVMwQXQxYmNHYmh3MmNBMVYvNy9heitEWlFmcDR5L2tOeFE2NWY5VUdsaDE4NURZUTk2SVBLSW54YTVtR0lZT0hNbElaczFYaDNnR3VkUkdqdmxIODN0NjJtRXRxVGdqRWFQbzhQNUNOaENWWWFRM2RzODNPN1dYd1NYTFJqVU5iYldhcWZxMElXRVdYcm1LeHVOaitYY1pEK0U3UHdJT0dCQ29Gb0E0dHpYMXNkd2pCV1d3S0tWd2c9PSJ9LHsiSWQiOiIxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUI4V3VEaE9FN0l2YWozTk5kaGJidkdXMFlBL1pEOEhOTmNKY3J0RHZ3SmJFc05HQ2xVUkViMm5LWUNQZXhKeUtIME9QbHBuTktvYkt1UUN1L0NIVEZXeitwcFk1Qk1sTThrVGt0SkR4RHM1L2dXUFdsK1p0YmVtRTJNd2NwVGVlYXhoY2I0ZUlyOU5rUENrZWg5WVl1cmJZd3BVMUFRRFNrK05DcXp2K0RoYi90RmJVbVNOdkl5Qk9QSjVxamZ2YmwwK2l6OUlyTktlVkt5ZVR5UXQxS1M3M0tUbi9WWm1SRU1sdHpnYVQ2OFRBeU1wYkRHL1NmTUZURmROdDMzRVVDUkpvS2RBMTZZQjJoUGM0WEdsc0ZWbWN3dnVTQ2NVcG5VamhWQmxSeHArcTgvSUh5LzJNYnIwOWttRnR0TU16UUFBZmtDa2tUMjczcXovdWJqRU5PU0tVWnZnWkJEODUxNitCVGwrQWZ0dzJIZFdPbHFTdnVJT0NGQ1VGYjkyU2YxMGZKNU5sdFd2bXp3UzRnRGYzY3F3PT0ifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NRU1RvcGljRG91YmxlQWNrLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "38" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "af7ea98c-5b14-51f7-a598-c9789bfa6be6" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifSx7IklkIjoiMSJ9XX0=" + } + }, + { + "ID": "8299eb71e77ed6a9", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "983" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQm5lVmgvRGprcGFVTEtvVzEvUjNuSnFlSkZHby9TbEVuZ2pOL05jNG1iNkxHRkdOaVpMUkpQbFJqMzZHVGpGNkZlcGV5QjZsNVU3MWQ1Y053L2JIbmJUQytBOW5nQTA0MnZFT0YrT2ZwQ2cwa2ZHWlcwbTkvaXc0Z3YyNHMvWGJlTTUweDBMR0Y4Uy85NFMrWEVXcEdyeGNaR2tKZXRKbjJPS0UyaWE0bVRkUmd0U3JXVTdPYnBhbnFIWnNOcHBSYTk4K0xtcytXaisvN1FKeCs5d2FGMlVxYWNGRERZaVMwQXQxYmNHYmh3MmNBMVYvNy9heitEWlFmcDR5L2tOeFE2NWY5VUdsaDE4NURZUTk2SVBLSW54YTVtR0lZT0hNbElaczFYaDNnR3VkUkdqdmxIODN0NjJtRXRxVGdqRWFQbzhQNUNOaENWWWFRM2RzODNPN1dYd1NYTFJqVU5iYldhcWZxMElXRVdYcm1LeHVOaitYY1pEK0U3UHdJT0dCQ29Gb0E0dHpYMXNkd2pCV1d3S0tWd2c9PSJ9LHsiSWQiOiIxIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUI4V3VEaE9FN0l2YWozTk5kaGJidkdXMFlBL1pEOEhOTmNKY3J0RHZ3SmJFc05HQ2xVUkViMm5LWUNQZXhKeUtIME9QbHBuTktvYkt1UUN1L0NIVEZXeitwcFk1Qk1sTThrVGt0SkR4RHM1L2dXUFdsK1p0YmVtRTJNd2NwVGVlYXhoY2I0ZUlyOU5rUENrZWg5WVl1cmJZd3BVMUFRRFNrK05DcXp2K0RoYi90RmJVbVNOdkl5Qk9QSjVxamZ2YmwwK2l6OUlyTktlVkt5ZVR5UXQxS1M3M0tUbi9WWm1SRU1sdHpnYVQ2OFRBeU1wYkRHL1NmTUZURmROdDMzRVVDUkpvS2RBMTZZQjJoUGM0WEdsc0ZWbWN3dnVTQ2NVcG5VamhWQmxSeHArcTgvSUh5LzJNYnIwOWttRnR0TU16UUFBZmtDa2tUMjczcXovdWJqRU5PU0tVWnZnWkJEODUxNitCVGwrQWZ0dzJIZFdPbHFTdnVJT0NGQ1VGYjkyU2YxMGZKNU5sdFd2bXp3UzRnRGYzY3F3PT0ifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NRU1RvcGljRG91YmxlQWNrLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "38" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "f6b1e930-1ed5-5f2d-8226-89c4de3b553c" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifSx7IklkIjoiMSJ9XX0=" + } + }, + { + "ID": "998de355eb00273c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "1491" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ChangeMessageVisibilityBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQm5lVmgvRGprcGFVTEtvVzEvUjNuSnFlSkZHby9TbEVuZ2pOL05jNG1iNkxHRkdOaVpMUkpQbFJqMzZHVGpGNkZlcGV5QjZsNVU3MWQ1Y053L2JIbmJUQytBOW5nQTA0MnZFT0YrT2ZwQ2cwa2ZHWlcwbTkvaXc0Z3YyNHMvWGJlTTUweDBMR0Y4Uy85NFMrWEVXcEdyeGNaR2tKZXRKbjJPS0UyaWE0bVRkUmd0U3JXVTdPYnBhbnFIWnNOcHBSYTk4K0xtcytXaisvN1FKeCs5d2FGMlVxYWNGRERZaVMwQXQxYmNHYmh3MmNBMVYvNy9heitEWlFmcDR5L2tOeFE2NWY5VUdsaDE4NURZUTk2SVBLSW54YTVtR0lZT0hNbElaczFYaDNnR3VkUkdqdmxIODN0NjJtRXRxVGdqRWFQbzhQNUNOaENWWWFRM2RzODNPN1dYd1NYTFJqVU5iYldhcWZxMElXRVdYcm1LeHVOaitYY1pEK0U3UHdJT0dCQ29Gb0E0dHpYMXNkd2pCV1d3S0tWd2c9PSIsIlZpc2liaWxpdHlUaW1lb3V0IjoxfSx7IklkIjoiMSIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCOFd1RGhPRTdJdmFqM05OZGhiYnZHVzBZQS9aRDhITk5jSmNydER2d0piRXNOR0NsVVJFYjJuS1lDUGV4SnlLSDBPUGxwbk5Lb2JLdVFDdS9DSFRGV3orcHBZNUJNbE04a1RrdEpEeERzNS9nV1BXbCtadGJlbUUyTXdjcFRlZWF4aGNiNGVJcjlOa1BDa2VoOVlZdXJiWXdwVTFBUURTaytOQ3F6ditEaGIvdEZiVW1TTnZJeUJPUEo1cWpmdmJsMCtpejlJck5LZVZLeWVUeVF0MUtTNzNLVG4vVlptUkVNbHR6Z2FUNjhUQXlNcGJERy9TZk1GVEZkTnQzM0VVQ1JKb0tkQTE2WUIyaFBjNFhHbHNGVm1jd3Z1U0NjVXBuVWpoVkJsUnhwK3E4L0lIeS8yTWJyMDlrbUZ0dE1NelFBQWZrQ2trVDI3M3F6L3ViakVOT1NLVVp2Z1pCRDg1MTYrQlRsK0FmdHcySGRXT2xxU3Z1SU9DRkNVRmI5MlNmMTBmSjVObHRXdm16d1M0Z0RmM2Nxdz09IiwiVmlzaWJpbGl0eVRpbWVvdXQiOjF9LHsiSWQiOiIyIiwiUmVjZWlwdEhhbmRsZSI6IkFRRUI3NHZhK1ZhYTVKT2NSR3I5aHNtT1BEOFFsV2kwSjM5N1k5NDdTQ0JyaS9JRzhQRmZaV0EvNWxsdVBqb05IY0lQNUtQRElYSUFyNHBkU2w3ckRBdGtBbVB0VnBjOHVpWHoxZUkrTTdlQm15eHBvczBGcTJSY21LSDF2ZDBDb2ptV3dFMVd4L1orS2RVM21ueVJzVjVJYXpiOXptK1JqQjZGdW1NL1hYRFZiRVVMOHJ3NERHYzdmdzg4VTRsYkFEUmxiVzMrckIvQTBwODVuZWJ3WDVMSExVbG1uWlJDYXRFSnNUVVRNT0FXd2dVMlExaFRWYXl0ajFiV1NGTyszMkJVakhoS0NoTFdxYWxWOThDbHpvbGM1UFdzRG9yZW9tcnZGejVBSVdrYjQyVW8vR25GK0hCY2F5MkY0WnBuZ0xKOEI3ZzNJTkY2RjRiWERtNktXY1hLL2hYeEJEZzlKYVQ3aDg0TDJNR3lFSzJvRE5wN0ZNOWFJbGdxRGc3SzhNSE0vNTQxL3o4SnJMK2ZGbnlEQXQ5ellBPT0iLCJWaXNpYmlsaXR5VGltZW91dCI6MX1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "332" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "02e02b96-3d7d-5593-a6d1-4b62fd932f82" + ] + }, + "Body": "eyJGYWlsZWQiOlt7IkNvZGUiOiJSZWNlaXB0SGFuZGxlSXNJbnZhbGlkIiwiSWQiOiIwIiwiTWVzc2FnZSI6Ik1lc3NhZ2UgZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IGF2YWlsYWJsZSBmb3IgdmlzaWJpbGl0eSB0aW1lb3V0IGNoYW5nZSIsIlNlbmRlckZhdWx0Ijp0cnVlfSx7IkNvZGUiOiJSZWNlaXB0SGFuZGxlSXNJbnZhbGlkIiwiSWQiOiIxIiwiTWVzc2FnZSI6Ik1lc3NhZ2UgZG9lcyBub3QgZXhpc3Qgb3IgaXMgbm90IGF2YWlsYWJsZSBmb3IgdmlzaWJpbGl0eSB0aW1lb3V0IGNoYW5nZSIsIlNlbmRlckZhdWx0Ijp0cnVlfV0sIlN1Y2Nlc3NmdWwiOlt7IklkIjoiMiJ9XX0=" + } + }, + { + "ID": "0e54a09a470b93d2", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:50 GMT" + ], + "X-Amzn-Requestid": [ + "f04a98af-c4cc-5058-9f0c-f85b04228a49" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "a24716bf4ba87433", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:51 GMT" + ], + "X-Amzn-Requestid": [ + "affe01c5-85fe-5011-8d7a-613145110a00" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "eb4f66d036ae8dfe", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:51 GMT" + ], + "X-Amzn-Requestid": [ + "c5f9d06b-4680-5d9c-bd00-b09f866f078d" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "256cbf867e4ff551", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "719" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:52 GMT" + ], + "X-Amzn-Requestid": [ + "603460f3-b427-5d05-89e7-000774c8e714" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3MDY4NyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMiIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjcwNDk3In0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNZXNzYWdlSWQiOiI1NWE2YWJkZS0wYTdiLTRlNjMtODc4MC03NjQzM2M5NmI4M2UiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmpXZ0psWE9Zdlo1WSs2cHE4c1NpVFF3bjV1bmxJU1RDQ21EWVp2UHo0QWo2Z3V3Z1ZYeFBhL2hBTnJDUGdKSERJak9PcVU0YjVzbEJQNDBpcFgyWnhpN0R2cHZORTJlVGdJd053TzBiME1jVmo1SlZobEdHOE9UTW80eEpiRlRKd0xkQ2EwSE1nekpuZnNqczRDVWtjTWhKZ21oNkJGZWZDMFpyUkhGbVNrV2tKZHZnUFRBc3hKYVorSG1YeHhjeXBkL0VGZklOMEMxMnNZdzFlZEozb25sblFiUlQyZ3dhd0VxYWtlTDJ6ZzlySjYya1k0Z0sxZnJnZXJIZlNCeG5kdWN3SUlGdmR3bjk4QlR5azQxdVVVMDJ2anZZaXVuWTVpbVlZT2Z2ck1tOGxNL0ZCREZmUVcyRk1qY0JFMEE5RnVhWk1wYUdZcWEvQTJWMmpRVUcvT1JsdEtOR3hZMlVuVkNFZS9yYnBaN1UvSXpkbFRBdzJUN3ljOW5YOXNqRXVZRTVSYUhxSFBYUzZYZCtIa21mU3c9PSJ9XX0=" + } + }, + { + "ID": "c305e21602ef2682", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "87" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0RvdWJsZUFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:52 GMT" + ], + "X-Amzn-Requestid": [ + "23315f06-383a-509c-92f9-3ff2f8ca1a8d" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestErrorOnReceiveFromClosedSubscription.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestErrorOnReceiveFromClosedSubscription.replay new file mode 100644 index 000000000..feae0d481 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestErrorOnReceiveFromClosedSubscription.replay @@ -0,0 +1,279 @@ +{ + "Initial": "AQAAAA7gDLWwCewPYAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "250c2c53c339fba0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "66" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "114" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:52 GMT" + ], + "X-Amzn-Requestid": [ + "d302b90b-2835-5050-946e-d9ffe8c53ce0" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi10b3AtMSJ9" + } + }, + { + "ID": "1dd1a35e0f881f75", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "144" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "115" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:52 GMT" + ], + "X-Amzn-Requestid": [ + "7d0ee6f8-6acf-57d9-8b17-860caa3f0b69" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi10b3AtMSJ9fQ==" + } + }, + { + "ID": "0983cc310feceb5d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "514" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljRXJyb3JPblJlY2VpdmVGcm9tQ2xvc2VkU3Vic2NyaXB0aW9uLXRvcC0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU1FTVG9waWNFcnJvck9uUmVjZWl2ZUZyb21DbG9zZWRTdWJzY3JpcHRpb24tdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:52 GMT" + ], + "X-Amzn-Requestid": [ + "8458781d-c5cc-5574-91b6-18e9053cc9c4" + ] + }, + "Body": "" + } + }, + { + "ID": "6f770aa2be8265e0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "114" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0Vycm9yT25SZWNlaXZlRnJvbUNsb3NlZFN1YnNjcmlwdGlvbi10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:52 GMT" + ], + "X-Amzn-Requestid": [ + "1517af4d-f966-5f07-a733-cfb9399683b7" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestErrorOnSendToClosedTopic.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestErrorOnSendToClosedTopic.replay new file mode 100644 index 000000000..63d1b2c61 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestErrorOnSendToClosedTopic.replay @@ -0,0 +1,279 @@ +{ + "Initial": "AQAAAA7gDLW4Aw60mgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b565470a82f9b9cf", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "54" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY0Vycm9yT25TZW5kVG9DbG9zZWRUb3BpYy10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "102" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:00 GMT" + ], + "X-Amzn-Requestid": [ + "0eafe36d-4db6-5419-bb69-83998d4e3212" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0Vycm9yT25TZW5kVG9DbG9zZWRUb3BpYy10b3AtMSJ9" + } + }, + { + "ID": "a86dde6f910278de", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "132" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0Vycm9yT25TZW5kVG9DbG9zZWRUb3BpYy10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "103" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:00 GMT" + ], + "X-Amzn-Requestid": [ + "5f01b93d-2d33-5dc2-99bc-d9c9edcb1bc9" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY0Vycm9yT25TZW5kVG9DbG9zZWRUb3BpYy10b3AtMSJ9fQ==" + } + }, + { + "ID": "4a8b3a8175522732", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "490" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljRXJyb3JPblNlbmRUb0Nsb3NlZFRvcGljLXRvcC0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU1FTVG9waWNFcnJvck9uU2VuZFRvQ2xvc2VkVG9waWMtdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:00 GMT" + ], + "X-Amzn-Requestid": [ + "70e75ac3-f7d9-5fd8-9b43-3a37372119d3" + ] + }, + "Body": "" + } + }, + { + "ID": "cf63ce4772e6cfc6", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "102" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY0Vycm9yT25TZW5kVG9DbG9zZWRUb3BpYy10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:00 GMT" + ], + "X-Amzn-Requestid": [ + "d533cd40-6bc6-54eb-824d-adb4ab3e52e0" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestMetadata.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestMetadata.replay new file mode 100644 index 000000000..55dcb49b4 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestMetadata.replay @@ -0,0 +1,627 @@ +{ + "Initial": "AQAAAA7gDLWwNtYbvgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "59e77c8491c9bd57", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "38" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY01ldGFkYXRhLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "86" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:53 GMT" + ], + "X-Amzn-Requestid": [ + "acde7b7a-f6d3-50f9-96f6-1b8e362280cb" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY01ldGFkYXRhLXRvcC0xIn0=" + } + }, + { + "ID": "d44a2968b78ef0a7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "116" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY01ldGFkYXRhLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "87" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:53 GMT" + ], + "X-Amzn-Requestid": [ + "94c6afac-3774-5b6c-ae40-cf58f7858b5e" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY01ldGFkYXRhLXRvcC0xIn19" + } + }, + { + "ID": "95ebef35e75fd82e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "458" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljTWV0YWRhdGEtdG9wLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY01ldGFkYXRhLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:53 GMT" + ], + "X-Amzn-Requestid": [ + "8d5719ce-5613-5164-b1f0-793a96e26156" + ] + }, + "Body": "" + } + }, + { + "ID": "baa85aa9ea81fad8", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "1610" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJDTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "192" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:53 GMT" + ], + "X-Amzn-Requestid": [ + "26d72c88-819c-5c7a-bdb6-4c7c416d3c48" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiZjNmYmZkZTFlODI1MjRkZWMwOGU0YjVmNjYwYTEwNmMiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiNWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMiLCJNZXNzYWdlSWQiOiI2N2U4MWE3ZS02Nzg5LTQ0MDMtYjIyZC1mM2M3ZWRhNDQzMzYifV19" + } + }, + { + "ID": "a90e5ecc7176c8cb", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY01ldGFkYXRhLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2262" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:53 GMT" + ], + "X-Amzn-Requestid": [ + "bbd61d74-1274-56b5-a276-7d80d2850687" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3MzQxOSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjczMzUwIn0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTUQ1T2ZNZXNzYWdlQXR0cmlidXRlcyI6ImYzZmJmZGUxZTgyNTI0ZGVjMDhlNGI1ZjY2MGExMDZjIiwiTWVzc2FnZUF0dHJpYnV0ZXMiOnsiMTIzNDUiOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6IjEyMzQ1In0sIl9fMHgwX19fXzB4MV9fX18weDJfX19fMHgzX19fXzB4NF9fX18weDVfX19fMHg2X19fXzB4N19fX18weDhfX19fMHg5X19fXzB4YV9fX18weGJfX19fMHhjX19fXzB4ZF9fX18weGVfX19fMHhmX18iOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6IiUwMCUwMSUwMiUwMyUwNCUwNSUwNiUwNyUwOCUwOSUwQSUwQiUwQyUwRCUwRSUwRiJ9LCJfXzB4MTBfX19fMHgxMV9fX18weDEyX19fXzB4MTNfX19fMHgxNF9fX18weDE1X19fXzB4MTZfX19fMHgxN19fX18weDE4X19fXzB4MTlfX19fMHgxYV9fX18weDFiX19fXzB4MWNfX19fMHgxZF9fX18weDFlX19fXzB4MWZfXyI6eyJEYXRhVHlwZSI6IlN0cmluZyIsIlN0cmluZ1ZhbHVlIjoiJTEwJTExJTEyJTEzJTE0JTE1JTE2JTE3JTE4JTE5JTFBJTFCJTFDJTFEJTFFJTFGIn0sIl9fMHgyMF9fX18weDIxX19fXzB4MjJfX19fMHgyM19fX18weDI0X19fXzB4MjVfX19fMHgyNl9fX18weDI3X19fXzB4MjhfX19fMHgyOV9fX18weDJhX19fXzB4MmJfX19fMHgyY19fLS5fXzB4MmZfXyI6eyJEYXRhVHlwZSI6IlN0cmluZyIsIlN0cmluZ1ZhbHVlIjoiJTIwJTIxJTIyJTIzJCUyNSYlMjclMjglMjklMkErJTJDLS4lMkYifSwiX18weDJlX19fXzB4MmVfX19fMHgyZl9fZm9vX18weDJmX18uX18weDJlX19fXzB4MmZfX2Jhcl9fMHgyZl9fLl9fMHgyZV9fX18weDJmX18uX18weDJlX19fXzB4MmZfX2Jhei5fXzB4MmVfX19fMHgyZl9fIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIuLiUyRmZvbyUyRi4uJTJGYmFyJTJGLi4lMkYuLiUyRmJhei4uJTJGIn0sIl9fMHgyZV9fX18weDJlX19fXzB4NWNfX2Zvb19fMHg1Y19fLl9fMHgyZV9fX18weDVjX19iYXJfXzB4NWNfXy5fXzB4MmVfX19fMHg1Y19fLl9fMHgyZV9fX18weDVjX19iYXouX18weDJlX19fXzB4NWNfXyI6eyJEYXRhVHlwZSI6IlN0cmluZyIsIlN0cmluZ1ZhbHVlIjoiLi4lNUNmb28lNUMuLiU1Q2JhciU1Qy4uJTVDLi4lNUNiYXouLiU1QyJ9LCJfXzB4MmVfX19fMHgyZV9fX18weDVjX19mb29fXzB4NWNfX19fMHg1Y19fYmFyX18weDVjX19fXzB4NWNfX19fMHg1Y19fYmF6Ijp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIuLiU1Q2ZvbyU1QyU1Q2JhciU1QyU1QyU1Q2JheiJ9LCJfXzB4M2FfX19fMHgzYl9fX18weDNjX19fXzB4M2RfX19fMHgzZV9fX18weDNmX18iOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6IjolM0IlM0M9JTNFJTNGIn0sIl9fMHg0MF9fIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiJAIn0sIl9fMHg1Yl9fX18weDVjX19fXzB4NWRfX19fMHg1ZV9fXyI6eyJEYXRhVHlwZSI6IlN0cmluZyIsIlN0cmluZ1ZhbHVlIjoiJTVCJTVDJTVEJTVFXyJ9fSwiTWVzc2FnZUlkIjoiNjdlODFhN2UtNjc4OS00NDAzLWIyMmQtZjNjN2VkYTQ0MzM2IiwiUmVjZWlwdEhhbmRsZSI6IkFRRUJUNG55K2FUNitoeU1ZUGJBOGdGVkhmM3UzaXdlRTFkZW02Uk9MVFZOeVQrRzI5ZGFreDhhMUxOenZXTjNndEp1eWhVcjV2Y2w5Y0hjcWRqZTZKY25DMStteGpjNUJNbHRla0xUYk5QTy9wNllZUVd4ZFlLemdaNkRFb1d2dTBiOGdhdU5xSHUxa2RGMlB3eHc1cE9SdGMzaTA5OGxhZ3pmQnAzY0JGUThMNWoyYVAzSGg5a2dhQmY4Si91NkNIeCs1Rk14SjlGTUFJT2sxK1B1azdZV2Z1c3lUdVhHWjRVZXUwOFMyaE5LbjZ4WFNZYjRKU0VWNGEzQlA4ODJYdnRCUnJYeEpGWlNDZWhGbEhsMVcyS1V6OTVKSTV4VlRheWNIVEFmb3A1U0QzK3QrNE4zL09lTFVmMllPT1l3dWliUjY0VWpza0tlc3pDWEIvamdxZWN0ODlQejgzMFRMWFNZMGg0R3BEOHE4bGpOVmFRNDY3d2ZPN24vUkRYTzhCeVgrSlNWRkVUWHp6aXg1dE5FSmFGVnZRPT0ifV19" + } + }, + { + "ID": "3f1ee3e5b5d64c5f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "849" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJDTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "192" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:53 GMT" + ], + "X-Amzn-Requestid": [ + "33816a1a-1a80-52fb-bf8d-0aeeda7112c9" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiZGU4YmE3MGUyOTA3NjljYTE4NTQzZGE5MjQwZGUwMjUiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiNWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMiLCJNZXNzYWdlSWQiOiJlYzdiNTIzYi0wNzdhLTRkMTctODFlMy00MTA1Y2E3N2JjMGMifV19" + } + }, + { + "ID": "ab7929e34acb4b4a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "540" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlQ0bnkrYVQ2K2h5TVlQYkE4Z0ZWSGYzdTNpd2VFMWRlbTZST0xUVk55VCtHMjlkYWt4OGExTE56dldOM2d0SnV5aFVyNXZjbDljSGNxZGplNkpjbkMxK214amM1Qk1sdGVrTFRiTlBPL3A2WVlRV3hkWUt6Z1o2REVvV3Z1MGI4Z2F1TnFIdTFrZEYyUHd4dzVwT1J0YzNpMDk4bGFnemZCcDNjQkZROEw1ajJhUDNIaDlrZ2FCZjhKL3U2Q0h4KzVGTXhKOUZNQUlPazErUHVrN1lXZnVzeVR1WEdaNFVldTA4UzJoTktuNnhYU1liNEpTRVY0YTNCUDg4Mlh2dEJSclh4SkZaU0NlaEZsSGwxVzJLVXo5NUpJNXhWVGF5Y0hUQWZvcDVTRDMrdCs0TjMvT2VMVWYyWU9PWXd1aWJSNjRVanNrS2VzekNYQi9qZ3FlY3Q4OVB6ODMwVExYU1kwaDRHcEQ4cThsak5WYVE0Njd3Zk83bi9SRFhPOEJ5WCtKU1ZGRVRYenppeDV0TkVKYUZWdlE9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU1FTVG9waWNNZXRhZGF0YS10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:53 GMT" + ], + "X-Amzn-Requestid": [ + "8a5c0fd4-3f20-5413-850c-6f20ffd1a421" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "84a242eb162846c0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "167" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY01ldGFkYXRhLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1501" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:53 GMT" + ], + "X-Amzn-Requestid": [ + "c53127db-a635-54b7-aa18-472f66c48485" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3MzYxNyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0NjczNDg3In0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTUQ1T2ZNZXNzYWdlQXR0cmlidXRlcyI6ImRlOGJhNzBlMjkwNzY5Y2ExODU0M2RhOTI0MGRlMDI1IiwiTWVzc2FnZUF0dHJpYnV0ZXMiOnsiX18weDI2M2FfX19fMHgyNjNhX19fXzB4MjYzYV9fIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIlRTIlOTglQkElRTIlOTglQkElRTIlOTglQkEifSwiX18weDYwX18iOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6IiU2MCJ9LCJfXzB4N2JfX19fMHg3Y19fX18weDdkX19fXzB4N2VfX19fMHg3Zl9fIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIlN0IlN0MlN0R+JTdGIn0sImZvb19fMHgyMF9fYmFyX18weDIwX19iYXoiOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6ImZvbyUyMGJhciUyMGJheiJ9LCJmb29fXzB4MjJfX2Jhcl9fMHgyMl9fYmF6Ijp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiJmb28lMjJiYXIlMjJiYXoifSwiZm9vX18weDJmX19fXzB4MmZfX2Jhcl9fMHgyZl9fX18weDJmX19fXzB4MmZfX2JheiI6eyJEYXRhVHlwZSI6IlN0cmluZyIsIlN0cmluZ1ZhbHVlIjoiZm9vJTJGJTJGYmFyJTJGJTJGJTJGYmF6In0sImZvb19fMHgyZl9fYmFyX18weDJmX19iYXoiOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6ImZvbyUyRmJhciUyRmJheiJ9LCJmb29fXzB4NWNfX2Jhcl9fMHg1Y19fYmF6Ijp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiJmb28lNUNiYXIlNUNiYXoifX0sIk1lc3NhZ2VJZCI6ImVjN2I1MjNiLTA3N2EtNGQxNy04MWUzLTQxMDVjYTc3YmMwYyIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCNjhqQnZSU0RPbUlWUGhSbWdlQ1FKZlQ4R1B3Rm9uNkY4cVNuemE5NHdHVi8wdDBKUlZUalRBTEZsVU1WTHhXTTRKa3FzSnVFOU11MEs0eUI5SUpjamxRWXVZeWdyUkszTE1VaEwvZm5PTGkvN2dSMVhhV3dTa1FjRnpwWndQQm90Y0Vxbzl6NEN0VlhuVFFsUU15VklBcGFWRlVLTk42MlVIMG9FTVk0SjdtMUhBNXRHTFc4MkppZ25mdldkUWJ1VGNoQUhZekJ6RkZiSDlXRENybFdRRjRJcVVWSDM1N2x2OERTcXpCVVRPcVVyai9Ta0dOeGJPZWdCL1ZvYjVJMDJNZTNsVkdOelB4bmswYnY3VnJTc0ZFWVRkRERPb28zTE9vTWpSZFZkNnBCMHFpUVBWeCtLWmFpdVMxVTFTcFJTVnRBM29PT3U3OHl3RnVmZENzMjlqWEhTK05Oam9OMUdwZ0VQT3VQa1FHZWNBdHJjWmQ4OTFqM0dVTmswa2FqVmhDZWtMNzBOaENSeE85NzRSYkhJZz09In1dfQ==" + } + }, + { + "ID": "0708db5de6b7851d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "540" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjY4akJ2UlNET21JVlBoUm1nZUNRSmZUOEdQd0ZvbjZGOHFTbnphOTR3R1YvMHQwSlJWVGpUQUxGbFVNVkx4V000Smtxc0p1RTlNdTBLNHlCOUlKY2psUVl1WXlnclJLM0xNVWhML2ZuT0xpLzdnUjFYYVd3U2tRY0Z6cFp3UEJvdGNFcW85ejRDdFZYblRRbFFNeVZJQXBhVkZVS05ONjJVSDBvRU1ZNEo3bTFIQTV0R0xXODJKaWduZnZXZFFidVRjaEFIWXpCekZGYkg5V0RDcmxXUUY0SXFVVkgzNTdsdjhEU3F6QlVUT3FVcmovU2tHTnhiT2VnQi9Wb2I1STAyTWUzbFZHTnpQeG5rMGJ2N1ZyU3NGRVlUZERET29vM0xPb01qUmRWZDZwQjBxaVFQVngrS1phaXVTMVUxU3BSU1Z0QTNvT091Nzh5d0Z1ZmRDczI5alhIUytOTmpvTjFHcGdFUE91UGtRR2VjQXRyY1pkODkxajNHVU5rMGthalZoQ2VrTDcwTmhDUnhPOTc0UmJISWc9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU1FTVG9waWNNZXRhZGF0YS10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:53 GMT" + ], + "X-Amzn-Requestid": [ + "1b3bc0fe-5cfc-5584-8e2a-a00a9c0d25b6" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "02c9d255f93d744c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "86" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY01ldGFkYXRhLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:53 GMT" + ], + "X-Amzn-Requestid": [ + "dbd10767-3f18-59fa-82c5-6793ffe959c8" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNack.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNack.replay new file mode 100644 index 000000000..b13edd857 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNack.replay @@ -0,0 +1,1033 @@ +{ + "Initial": "AQAAAA7gDLW0D7pElQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "4f3e9bb02907aaab", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "34" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY05hY2stdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "82" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "44ea5cbc-5d51-5482-a9af-3c489da51a6d" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05hY2stdG9wLTEifQ==" + } + }, + { + "ID": "dc0ebf777aaac00f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "112" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05hY2stdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "83" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "aa3e4982-1137-5915-89e9-2976d1c387fa" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY05hY2stdG9wLTEifX0=" + } + }, + { + "ID": "49b76ce4230641e6", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "450" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljTmFjay10b3AtMVwiXG5cdFx0fVxuXHRcdF1cblx0XHR9In0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NRU1RvcGljTmFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "9f8c286c-4c9e-5e91-8819-48988c6a207e" + ] + }, + "Body": "" + } + }, + { + "ID": "91bf4e9f0db56503", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "189" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJDTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "192" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "24c1052e-a2ee-5691-af0f-65da621aa87e" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiOWFhNDY4N2M4Yjc1NjdiYWEzODBkOWYzMDBmZTI4M2EiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNZXNzYWdlSWQiOiJiYzEyMWRmMC0zMzliLTRhZGQtODU3ZS05NGMwODM3ZTM2OTUifV19" + } + }, + { + "ID": "593ce4eb63d40227", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "189" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJDTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "192" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "a9bd8d6c-a881-5348-80df-ed9868757da7" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiMzE0Yzc3YjI0OTg5M2M2YjNjNzY1YTQyY2MwOGIyNDUiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNZXNzYWdlSWQiOiJlOGJlNmQyMi04YjU1LTRkM2EtOTE4Ny00Yjg0Y2RjMTE3MWEifV19" + } + }, + { + "ID": "e92ba6f7bbd6b833", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05hY2stdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "845" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "c6b53a80-73ee-53c4-8c9c-5a74b31aed2b" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3NjgzMiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc2NzY4In0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiMzE0Yzc3YjI0OTg5M2M2YjNjNzY1YTQyY2MwOGIyNDUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIxIn19LCJNZXNzYWdlSWQiOiJlOGJlNmQyMi04YjU1LTRkM2EtOTE4Ny00Yjg0Y2RjMTE3MWEiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlpkam5NMVpYMFBDbkpmTDRPRGZlZnVmUzkvZ2pmZWh5SDMyTEpmOXRTSys2UWtWdG9lWjRRd25hdld6ZzBmQXUrdVY5N0lhUUk2S2tWbWtHamd5SlJIeE00cXZkZWVpOGZtNGhpeXI5SzVXUTQyT3d4RWFod09NZXErVEYwRTk0WDlhVWVSbmhJYkNPVGxpdk5RMmxjVlBOK0ZmbElSNWNtdlVWdXErbDBCelduOUtSQldteHZVeVdjV0dHRDcxTGxUY1NHbzJReDZnTUpSZHhORU5xRWlXNFMxSW1MclBGKzZrR3JwN3NSVmJUcTNwTlpZa1dsWmJ2dmZQMWQzakNLYXQzNzdoRm9GWVdFOVhwcWFzTE03WVhCVldLbmUvTmVVUGhlZWNwd2lyVUtXYnp2a0dPaEJDZGRxdHB2SSs0dFlOUzY0YVJqSXFibzU4Ry92NEVxRjBtWDdtS2liYm5pR05SNC9SUGIrVWRQakg5bU5UTUFYQW5wTXU4TDBOa3J0aThSWWdEN2hvSlkweWZCSmxwbWc9PSJ9XX0=" + } + }, + { + "ID": "5c5baaf359547c5d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05hY2stdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "845" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "14dc0eae-3b10-5b7c-8997-6e5afbe47593" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3Njg5NiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc2NzAxIn0sIkJvZHkiOiIwIiwiTUQ1T2ZCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiOWFhNDY4N2M4Yjc1NjdiYWEzODBkOWYzMDBmZTI4M2EiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIwIn19LCJNZXNzYWdlSWQiOiJiYzEyMWRmMC0zMzliLTRhZGQtODU3ZS05NGMwODM3ZTM2OTUiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmVjYjYwdjAycnRCRUtuaDlaZGFzd0gySUVTTFFEOXB5N05aVmJWdGMzL0k4RnNSOHN3SXFyOWRLbGhYQ0N2WVJMV2Y0U1N6M3hqSldoekNGTW55UzFNS2FXSXI2djVXeHpocU43NW5Nd1ArYk0yVGR1WHI3M2tNL240TkRzc3lWOGI4NWx6SDFtUnhoSUdoVXBxUFludHIwNlBlRUNTMC8xNldDcFBPKzEvallnQzVKb0VpS0M3cm1HWitRNGFSTVpUVDk5c3lvcXhaUFNoM2VHd0F5Rmk5Mzg3S1NXQ0lkZWpwblVyYmR0R0hpZEdGVUtkMXVrWWRId2dQRmFPNm9zdk42RFY4OXZTdE9qOWpZODcxVmU4dHBxNldrOUhYTWtTWlRzZzRhUmRKVDgyR2YzNlA4Y2F0eWFrQURXSnlqeGYzWmtZVlR0WVRBaEdrUjZzRmoxbFdRZUtiYlRpNnkxWkVZMmRkcStqWnpYZ1l1MlJNOFdjSS96QytZSVRKdGZZdjQ0ZGY1QVl0aHFaR1R2dUc1eEE9PSJ9XX0=" + } + }, + { + "ID": "5a3b1e01f9d0210d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "558" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ChangeMessageVisibilityBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQlpkam5NMVpYMFBDbkpmTDRPRGZlZnVmUzkvZ2pmZWh5SDMyTEpmOXRTSys2UWtWdG9lWjRRd25hdld6ZzBmQXUrdVY5N0lhUUk2S2tWbWtHamd5SlJIeE00cXZkZWVpOGZtNGhpeXI5SzVXUTQyT3d4RWFod09NZXErVEYwRTk0WDlhVWVSbmhJYkNPVGxpdk5RMmxjVlBOK0ZmbElSNWNtdlVWdXErbDBCelduOUtSQldteHZVeVdjV0dHRDcxTGxUY1NHbzJReDZnTUpSZHhORU5xRWlXNFMxSW1MclBGKzZrR3JwN3NSVmJUcTNwTlpZa1dsWmJ2dmZQMWQzakNLYXQzNzdoRm9GWVdFOVhwcWFzTE03WVhCVldLbmUvTmVVUGhlZWNwd2lyVUtXYnp2a0dPaEJDZGRxdHB2SSs0dFlOUzY0YVJqSXFibzU4Ry92NEVxRjBtWDdtS2liYm5pR05SNC9SUGIrVWRQakg5bU5UTUFYQW5wTXU4TDBOa3J0aThSWWdEN2hvSlkweWZCSmxwbWc9PSIsIlZpc2liaWxpdHlUaW1lb3V0IjoxfV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NRU1RvcGljTmFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "3715793b-08be-5288-8f81-19cfc84adc67" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "5fdf8a8c09274371", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05hY2stdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:57 GMT" + ], + "X-Amzn-Requestid": [ + "d03008ec-12bd-56a0-87a2-6818d248684f" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "867d7e2e28b45a34", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "558" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ChangeMessageVisibilityBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmVjYjYwdjAycnRCRUtuaDlaZGFzd0gySUVTTFFEOXB5N05aVmJWdGMzL0k4RnNSOHN3SXFyOWRLbGhYQ0N2WVJMV2Y0U1N6M3hqSldoekNGTW55UzFNS2FXSXI2djVXeHpocU43NW5Nd1ArYk0yVGR1WHI3M2tNL240TkRzc3lWOGI4NWx6SDFtUnhoSUdoVXBxUFludHIwNlBlRUNTMC8xNldDcFBPKzEvallnQzVKb0VpS0M3cm1HWitRNGFSTVpUVDk5c3lvcXhaUFNoM2VHd0F5Rmk5Mzg3S1NXQ0lkZWpwblVyYmR0R0hpZEdGVUtkMXVrWWRId2dQRmFPNm9zdk42RFY4OXZTdE9qOWpZODcxVmU4dHBxNldrOUhYTWtTWlRzZzRhUmRKVDgyR2YzNlA4Y2F0eWFrQURXSnlqeGYzWmtZVlR0WVRBaEdrUjZzRmoxbFdRZUtiYlRpNnkxWkVZMmRkcStqWnpYZ1l1MlJNOFdjSS96QytZSVRKdGZZdjQ0ZGY1QVl0aHFaR1R2dUc1eEE9PSIsIlZpc2liaWxpdHlUaW1lb3V0IjoxfV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1NRU1RvcGljTmFjay10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:57 GMT" + ], + "X-Amzn-Requestid": [ + "e0aceec7-8769-5237-ae51-8e33479c0cd8" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "87e4a8ee25b92760", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05hY2stdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:57 GMT" + ], + "X-Amzn-Requestid": [ + "96340371-17de-5379-94af-6385d72bed96" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "2e0d921a81e29a0e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05hY2stdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:57 GMT" + ], + "X-Amzn-Requestid": [ + "df78ebba-b35a-5256-947d-8b4e73affcb9" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "5b256e2bcc14241d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05hY2stdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "845" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:58 GMT" + ], + "X-Amzn-Requestid": [ + "b5e5a0d4-7f17-52b6-a8c3-c020bfe1ac59" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3NjgzMiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMiIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc2NzY4In0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiMzE0Yzc3YjI0OTg5M2M2YjNjNzY1YTQyY2MwOGIyNDUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIxIn19LCJNZXNzYWdlSWQiOiJlOGJlNmQyMi04YjU1LTRkM2EtOTE4Ny00Yjg0Y2RjMTE3MWEiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkVGUFJKNUtKUHU0bmxuWkxCQmZ0UzRBdDRwcXBUZXFWTzhsazY4MzdPbERJUWsrS2VOR2ZkQitaZUg4WWttdHlEdlEyQUFmNGdFamVZQjZyVVJnek9tbnpKNFRvZktwbnFuYzhLbkdBWDJPdEhsVjBZaWZoTHZlM3RiSzErVnJJWXJybmVoWS9JRm1xWHZZNi9SSnVvcktPUTVoZVZocnEzaWVldjE4S1pERStHRlZjMHVIRHpzejN2RnVMSzd4RU14aEtIN1V0Zlg3aC8zNU5sZkV6RjdHcGxmekRHOGF5MHNyb2xsUGdEU1Jja0JUUSt0ZElGVDlSMzc2WjQraGViZ3ZWS0VmY1lucGQyVHpVdmNpc2ZMNW0vR2QvSTB6TXlHaitadTJ5RXFIZklwbTV3TWVSM1k4amNKOXNJb2MxcW95N1J5Z2RnWlJRWFVwUUZKRHdtbWpueDZBei9YRlV3a0hLWmNqdStkVDQyRnVxL0VhcENmUG03SnJYY1BOOCtGTGlkNHhRaVpiNnZYVkUzNFV6ZHc9PSJ9XX0=" + } + }, + { + "ID": "14bc2f2d65fb6a5a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05hY2stdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "845" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:58 GMT" + ], + "X-Amzn-Requestid": [ + "bd701d21-4b71-557e-8105-7dd58b876b91" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3Njg5NiIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMiIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc2NzAxIn0sIkJvZHkiOiIwIiwiTUQ1T2ZCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiOWFhNDY4N2M4Yjc1NjdiYWEzODBkOWYzMDBmZTI4M2EiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIwIn19LCJNZXNzYWdlSWQiOiJiYzEyMWRmMC0zMzliLTRhZGQtODU3ZS05NGMwODM3ZTM2OTUiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQndxRjFOOW9UcHpJN1BDNzVKR2dra2FWNXVYWU1id3hKS2w5WlNpck82NFVXVSsyQjBKeXlDTDR6dlcyTmJsL090WEdkQUxKaVo4UzBZWXF0a0FFK2R4RkdRZ2F1c3NiSlZwekRta2t0SW53a3RMMUltR1dpOXJvRXdxOWptSGtGV2ErV1ZUZ1NzRTJyWC91VVo1VkVhZFM5c1JBVE9ZMDd0aXMreFJkclJTeDgrRjkxc2hyczVJMkJsVlVNTG5DRE1CSHlWV0ZmN2U1MkxoemdMQUNYVExscnZOOFZOM3krWm56YUZhajg4YTNVQkFBRkVVOHo1aHJRNEpZaHhZa3kyeTRiVEUxd0xtQjZFWXMySWhhQTVrQnJvb0FMRUx6NHNwYkJIQ21Ia1BHUjFyaHVEeURBRFYrZ1lXRXVnU0lNdCthbzVSUzFCNlNuSTNLUW9admJYSXFzR2VoaVdnNUJDTVI0RXlmZTJNaUIyQ2h6c3hveHB1MnREQ1dueVk5eWt4WjlBWnNJS3J5UG83a24vcHZCemc9PSJ9XX0=" + } + }, + { + "ID": "2f1468c5b3bc7a0a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "536" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkVGUFJKNUtKUHU0bmxuWkxCQmZ0UzRBdDRwcXBUZXFWTzhsazY4MzdPbERJUWsrS2VOR2ZkQitaZUg4WWttdHlEdlEyQUFmNGdFamVZQjZyVVJnek9tbnpKNFRvZktwbnFuYzhLbkdBWDJPdEhsVjBZaWZoTHZlM3RiSzErVnJJWXJybmVoWS9JRm1xWHZZNi9SSnVvcktPUTVoZVZocnEzaWVldjE4S1pERStHRlZjMHVIRHpzejN2RnVMSzd4RU14aEtIN1V0Zlg3aC8zNU5sZkV6RjdHcGxmekRHOGF5MHNyb2xsUGdEU1Jja0JUUSt0ZElGVDlSMzc2WjQraGViZ3ZWS0VmY1lucGQyVHpVdmNpc2ZMNW0vR2QvSTB6TXlHaitadTJ5RXFIZklwbTV3TWVSM1k4amNKOXNJb2MxcW95N1J5Z2RnWlJRWFVwUUZKRHdtbWpueDZBei9YRlV3a0hLWmNqdStkVDQyRnVxL0VhcENmUG03SnJYY1BOOCtGTGlkNHhRaVpiNnZYVkUzNFV6ZHc9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU1FTVG9waWNOYWNrLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:58 GMT" + ], + "X-Amzn-Requestid": [ + "72fcc875-2dc8-543a-a0b7-a881ed3e0456" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "42ae52798a84d485", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "536" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQndxRjFOOW9UcHpJN1BDNzVKR2dra2FWNXVYWU1id3hKS2w5WlNpck82NFVXVSsyQjBKeXlDTDR6dlcyTmJsL090WEdkQUxKaVo4UzBZWXF0a0FFK2R4RkdRZ2F1c3NiSlZwekRta2t0SW53a3RMMUltR1dpOXJvRXdxOWptSGtGV2ErV1ZUZ1NzRTJyWC91VVo1VkVhZFM5c1JBVE9ZMDd0aXMreFJkclJTeDgrRjkxc2hyczVJMkJsVlVNTG5DRE1CSHlWV0ZmN2U1MkxoemdMQUNYVExscnZOOFZOM3krWm56YUZhajg4YTNVQkFBRkVVOHo1aHJRNEpZaHhZa3kyeTRiVEUxd0xtQjZFWXMySWhhQTVrQnJvb0FMRUx6NHNwYkJIQ21Ia1BHUjFyaHVEeURBRFYrZ1lXRXVnU0lNdCthbzVSUzFCNlNuSTNLUW9admJYSXFzR2VoaVdnNUJDTVI0RXlmZTJNaUIyQ2h6c3hveHB1MnREQ1dueVk5eWt4WjlBWnNJS3J5UG83a24vcHZCemc9PSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU1FTVG9waWNOYWNrLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:58 GMT" + ], + "X-Amzn-Requestid": [ + "caecc6a9-58b6-5aed-a768-a65d9840fa81" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "12b4ad66fa8d20af", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "82" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05hY2stdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:58 GMT" + ], + "X-Amzn-Requestid": [ + "5e47feb0-d88a-5d00-8420-9e44187c2d6c" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay new file mode 100644 index 000000000..80898695c --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay @@ -0,0 +1,108 @@ +{ + "Initial": "AQAAAA7gDLW5A4rRmgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "46c4b9ca20bf97c0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "165" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vdXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L25vbmV4aXN0ZW50LXN1YnNjcmlwdGlvbiJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:01 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "33718391-99c4-5f2b-b66b-e365593d4b3e" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay new file mode 100644 index 000000000..7fc59ad51 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay @@ -0,0 +1,108 @@ +{ + "Initial": "AQAAAA7gDLWwJ6fSmgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "a7ca61339e863d4b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "117" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6IiJ9XSwiUXVldWVVcmwiOiJodHRwczovL3VzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9ub25leGlzdGVudC1xdWV1ZSJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:52 GMT" + ], + "X-Amzn-Query-Error": [ + "AWS.SimpleQueueService.NonExistentQueue;Sender" + ], + "X-Amzn-Requestid": [ + "b0e1a3de-47dd-5ed0-823d-c32a872d240a" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uYXdzLnNxcyNRdWV1ZURvZXNOb3RFeGlzdCIsIm1lc3NhZ2UiOiJUaGUgc3BlY2lmaWVkIHF1ZXVlIGRvZXMgbm90IGV4aXN0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNonUTF8MessageBody.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNonUTF8MessageBody.replay new file mode 100644 index 000000000..7216bc82a --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestNonUTF8MessageBody.replay @@ -0,0 +1,453 @@ +{ + "Initial": "AQAAAA7gDLWxMNcYPgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "59580386c9b7c418", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "48" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY05vblVURjhNZXNzYWdlQm9keS10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "96" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:54 GMT" + ], + "X-Amzn-Requestid": [ + "c6575963-69f9-58ba-bee0-3997a90b70ca" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05vblVURjhNZXNzYWdlQm9keS10b3AtMSJ9" + } + }, + { + "ID": "b17713150fa08555", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "126" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05vblVURjhNZXNzYWdlQm9keS10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "97" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:54 GMT" + ], + "X-Amzn-Requestid": [ + "8ce493f5-0b48-5948-91d8-f301cbba8138" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY05vblVURjhNZXNzYWdlQm9keS10b3AtMSJ9fQ==" + } + }, + { + "ID": "479569c4e5fc6b1e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "478" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljTm9uVVRGOE1lc3NhZ2VCb2R5LXRvcC0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU1FTVG9waWNOb25VVEY4TWVzc2FnZUJvZHktdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:54 GMT" + ], + "X-Amzn-Requestid": [ + "36e20d14-3ce7-5aab-bce5-6de0fc1552db" + ] + }, + "Body": "" + } + }, + { + "ID": "11c9f9957d11081a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "497" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJDTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "192" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:54 GMT" + ], + "X-Amzn-Requestid": [ + "c9f0086d-59b6-58a0-abb1-6899994490d0" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiZDk2Mjk2YWM2NzdhOWFjYTA1ZDQ5YWUwOTljNjU2YzAiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiMDBhYjg5OTZlODAxMWE3YTE0ZmI2ZmI5YWQ4M2M4MjAiLCJNZXNzYWdlSWQiOiJjZDUyMzUzMi1jZmEzLTQwZTEtYmU2MS00MWZhZjUxYzdmZTMifV19" + } + }, + { + "ID": "a69f2f7ba83a29c6", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "177" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05vblVURjhNZXNzYWdlQm9keS10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1159" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:54 GMT" + ], + "X-Amzn-Requestid": [ + "ee8f07c2-11a6-5eb7-b89b-6736d15426c7" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3NDMxNyIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc0MjQ5In0sIkJvZHkiOiJBQUVDQXdRRkJnY0lDUW9MREEwT0R4QVJFaE1VRlJZWEdCa2FHeHdkSGg4Z0lTSWpKQ1VtSnlncEtpc3NMUzR2T2pzOFBUNC9RRnRjWFY1ZllIdDhmWDUvWm05dlhHSmhjbHhpWVhvdUxseG1iMjljTGk1Y1ltRnlYQzR1WEM0dVhHSmhlaTR1WEM0dUwyWnZieTh1TGk5aVlYSXZMaTR2TGk0dlltRjZMaTR2Wm05dkwySmhjaTlpWVhwbWIyOGlZbUZ5SW1KaGVpNHVYR1p2YjF4Y1ltRnlYRnhjWW1GNlptOXZMeTlpWVhJdkx5OWlZWHBtYjI4Z1ltRnlJR0poZWpFeU16UTE0cGk2NHBpNjRwaTZ2Ykk9IiwiTUQ1T2ZCb2R5IjoiMDBhYjg5OTZlODAxMWE3YTE0ZmI2ZmI5YWQ4M2M4MjAiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiZDk2Mjk2YWM2NzdhOWFjYTA1ZDQ5YWUwOTljNjU2YzAiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJiYXNlNjRlbmNvZGVkIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiJ0cnVlIn19LCJNZXNzYWdlSWQiOiJjZDUyMzUzMi1jZmEzLTQwZTEtYmU2MS00MWZhZjUxYzdmZTMiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnNlUGZLazVHYVI0aWFBM0RINGR2RWNaa1hNL0ZPTVhacmdJTFdaczZ3dTZoM3RIK2UwVWJXVzlmTU1DU3dsdHR3dHlKb0Vaakl6eXZrUWY0ampRWnBhZ0xKYkltbU9FVlRRWGNmSTVHZ1F0dVZVakxsQ0h0T0Rid2VTTzJVVXA4NllvTG5qd1Zhb0NMUElXdDZlcGowYklPaUl3TzVEOE0ySHVpK0JCTVdxVkg3dkhWQy9DUmUrTDdrcDRLNzVkc1ltb2V3djhTMUZFenB0czhHZDExWHY4ZFBqRG8rbkc2NGlqTGVKNVovN0VOaGtTeTlSMFQxUDc5MUpOSlMvMTczb24wT0tkMHJBUDBCWUU4VVRKMVRkM21TYVQxc2pvSVcwZ3NRcXVWelNzTS9hNUx0elJVcDR3bktMMXVFTjU0azEvSXkxR2NoUC9jZXlxMGhtcG5UaW9lT0VCbXJpSnh6QjVZMEdLWTBwcWVxcHo5WlBUcG5WV1p4a01YOFYwc1RwSWZEdXd2dml0b3JZeDdKZndNV3Mxekdjbm5yUWIrUXozOEY2MUV6eHc9In1dfQ==" + } + }, + { + "ID": "4159d7ca75863f69", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "570" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnNlUGZLazVHYVI0aWFBM0RINGR2RWNaa1hNL0ZPTVhacmdJTFdaczZ3dTZoM3RIK2UwVWJXVzlmTU1DU3dsdHR3dHlKb0Vaakl6eXZrUWY0ampRWnBhZ0xKYkltbU9FVlRRWGNmSTVHZ1F0dVZVakxsQ0h0T0Rid2VTTzJVVXA4NllvTG5qd1Zhb0NMUElXdDZlcGowYklPaUl3TzVEOE0ySHVpK0JCTVdxVkg3dkhWQy9DUmUrTDdrcDRLNzVkc1ltb2V3djhTMUZFenB0czhHZDExWHY4ZFBqRG8rbkc2NGlqTGVKNVovN0VOaGtTeTlSMFQxUDc5MUpOSlMvMTczb24wT0tkMHJBUDBCWUU4VVRKMVRkM21TYVQxc2pvSVcwZ3NRcXVWelNzTS9hNUx0elJVcDR3bktMMXVFTjU0azEvSXkxR2NoUC9jZXlxMGhtcG5UaW9lT0VCbXJpSnh6QjVZMEdLWTBwcWVxcHo5WlBUcG5WV1p4a01YOFYwc1RwSWZEdXd2dml0b3JZeDdKZndNV3Mxekdjbm5yUWIrUXozOEY2MUV6eHc9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05vblVURjhNZXNzYWdlQm9keS10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:54 GMT" + ], + "X-Amzn-Requestid": [ + "56a458b4-087f-5818-b456-3840c88d5068" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "bf6a8b93c697b75c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "96" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY05vblVURjhNZXNzYWdlQm9keS10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:54 GMT" + ], + "X-Amzn-Requestid": [ + "17e17523-a542-5f48-a892-15d765b09738" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestSendReceive.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestSendReceive.replay new file mode 100644 index 000000000..6681fff20 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestSendReceive.replay @@ -0,0 +1,801 @@ +{ + "Initial": "AQAAAA7gDLWyHeqjPgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "9a1cd726f21fb7bd", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "41" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "89" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:54 GMT" + ], + "X-Amzn-Requestid": [ + "5ae9e132-339e-5590-b021-81c6f36c0103" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn0=" + } + }, + { + "ID": "00a6b9a6f55a5dcc", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "119" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "90" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:54 GMT" + ], + "X-Amzn-Requestid": [ + "c006cac6-10ee-5719-ace7-aa32d01cb38a" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn19" + } + }, + { + "ID": "7f247e13e0fdd68f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "464" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljU2VuZFJlY2VpdmUtdG9wLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:54 GMT" + ], + "X-Amzn-Requestid": [ + "3d83bc03-c165-51a1-a4a7-dcf701979532" + ] + }, + "Body": "" + } + }, + { + "ID": "aa06e0ea9784ea3e", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "196" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJDTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "192" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:54 GMT" + ], + "X-Amzn-Requestid": [ + "66379a6d-3235-5d38-ba8e-fa99f2c709ab" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiOWFhNDY4N2M4Yjc1NjdiYWEzODBkOWYzMDBmZTI4M2EiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNZXNzYWdlSWQiOiJjZGI0Y2ZmZC0wNjdjLTQ4Y2ItOTY1Yi1kOGM1ZDdiMjhkZDYifV19" + } + }, + { + "ID": "995452f0299260ab", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "196" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJDTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "192" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "4379756b-926a-52e3-a849-159f5298f670" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiMzE0Yzc3YjI0OTg5M2M2YjNjNzY1YTQyY2MwOGIyNDUiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNZXNzYWdlSWQiOiI3YjJhZjE0Yy01OGFmLTQ2ZjYtOWNjNi00OGRhMjNhNDNkZjkifV19" + } + }, + { + "ID": "be3d670aa25adf59", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "196" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJDTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "192" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "957c99f8-b712-530b-b382-f90c77e11798" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiYjcyZTE0MGU3MjY5ZWJjZTkxMDdiYWYxZWYyNDBiYWUiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiYzgxZTcyOGQ5ZDRjMmY2MzZmMDY3Zjg5Y2MxNDg2MmMiLCJNZXNzYWdlSWQiOiI3MzExNWZiZS1iMTg5LTRhYzktYmUwOS1mZDhjMDFkYmVlYzUifV19" + } + }, + { + "ID": "0000fc09ded89e49", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "6f8a576e-08f5-5e63-9db2-379ac8063af0" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3NTEyOCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc0OTMwIn0sIkJvZHkiOiIwIiwiTUQ1T2ZCb2R5IjoiY2ZjZDIwODQ5NWQ1NjVlZjY2ZTdkZmY5Zjk4NzY0ZGEiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiOWFhNDY4N2M4Yjc1NjdiYWEzODBkOWYzMDBmZTI4M2EiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIwIn19LCJNZXNzYWdlSWQiOiJjZGI0Y2ZmZC0wNjdjLTQ4Y2ItOTY1Yi1kOGM1ZDdiMjhkZDYiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjZQcXRYRkhDenBSRmovemcwNFFuRE9BbDlPcCsxUG15aHpLMks3MEVlNk5IWUE1aTA3cUtJS0pNcjFNYzQ1TGNwb25lOWY3L1BEQ2MrZHB6VjR4LzNYd2RzMCt3MVlFeVVDbmQvVEhDd3UvSUgxSnBFMHUybDhIZzNwRVU3bzYzWnNlTnZlNy9NKy9jNEUyNjdKSndma2dzN3F0L2IzNXM0YmFOektMT0pRczhxV2grYnV3cGJiLy94VENVeG15T3pQZUFuR3hoSmhaWEZhR0hJbFd6VVFlNklmZVhBR1B2Si9ITnBLbVBOTGo1ZkxNK1hiZ0NPOWt3anhDa1lPc3l4anNZZUdXWWRIU1dPSlcwV2dSa2F5dEp4WUxaVHVqME5FR0I0RFZPVFQvd253Qkc1S0JMWkczWTRFa1Y3RnJ5MVRXQlhYa3JqYmhzMGZQSTM0QzB1SUVxamdUNnltOTRvQi9Cam9WV2dNZk1UR0ZnUXNsZmtBenZvczR0bG9RVXd5dWVkaS9OUERpNnEvNFVDc3hyOUZzcTgvbXhYbHN2dHZhOHVWY0N6a0U9In1dfQ==" + } + }, + { + "ID": "a64fb15b9cdf4231", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "31ec32c8-bcdb-5d81-ba23-523c7c284912" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3NTE5MCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc1MDY2In0sIkJvZHkiOiIyIiwiTUQ1T2ZCb2R5IjoiYzgxZTcyOGQ5ZDRjMmY2MzZmMDY3Zjg5Y2MxNDg2MmMiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiYjcyZTE0MGU3MjY5ZWJjZTkxMDdiYWYxZWYyNDBiYWUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIyIn19LCJNZXNzYWdlSWQiOiI3MzExNWZiZS1iMTg5LTRhYzktYmUwOS1mZDhjMDFkYmVlYzUiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnlRTHVjTjV5U2g3ZzhPcVNQeWlqN0Y5cDRPaGZUVVNXZWVjNXVGVDdVUVlvajdjbHlQeVg1Y2NwRWJOdW1keGduZlZjRnJvVlJtNm8zQk9vYXJWRkhhVG5DZnBHU1k4cTIvUlROVEFWbHppNWxVSUwyZWNZbFA5dG1tOTYzLzE2NjJQWHJNazVmUDVac1M2ZUxnV1Fyem85TkVDTzNiMEtCZlVpZVRxamlIdG9FRy9yS04rVlJ5UTByeHFTTU9PZk9IRVFiNnRyc0J1M013QnpydEQ2UDI4VXdzRXl4bUlza1VSVS9mdDV0SStGN2VsZGZFNFNhellFNzhCcEsreEVDZ2phbTVKUWhGTjFDem1ueGxtbk9KU2d2enkvdW5XbHBxUHhXK2hPSWJWSDJZU2lxbnF0cGFWTXhaYzhiTVB4QkhoZUI5ZlJWWWFoU3l0TXZWQW1aN0lHT0ROMkJrTk82V0FTT3VETGQrd0gyZE5FVUpFalpiZXlEMEFQMmswVDdiOEZOODR6ekM0RmhXMWk4akdKaUtSQ0RGN0lUaEZhYjF5WGhEZnJhVnc9In1dfQ==" + } + }, + { + "ID": "c2b707353cea09a1", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "563" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQjZQcXRYRkhDenBSRmovemcwNFFuRE9BbDlPcCsxUG15aHpLMks3MEVlNk5IWUE1aTA3cUtJS0pNcjFNYzQ1TGNwb25lOWY3L1BEQ2MrZHB6VjR4LzNYd2RzMCt3MVlFeVVDbmQvVEhDd3UvSUgxSnBFMHUybDhIZzNwRVU3bzYzWnNlTnZlNy9NKy9jNEUyNjdKSndma2dzN3F0L2IzNXM0YmFOektMT0pRczhxV2grYnV3cGJiLy94VENVeG15T3pQZUFuR3hoSmhaWEZhR0hJbFd6VVFlNklmZVhBR1B2Si9ITnBLbVBOTGo1ZkxNK1hiZ0NPOWt3anhDa1lPc3l4anNZZUdXWWRIU1dPSlcwV2dSa2F5dEp4WUxaVHVqME5FR0I0RFZPVFQvd253Qkc1S0JMWkczWTRFa1Y3RnJ5MVRXQlhYa3JqYmhzMGZQSTM0QzB1SUVxamdUNnltOTRvQi9Cam9WV2dNZk1UR0ZnUXNsZmtBenZvczR0bG9RVXd5dWVkaS9OUERpNnEvNFVDc3hyOUZzcTgvbXhYbHN2dHZhOHVWY0N6a0U9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "455e84e4-7cdf-5d8a-aa71-e410bc2cf919" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "117f3c09c8dd4527", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "170" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "865" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "22612d7a-f6cf-508a-87db-4d8e363cf419" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3NTMxMCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc1MDAwIn0sIkJvZHkiOiIxIiwiTUQ1T2ZCb2R5IjoiYzRjYTQyMzhhMGI5MjM4MjBkY2M1MDlhNmY3NTg0OWIiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiMzE0Yzc3YjI0OTg5M2M2YjNjNzY1YTQyY2MwOGIyNDUiLCJNZXNzYWdlQXR0cmlidXRlcyI6eyJhIjp7IkRhdGFUeXBlIjoiU3RyaW5nIiwiU3RyaW5nVmFsdWUiOiIxIn19LCJNZXNzYWdlSWQiOiI3YjJhZjE0Yy01OGFmLTQ2ZjYtOWNjNi00OGRhMjNhNDNkZjkiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQk9ob1BHNGpoSFBtT0RNcXArUDFtSmd3Ym5odkFJUE1FbTNoRjNXQ2lvckErRU5nNVJDS2pQTXk1MnV5SlJGZ1o3Mk8xSEZhV0xuK2pjWUFFYjloVFRkd2pkQS9LMmVXbnRxVlcwMkxtNUJWMVZlYWNIWjk5UjlvVFB3QVp4eUtXRmpNQXU2K1doZEtjdENOUEJUTzlQdXljcUNzb3lLYVNFVFFPMXlpZGJMdGdKVURGQ2ZHVXJSUFJwS0ltZEp6am04V2lVYi9KZ3V5V0U0TUpUaXZCbkVuNzlVMWE1S2NGRGJDeTV2UUVmZ2ZDYmtGanJ2VHFmUmVSeVVRZTM1Nk9nRHFyakx5SERiL1ZRRW5oTTBvOCtvSG9BOU55MWtFeGoxK1gra01uWkc5a3pqN0s3VzdLSzFibHFyZXBaY1RvMXFKZzRpVHdCMm11NEJPaXI5Zk4wWXFkVkphWjBmb3lOSlJKQ0sxZXFRckxwVlNrTmgvaERleHE2ZUJXeUpDbVJNYTBqaXBXYnh1dWhzbGszYmlmUVFySVJRYkJpVGVDblZ5YllFNjhRems9In1dfQ==" + } + }, + { + "ID": "90a299cadc064f0a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "563" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnlRTHVjTjV5U2g3ZzhPcVNQeWlqN0Y5cDRPaGZUVVNXZWVjNXVGVDdVUVlvajdjbHlQeVg1Y2NwRWJOdW1keGduZlZjRnJvVlJtNm8zQk9vYXJWRkhhVG5DZnBHU1k4cTIvUlROVEFWbHppNWxVSUwyZWNZbFA5dG1tOTYzLzE2NjJQWHJNazVmUDVac1M2ZUxnV1Fyem85TkVDTzNiMEtCZlVpZVRxamlIdG9FRy9yS04rVlJ5UTByeHFTTU9PZk9IRVFiNnRyc0J1M013QnpydEQ2UDI4VXdzRXl4bUlza1VSVS9mdDV0SStGN2VsZGZFNFNhellFNzhCcEsreEVDZ2phbTVKUWhGTjFDem1ueGxtbk9KU2d2enkvdW5XbHBxUHhXK2hPSWJWSDJZU2lxbnF0cGFWTXhaYzhiTVB4QkhoZUI5ZlJWWWFoU3l0TXZWQW1aN0lHT0ROMkJrTk82V0FTT3VETGQrd0gyZE5FVUpFalpiZXlEMEFQMmswVDdiOEZOODR6ekM0RmhXMWk4akdKaUtSQ0RGN0lUaEZhYjF5WGhEZnJhVnc9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "c32b0c0c-cd68-5f1e-82f3-6cf80d9b98ee" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "ff8e927a6821b9ba", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "563" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQk9ob1BHNGpoSFBtT0RNcXArUDFtSmd3Ym5odkFJUE1FbTNoRjNXQ2lvckErRU5nNVJDS2pQTXk1MnV5SlJGZ1o3Mk8xSEZhV0xuK2pjWUFFYjloVFRkd2pkQS9LMmVXbnRxVlcwMkxtNUJWMVZlYWNIWjk5UjlvVFB3QVp4eUtXRmpNQXU2K1doZEtjdENOUEJUTzlQdXljcUNzb3lLYVNFVFFPMXlpZGJMdGdKVURGQ2ZHVXJSUFJwS0ltZEp6am04V2lVYi9KZ3V5V0U0TUpUaXZCbkVuNzlVMWE1S2NGRGJDeTV2UUVmZ2ZDYmtGanJ2VHFmUmVSeVVRZTM1Nk9nRHFyakx5SERiL1ZRRW5oTTBvOCtvSG9BOU55MWtFeGoxK1gra01uWkc5a3pqN0s3VzdLSzFibHFyZXBaY1RvMXFKZzRpVHdCMm11NEJPaXI5Zk4wWXFkVkphWjBmb3lOSlJKQ0sxZXFRckxwVlNrTmgvaERleHE2ZUJXeUpDbVJNYTBqaXBXYnh1dWhzbGszYmlmUVFySVJRYkJpVGVDblZ5YllFNjhRems9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "ab33bf2d-7914-5294-97c8-dfd9b9e7ea67" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "10a118df98426aff", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "89" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlLXRvcC0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "73c2a2c8-5805-5c45-bb0d-c23c98f6e1ca" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestSendReceiveJSON.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestSendReceiveJSON.replay new file mode 100644 index 000000000..fc3f1e9e9 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestSendReceiveJSON.replay @@ -0,0 +1,453 @@ +{ + "Initial": "AQAAAA7gDLWzI3WcqAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "982fc2fe75c859b4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "45" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJTUVNUb3BpY1NlbmRSZWNlaXZlSlNPTi10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "93" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "ccd07835-9c86-5499-8bb7-18c15c75ec6a" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlSlNPTi10b3AtMSJ9" + } + }, + { + "ID": "38cf65f9bd571ffd", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "123" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlSlNPTi10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "94" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "96e22086-600b-570e-b916-4072a0f80ffd" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpTUVNUb3BpY1NlbmRSZWNlaXZlSlNPTi10b3AtMSJ9fQ==" + } + }, + { + "ID": "349a1a96abacd0ab", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "472" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlNRU1RvcGljU2VuZFJlY2VpdmVKU09OLXRvcC0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU1FTVG9waWNTZW5kUmVjZWl2ZUpTT04tdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:55 GMT" + ], + "X-Amzn-Requestid": [ + "de5bf5ad-5393-57f1-8f24-955993603f02" + ] + }, + "Body": "" + } + }, + { + "ID": "2fd9e7133d32eeca", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "151" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6IntcIkZvb1wiOiBcIkJhclwifSJ9XSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvU1FTVG9waWNTZW5kUmVjZWl2ZUpTT04tdG9wLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "132" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "68830858-2775-57e0-aa98-68ace781bf13" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiMzMzMzk5YmEyYjc2YTE5NjQzMjYwN2YyM2IzZWNiOTUiLCJNZXNzYWdlSWQiOiI4OTZlN2M5Ny01MWJkLTQ2NjQtOGNiMy01MDA4YmZhNDAwOTQifV19" + } + }, + { + "ID": "34b87e233ebf873b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "174" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlSlNPTi10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "756" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "94b56e8a-99da-5f8c-9ebf-0e7e592eb77f" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFXVVdFVVNQVUlHQkxPNEdKRCIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY3NjA4MCIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njc2MDEyIn0sIkJvZHkiOiJ7XCJGb29cIjogXCJCYXJcIn0iLCJNRDVPZkJvZHkiOiIzMzMzOTliYTJiNzZhMTk2NDMyNjA3ZjIzYjNlY2I5NSIsIk1lc3NhZ2VJZCI6Ijg5NmU3Yzk3LTUxYmQtNDY2NC04Y2IzLTUwMDhiZmE0MDA5NCIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCcjlTM1NaZkxkVXc4cys1aFJVTXI3bHNNUWxaY1Zyb0taMS9XdzJYUW1SRlJPMEErRGZQM0hxbGo3WE5CN0hXTnYrOGcvSytJQnEwWC9TMlZHRWpPUVIyR09MU2RjeXU4aUwzT1U2REZzYVNBcEx2TzJZeXdya0ZrcFlxUnRzRVhWRFpVY0tYd05nT20xZzFQaUZzbFRjWms3TlNCbkJtU0ptWGV4T2U0RWNNOVU3Tjk5dnNmL3BlOW1WcXJzVklvT1dSN3VZZ3lWZEszV0JSZW9JL0ZRb0crRXorbXBzMkhqK0pSeEI5WUZGeXJlM0kxdzRVOHFJbzY1Y3BPejAvVFF6Q1ZFeW9BUld3cEEveWVDL1AwNklGWEFEVU1Mc2VzWTB5SldXbmxkREJLUjVHZG9OMkUrUkNOWE1RUG9Wc3M4UmdVeUdTQjRNMHJOZ0FDaXhGNGFUaFF0YUxlcnNzMHBhVGlmN05sRGJOOENOclRnSlF2L2lCVkx2N1lhN1NjVXhDRWdEY3kzVE5ESmkxZHpmVjkrakFxL0JjdUxubFJBNjdybjRhUEFORT0ifV19" + } + }, + { + "ID": "45ba0c59cf949ab8", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "567" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQnI5UzNTWmZMZFV3OHMrNWhSVU1yN2xzTVFsWmNWcm9LWjEvV3cyWFFtUkZSTzBBK0RmUDNIcWxqN1hOQjdIV052KzhnL0srSUJxMFgvUzJWR0VqT1FSMkdPTFNkY3l1OGlMM09VNkRGc2FTQXBMdk8yWXl3cmtGa3BZcVJ0c0VYVkRaVWNLWHdOZ09tMWcxUGlGc2xUY1prN05TQm5CbVNKbVhleE9lNEVjTTlVN045OXZzZi9wZTltVnFyc1ZJb09XUjd1WWd5VmRLM1dCUmVvSS9GUW9HK0V6K21wczJIaitKUnhCOVlGRnlyZTNJMXc0VThxSW82NWNwT3owL1RRekNWRXlvQVJXd3BBL3llQy9QMDZJRlhBRFVNTHNlc1kweUpXV25sZERCS1I1R2RvTjJFK1JDTlhNUVBvVnNzOFJnVXlHU0I0TTByTmdBQ2l4RjRhVGhRdGFMZXJzczBwYVRpZjdObERiTjhDTnJUZ0pRdi9pQlZMdjdZYTdTY1V4Q0VnRGN5M1ROREppMWR6ZlY5K2pBcS9CY3VMbmxSQTY3cm40YVBBTkU9In1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlSlNPTi10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "2dae32a5-377c-576f-bbbd-5251f7882f9c" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "0499bc3293b7cc2a", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "93" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9TUVNUb3BpY1NlbmRSZWNlaXZlSlNPTi10b3AtMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:37:56 GMT" + ], + "X-Amzn-Requestid": [ + "bfe6786c-be60-56de-8dd1-18987e94ae2d" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestSendReceiveTwo.replay b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestSendReceiveTwo.replay new file mode 100644 index 000000000..e6dd3b037 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestConformanceSQSTopic/TestSendReceiveTwo.replay @@ -0,0 +1,46 @@ +{ + "Initial": "AQAAAA7gDLWtO1v0OAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": null +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSNSTopic/TestSendReceiveInvalidNoDeduplicationID.replay b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSNSTopic/TestSendReceiveInvalidNoDeduplicationID.replay new file mode 100644 index 000000000..43fe92c08 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSNSTopic/TestSendReceiveInvalidNoDeduplicationID.replay @@ -0,0 +1,539 @@ +{ + "Initial": "AQAAAA7gDLW+OtHRKQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "0559de1be5a995f8", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "173" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJkF0dHJpYnV0ZXMuZW50cnkuMS5rZXk9Rmlmb1RvcGljJkF0dHJpYnV0ZXMuZW50cnkuMS52YWx1ZT10cnVlJk5hbWU9VGVzdEZJRk9TTlNUb3BpY19UZXN0U2VuZFJlY2VpdmVJbnZhbGlkTm9EZWR1cGxpY2F0aW9uSUQtdG9wLTEuZmlmbyZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "374" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:07 GMT" + ], + "X-Amzn-Requestid": [ + "816cf243-80f0-5388-8225-92b7400f3923" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vRGVkdXBsaWNhdGlvbklELXRvcC0xLmZpZm88L1RvcGljQXJuPgogIDwvQ3JlYXRlVG9waWNSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjgxNmNmMjQzLTgwZjAtNTM4OC04MjI1LTkyYjc0MDBmMzkyMzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9DcmVhdGVUb3BpY1Jlc3BvbnNlPgo=" + } + }, + { + "ID": "104c99114ba63cf6", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "78" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb0RlZHVwbGljYXRpb25JRC1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "126" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:07 GMT" + ], + "X-Amzn-Requestid": [ + "507c6f02-20ad-5ba6-b10c-0ff6e05201e9" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb0RlZHVwbGljYXRpb25JRC1zdWItMSJ9" + } + }, + { + "ID": "22ee85350fa8b103", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "156" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb0RlZHVwbGljYXRpb25JRC1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "127" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:07 GMT" + ], + "X-Amzn-Requestid": [ + "7862ce7c-830d-57cf-9d95-ae8843f23d80" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb0RlZHVwbGljYXRpb25JRC1zdWItMSJ9fQ==" + } + }, + { + "ID": "6680ed6255e7ba0b", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "538" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vRGVkdXBsaWNhdGlvbklELXN1Yi0xXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NTY3NTI2NjU1NzYvVGVzdEZJRk9TTlNUb3BpY19UZXN0U2VuZFJlY2VpdmVJbnZhbGlkTm9EZWR1cGxpY2F0aW9uSUQtc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:07 GMT" + ], + "X-Amzn-Requestid": [ + "b720ba34-6b10-5527-8dab-dac0abef7f68" + ] + }, + "Body": "" + } + }, + { + "ID": "6ff54d6e07bf83ac", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "287" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb0RlZHVwbGljYXRpb25JRC1zdWItMSZQcm90b2NvbD1zcXMmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBVGVzdEZJRk9TTlNUb3BpY19UZXN0U2VuZFJlY2VpdmVJbnZhbGlkTm9EZWR1cGxpY2F0aW9uSUQtdG9wLTEuZmlmbyZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "417" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:07 GMT" + ], + "X-Amzn-Requestid": [ + "8e1b8ed3-392e-570c-9ad0-ee27f9d11da7" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vRGVkdXBsaWNhdGlvbklELXRvcC0xLmZpZm86NDQyZTE0MjgtMjM5My00OTg1LWFiNTItNTNmNWRkZDQ1OTY1PC9TdWJzY3JpcHRpb25Bcm4+CiAgPC9TdWJzY3JpYmVSZXN1bHQ+CiAgPFJlc3BvbnNlTWV0YWRhdGE+CiAgICA8UmVxdWVzdElkPjhlMWI4ZWQzLTM5MmUtNTcwYy05YWQwLWVlMjdmOWQxMWRhNzwvUmVxdWVzdElkPgogIDwvUmVzcG9uc2VNZXRhZGF0YT4KPC9TdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "fa35d8216f62df25", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "257" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9aGVsbG8rd29ybGQmVG9waWNBcm49YXJuJTNBYXdzJTNBc25zJTNBdXMtZWFzdC0yJTNBNDU2NzUyNjY1NTc2JTNBVGVzdEZJRk9TTlNUb3BpY19UZXN0U2VuZFJlY2VpdmVJbnZhbGlkTm9EZWR1cGxpY2F0aW9uSUQtdG9wLTEuZmlmbyZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "322" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:07 GMT" + ], + "X-Amzn-Requestid": [ + "283217b6-b323-503d-aca0-774273dcca96" + ] + }, + "Body": "PEVycm9yUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxFcnJvcj4KICAgIDxUeXBlPlNlbmRlcjwvVHlwZT4KICAgIDxDb2RlPkludmFsaWRQYXJhbWV0ZXI8L0NvZGU+CiAgICA8TWVzc2FnZT5JbnZhbGlkIHBhcmFtZXRlcjogVGhlIE1lc3NhZ2VHcm91cElkIHBhcmFtZXRlciBpcyByZXF1aXJlZCBmb3IgRklGTyB0b3BpY3M8L01lc3NhZ2U+CiAgPC9FcnJvcj4KICA8UmVxdWVzdElkPjI4MzIxN2I2LWIzMjMtNTAzZC1hY2EwLTc3NDI3M2RjY2E5NjwvUmVxdWVzdElkPgo8L0Vycm9yUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "b3e0b8aac07a1fa3", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "205" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb0RlZHVwbGljYXRpb25JRC10b3AtMS5maWZvJTNBNDQyZTE0MjgtMjM5My00OTg1LWFiNTItNTNmNWRkZDQ1OTY1JlZlcnNpb249MjAxMC0wMy0zMQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:08 GMT" + ], + "X-Amzn-Requestid": [ + "ee46a708-7016-59f7-8eb9-c7fcb116835c" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD5lZTQ2YTcwOC03MDE2LTU5ZjctOGViOS1jN2ZjYjExNjgzNWM8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "e54d86600f64151c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "126" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb0RlZHVwbGljYXRpb25JRC1zdWItMSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:08 GMT" + ], + "X-Amzn-Requestid": [ + "c2b2c8b6-c5bc-5998-a6a4-a84204bc03d7" + ] + }, + "Body": "" + } + }, + { + "ID": "20f46969fdc5d625", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "159" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vRGVkdXBsaWNhdGlvbklELXRvcC0xLmZpZm8mVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:08 GMT" + ], + "X-Amzn-Requestid": [ + "1f3d46ff-a7f1-58c5-90cc-260b66f1426e" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4xZjNkNDZmZi1hN2YxLTU4YzUtOTBjYy0yNjBiNjZmMTQyNmU8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSNSTopic/TestSendReceiveInvalidNoMessageGroupID.replay b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSNSTopic/TestSendReceiveInvalidNoMessageGroupID.replay new file mode 100644 index 000000000..59f554047 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSNSTopic/TestSendReceiveInvalidNoMessageGroupID.replay @@ -0,0 +1,539 @@ +{ + "Initial": "AQAAAA7gDLW9JLKWhwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "9bd5559155256c79", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "251" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJkF0dHJpYnV0ZXMuZW50cnkuMS5rZXk9Q29udGVudEJhc2VkRGVkdXBsaWNhdGlvbiZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZBdHRyaWJ1dGVzLmVudHJ5LjIua2V5PUZpZm9Ub3BpYyZBdHRyaWJ1dGVzLmVudHJ5LjIudmFsdWU9dHJ1ZSZOYW1lPVRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vTWVzc2FnZUdyb3VwSUQtdG9wLTEuZmlmbyZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "373" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:05 GMT" + ], + "X-Amzn-Requestid": [ + "d63ffc46-74f1-59fa-b229-9cb2b40c1353" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vTWVzc2FnZUdyb3VwSUQtdG9wLTEuZmlmbzwvVG9waWNBcm4+CiAgPC9DcmVhdGVUb3BpY1Jlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+ZDYzZmZjNDYtNzRmMS01OWZhLWIyMjktOWNiMmI0MGMxMzUzPC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L0NyZWF0ZVRvcGljUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "9e864a1ec9d6a18d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "77" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb01lc3NhZ2VHcm91cElELXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "125" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:06 GMT" + ], + "X-Amzn-Requestid": [ + "ef868745-320a-50cc-9b1f-e7b1f2f431c0" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb01lc3NhZ2VHcm91cElELXN1Yi0xIn0=" + } + }, + { + "ID": "75f394101a05a358", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "155" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb01lc3NhZ2VHcm91cElELXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "126" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:06 GMT" + ], + "X-Amzn-Requestid": [ + "0e201ba5-eaf5-564a-abd8-7b512a0b2746" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb01lc3NhZ2VHcm91cElELXN1Yi0xIn19" + } + }, + { + "ID": "392ec92e807f729d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "536" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vTWVzc2FnZUdyb3VwSUQtc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb01lc3NhZ2VHcm91cElELXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:06 GMT" + ], + "X-Amzn-Requestid": [ + "a9165a59-a07f-5bf0-bd87-3aad60818afc" + ] + }, + "Body": "" + } + }, + { + "ID": "cb3b00cf5f877fe7", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "285" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb01lc3NhZ2VHcm91cElELXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb01lc3NhZ2VHcm91cElELXRvcC0xLmZpZm8mVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "416" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:06 GMT" + ], + "X-Amzn-Requestid": [ + "01c2a5a0-a24f-503f-9312-c55462b11a96" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vTWVzc2FnZUdyb3VwSUQtdG9wLTEuZmlmbzowZGJmMGIwYy0wZjk4LTQzODUtOTBjMy04ZjMwMWM1MWEyZTI8L1N1YnNjcmlwdGlvbkFybj4KICA8L1N1YnNjcmliZVJlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+MDFjMmE1YTAtYTI0Zi01MDNmLTkzMTItYzU1NDYyYjExYTk2PC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L1N1YnNjcmliZVJlc3BvbnNlPgo=" + } + }, + { + "ID": "9a8de1bce2cc14cf", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "566" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjEuQ0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "322" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:06 GMT" + ], + "X-Amzn-Requestid": [ + "520e9f97-4dd0-5773-a1e0-ff638d2eadda" + ] + }, + "Body": "PEVycm9yUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxFcnJvcj4KICAgIDxUeXBlPlNlbmRlcjwvVHlwZT4KICAgIDxDb2RlPkludmFsaWRQYXJhbWV0ZXI8L0NvZGU+CiAgICA8TWVzc2FnZT5JbnZhbGlkIHBhcmFtZXRlcjogVGhlIE1lc3NhZ2VHcm91cElkIHBhcmFtZXRlciBpcyByZXF1aXJlZCBmb3IgRklGTyB0b3BpY3M8L01lc3NhZ2U+CiAgPC9FcnJvcj4KICA8UmVxdWVzdElkPjUyMGU5Zjk3LTRkZDAtNTc3My1hMWUwLWZmNjM4ZDJlYWRkYTwvUmVxdWVzdElkPgo8L0Vycm9yUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "fc5572c1f4f77f76", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "204" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb01lc3NhZ2VHcm91cElELXRvcC0xLmZpZm8lM0EwZGJmMGIwYy0wZjk4LTQzODUtOTBjMy04ZjMwMWM1MWEyZTImVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:06 GMT" + ], + "X-Amzn-Requestid": [ + "0b8b8381-9157-5db0-9419-e37551a9c719" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4wYjhiODM4MS05MTU3LTVkYjAtOTQxOS1lMzc1NTFhOWM3MTk8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "a95ccf7d97077561", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "125" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb01lc3NhZ2VHcm91cElELXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:06 GMT" + ], + "X-Amzn-Requestid": [ + "ed89167d-d60c-531e-a511-768916f22212" + ] + }, + "Body": "" + } + }, + { + "ID": "4f8ab8e97176fba8", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "158" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vTWVzc2FnZUdyb3VwSUQtdG9wLTEuZmlmbyZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:06 GMT" + ], + "X-Amzn-Requestid": [ + "37ff6498-5571-5f51-b1bb-046c958f05f8" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD4zN2ZmNjQ5OC01NTcxLTVmNTEtYjFiYi0wNDZjOTU4ZjA1Zjg8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSNSTopic/TestSendReceiveValid.replay b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSNSTopic/TestSendReceiveValid.replay new file mode 100644 index 000000000..b527b5880 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSNSTopic/TestSendReceiveValid.replay @@ -0,0 +1,771 @@ +{ + "Initial": "AQAAAA7gDLW6ODs+8wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "1b89409c82d29c25", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "233" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPUNyZWF0ZVRvcGljJkF0dHJpYnV0ZXMuZW50cnkuMS5rZXk9Q29udGVudEJhc2VkRGVkdXBsaWNhdGlvbiZBdHRyaWJ1dGVzLmVudHJ5LjEudmFsdWU9dHJ1ZSZBdHRyaWJ1dGVzLmVudHJ5LjIua2V5PUZpZm9Ub3BpYyZBdHRyaWJ1dGVzLmVudHJ5LjIudmFsdWU9dHJ1ZSZOYW1lPVRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmbyZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "355" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:03 GMT" + ], + "X-Amzn-Requestid": [ + "c93ff768-44ad-529e-b13b-979c845602d2" + ] + }, + "Body": "PENyZWF0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxDcmVhdGVUb3BpY1Jlc3VsdD4KICAgIDxUb3BpY0Fybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmbzwvVG9waWNBcm4+CiAgPC9DcmVhdGVUb3BpY1Jlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+YzkzZmY3NjgtNDRhZC01MjllLWIxM2ItOTc5Yzg0NTYwMmQyPC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L0NyZWF0ZVRvcGljUmVzcG9uc2U+Cg==" + } + }, + { + "ID": "1f896aafa23823d2", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "59" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZU5hbWUiOiJUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "107" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:03 GMT" + ], + "X-Amzn-Requestid": [ + "8ad7ea0c-bc42-5a40-a619-8af87cb95faf" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXN1Yi0xIn0=" + } + }, + { + "ID": "8e0af2b6e70a4468", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "137" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "108" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:03 GMT" + ], + "X-Amzn-Requestid": [ + "f6129a32-bb8b-5159-abd1-fac67b7054b6" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXN1Yi0xIn19" + } + }, + { + "ID": "11d70dceeecf5375", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "500" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlVmFsaWQtc3ViLTFcIlxuXHRcdH1cblx0XHRdXG5cdFx0fSJ9LCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:04 GMT" + ], + "X-Amzn-Requestid": [ + "4f179574-0d44-5219-948d-f580cdb897f6" + ] + }, + "Body": "" + } + }, + { + "ID": "8daa000c1cc091fb", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "249" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVN1YnNjcmliZSZFbmRwb2ludD1hcm4lM0Fhd3MlM0FzcXMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXN1Yi0xJlByb3RvY29sPXNxcyZUb3BpY0Fybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXRvcC0xLmZpZm8mVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "398" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:04 GMT" + ], + "X-Amzn-Requestid": [ + "e70fdbe3-d7df-50d5-9500-bb171723d099" + ] + }, + "Body": "PFN1YnNjcmliZVJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8U3Vic2NyaWJlUmVzdWx0PgogICAgPFN1YnNjcmlwdGlvbkFybj5hcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmbzozY2QwNTRiZC01OWMxLTQ5NTAtYTEzNS04NzQyZTdmZTRmMDE8L1N1YnNjcmlwdGlvbkFybj4KICA8L1N1YnNjcmliZVJlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+ZTcwZmRiZTMtZDdkZi01MGQ1LTk1MDAtYmIxNzE3MjNkMDk5PC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L1N1YnNjcmliZVJlc3BvbnNlPgo=" + } + }, + { + "ID": "b9567b9f311ba4c9", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "539" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVB1Ymxpc2hCYXRjaCZQdWJsaXNoQmF0Y2hSZXF1ZXN0RW50cmllcy5tZW1iZXIuMS5JZD0wJlB1Ymxpc2hCYXRjaFJlcXVlc3RFbnRyaWVzLm1lbWJlci4xLk1lc3NhZ2U9aGVsbG8rd29ybGQmUHVibGlzaEJhdGNoUmVxdWVzdEVudHJpZXMubWVtYmVyLjEuQ0xFQVJFRA==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "479" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:04 GMT" + ], + "X-Amzn-Requestid": [ + "302598f0-eca6-5d0e-8b3d-f8042c5afd42" + ] + }, + "Body": "PFB1Ymxpc2hCYXRjaFJlc3BvbnNlIHhtbG5zPSJodHRwOi8vc25zLmFtYXpvbmF3cy5jb20vZG9jLzIwMTAtMDMtMzEvIj4KICA8UHVibGlzaEJhdGNoUmVzdWx0PgogICAgPEZhaWxlZC8+CiAgICA8U3VjY2Vzc2Z1bD4KICAgICAgPG1lbWJlcj4KICAgICAgICA8U2VxdWVuY2VOdW1iZXI+MTAwMDAwMDAwMDAwMDAwMDMwMDA8L1NlcXVlbmNlTnVtYmVyPgogICAgICAgIDxNZXNzYWdlSWQ+MTI3NWVjNGMtNDJjMS01MzM0LTk1N2ItOGNiODgyM2RiMzc4PC9NZXNzYWdlSWQ+CiAgICAgICAgPElkPjA8L0lkPgogICAgICA8L21lbWJlcj4KICAgIDwvU3VjY2Vzc2Z1bD4KICA8L1B1Ymxpc2hCYXRjaFJlc3VsdD4KICA8UmVzcG9uc2VNZXRhZGF0YT4KICAgIDxSZXF1ZXN0SWQ+MzAyNTk4ZjAtZWNhNi01ZDBlLThiM2QtZjgwNDJjNWFmZDQyPC9SZXF1ZXN0SWQ+CiAgPC9SZXNwb25zZU1ldGFkYXRhPgo8L1B1Ymxpc2hCYXRjaFJlc3BvbnNlPgo=" + } + }, + { + "ID": "8cd2c3dbd839db43", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "188" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:04 GMT" + ], + "X-Amzn-Requestid": [ + "7f163331-d6c1-58d3-b5ff-53c5163d1d3c" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "292873b90ad244a7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "188" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "2" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:04 GMT" + ], + "X-Amzn-Requestid": [ + "19c82a19-5ed5-5ea4-bc19-4aed9e29ab4b" + ] + }, + "Body": "e30=" + } + }, + { + "ID": "8a4ead80e61825d6", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "188" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "1415" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:05 GMT" + ], + "X-Amzn-Requestid": [ + "16c8f623-9143-56f4-890a-96d751bed31b" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFSSU1WQ1dWRVozVkw1NEZEQSIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTc1Mjg3NDY4NTE2NSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzUyODc0Njg0ODk2In0sIkJvZHkiOiJ7XG4gIFwiVHlwZVwiIDogXCJOb3RpZmljYXRpb25cIixcbiAgXCJNZXNzYWdlSWRcIiA6IFwiMTI3NWVjNGMtNDJjMS01MzM0LTk1N2ItOGNiODgyM2RiMzc4XCIsXG4gIFwiU2VxdWVuY2VOdW1iZXJcIiA6IFwiMTAwMDAwMDAwMDAwMDAwMDMwMDBcIixcbiAgXCJUb3BpY0FyblwiIDogXCJhcm46YXdzOnNuczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OlRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmb1wiLFxuICBcIk1lc3NhZ2VcIiA6IFwiaGVsbG8gd29ybGRcIixcbiAgXCJUaW1lc3RhbXBcIiA6IFwiMjAyNS0wNy0xOFQyMTozODowNC4zMjJaXCIsXG4gIFwiVW5zdWJzY3JpYmVVUkxcIiA6IFwiaHR0cHM6Ly9zbnMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1VbnN1YnNjcmliZSZTdWJzY3JpcHRpb25Bcm49YXJuOmF3czpzbnM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjpUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXRvcC0xLmZpZm86M2NkMDU0YmQtNTljMS00OTUwLWExMzUtODc0MmU3ZmU0ZjAxXCIsXG4gIFwiTWVzc2FnZUF0dHJpYnV0ZXNcIiA6IHtcbiAgICBcIk1lc3NhZ2VHcm91cElkXCIgOiB7XCJUeXBlXCI6XCJTdHJpbmdcIixcIlZhbHVlXCI6XCIxXCJ9XG4gIH1cbn0iLCJNRDVPZkJvZHkiOiJkNjFlZTE1NjhlNzE4OTNiZjdjM2VmNTM2MjJlNjAzYSIsIk1lc3NhZ2VJZCI6ImZhYTM0ODAxLWM3MTQtNGI3MS1hN2U5LTc5NWU0ZjRlNjQxOCIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCaitmSjlISTlWdTlpSE54Sm1EOU1aUVpaZDIxUFIyZXFqblV6SWZzaU9UdHZpTEFYOE80Q1NaQWtZMlRBTk02L3Bud2NZU3Z2MXBNTUJFQld6emVBR1ZyZGpQd1V3RVhDcEhoVWxIRGFtdjg4MjJUZGpjQ3pSWmFOY05wZUFjdW0wd3BZUUhYNFhkUWc3d0tXZFBDK3N0aDRWRmYwTFUvL1RUbldxOElkWjR6KzZ4aGYrcGZsRGRTdTdmVXo1ODJhT3pBV2NsdzNMbzE3Q25TcmZUazZNYnNQWGhzTmN3RzBTM1JDWkxDTFNVb1JKRVpsZ1hGT2NKdkVhM1daLzkxaFJuRTdkZi9wVjhuUEM4NUZEU1krb01lSy85eEIzbFNDM1RFTld3a2ZXS1lzaE9GazVQQ1NJenVBRzVjVGNJemJUbHAyTGhTMThvUUU2cTN5bVFiYlRpREtlMFZLMCt3SVo2U2N3QnVuZWFGbFdxVlNNVXdtTkdCYTVicllhLzdsdlFaeE1IY25VZ2l3VjYwb210aDRmUktCVjZWVGszMUttbTVRWWlxWGZmYnA5SEx5dk1zNFk3eUpub2cxR1ovTSJ9XX0=" + } + }, + { + "ID": "7bbac97a7e4c15c3", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "601" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQmorZko5SEk5VnU5aUhOeEptRDlNWlFaWmQyMVBSMmVxam5Veklmc2lPVHR2aUxBWDhPNENTWkFrWTJUQU5NNi9wbndjWVN2djFwTU1CRUJXenplQUdWcmRqUHdVd0VYQ3BIaFVsSERhbXY4ODIyVGRqY0N6UlphTmNOcGVBY3VtMHdwWVFIWDRYZFFnN3dLV2RQQytzdGg0VkZmMExVLy9UVG5XcThJZFo0eis2eGhmK3BmbERkU3U3ZlV6NTgyYU96QVdjbHczTG8xN0NuU3JmVGs2TWJzUFhoc05jd0cwUzNSQ1pMQ0xTVW9SSkVabGdYRk9jSnZFYTNXWi85MWhSbkU3ZGYvcFY4blBDODVGRFNZK29NZUsvOXhCM2xTQzNURU5Xd2tmV0tZc2hPRms1UENTSXp1QUc1Y1RjSXpiVGxwMkxoUzE4b1FFNnEzeW1RYmJUaURLZTBWSzArd0laNlNjd0J1bmVhRmxXcVZTTVV3bU5HQmE1YnJZYS83bHZRWnhNSGNuVWdpd1Y2MG9tdGg0ZlJLQlY2VlRrMzFLbW01UVlpcVhmZmJwOUhMeXZNczRZN3lKbm9nMUdaL00ifV0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDU2NzUyNjY1NTc2L1Rlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlVmFsaWQtc3ViLTEifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:05 GMT" + ], + "X-Amzn-Requestid": [ + "7288fb55-a03f-5184-9a0b-9ba160c2846b" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "85df06718b42ec7f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "186" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPVVuc3Vic2NyaWJlJlN1YnNjcmlwdGlvbkFybj1hcm4lM0Fhd3MlM0FzbnMlM0F1cy1lYXN0LTIlM0E0NTY3NTI2NjU1NzYlM0FUZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXRvcC0xLmZpZm8lM0EzY2QwNTRiZC01OWMxLTQ5NTAtYTEzNS04NzQyZTdmZTRmMDEmVmVyc2lvbj0yMDEwLTAzLTMx" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:05 GMT" + ], + "X-Amzn-Requestid": [ + "8a4fad99-02a7-5278-bad5-cd6dc25ae234" + ] + }, + "Body": "PFVuc3Vic2NyaWJlUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD44YTRmYWQ5OS0wMmE3LTUyNzgtYmFkNS1jZDZkYzI1YWUyMzQ8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvVW5zdWJzY3JpYmVSZXNwb25zZT4K" + } + }, + { + "ID": "9f87f8146bc40dcc", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "107" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ], + "X-Amzn-Query-Mode": [ + "true" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ1Njc1MjY2NTU3Ni9UZXN0RklGT1NOU1RvcGljX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXN1Yi0xIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:05 GMT" + ], + "X-Amzn-Requestid": [ + "4f563c56-64dc-5d6d-a317-5ca2a421d882" + ] + }, + "Body": "" + } + }, + { + "ID": "fb5f6a5fb2006c0f", + "Request": { + "Method": "POST", + "URL": "https://sns.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "140" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ] + }, + "MediaType": "application/x-www-form-urlencoded", + "BodyParts": [ + "QWN0aW9uPURlbGV0ZVRvcGljJlRvcGljQXJuPWFybiUzQWF3cyUzQXNucyUzQXVzLWVhc3QtMiUzQTQ1Njc1MjY2NTU3NiUzQVRlc3RGSUZPU05TVG9waWNfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmbyZWZXJzaW9uPTIwMTAtMDMtMzE=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "201" + ], + "Content-Type": [ + "text/xml" + ], + "Date": [ + "Fri, 18 Jul 2025 21:38:05 GMT" + ], + "X-Amzn-Requestid": [ + "9b206a1b-26fd-5d12-8c3d-0aefe600dd5e" + ] + }, + "Body": "PERlbGV0ZVRvcGljUmVzcG9uc2UgeG1sbnM9Imh0dHA6Ly9zbnMuYW1hem9uYXdzLmNvbS9kb2MvMjAxMC0wMy0zMS8iPgogIDxSZXNwb25zZU1ldGFkYXRhPgogICAgPFJlcXVlc3RJZD45YjIwNmExYi0yNmZkLTVkMTItOGMzZC0wYWVmZTYwMGRkNWU8L1JlcXVlc3RJZD4KICA8L1Jlc3BvbnNlTWV0YWRhdGE+CjwvRGVsZXRlVG9waWNSZXNwb25zZT4K" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSQSTopic/TestSendReceiveInvalidNoDeduplicationID.replay b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSQSTopic/TestSendReceiveInvalidNoDeduplicationID.replay new file mode 100644 index 000000000..68d933194 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSQSTopic/TestSendReceiveInvalidNoDeduplicationID.replay @@ -0,0 +1,325 @@ +{ + "Initial": "AQAAAA7d7DkaEPsp2wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "488c1b7baccec043", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "119" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IkZpZm9RdWV1ZSI6InRydWUifSwiUXVldWVOYW1lIjoiVGVzdEZJRk9TUVNUb3BpY1YyX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb0RlZHVwbGljYXRpb25JRC10b3AtMS5maWZvIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "133" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:14 GMT" + ], + "X-Amzn-Requestid": [ + "c8fe192d-a596-55ff-a284-47f9e1cce82b" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vRGVkdXBsaWNhdGlvbklELXRvcC0xLmZpZm8ifQ==" + } + }, + { + "ID": "ef216f838ffba6a3", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "163" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vRGVkdXBsaWNhdGlvbklELXRvcC0xLmZpZm8ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "134" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:14 GMT" + ], + "X-Amzn-Requestid": [ + "f55f2002-99bb-539e-b832-7ed6dde1fe4a" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ2MjM4MDIyNTcyMjpUZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vRGVkdXBsaWNhdGlvbklELXRvcC0xLmZpZm8ifX0=" + } + }, + { + "ID": "3ca56206193d9a4f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "552" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDYyMzgwMjI1NzIyOlRlc3RGSUZPU1FTVG9waWNWMl9UZXN0U2VuZFJlY2VpdmVJbnZhbGlkTm9EZWR1cGxpY2F0aW9uSUQtdG9wLTEuZmlmb1wiXG5cdFx0fVxuXHRcdF1cblx0XHR9In0sIlF1ZXVlVXJsIjoiaHR0cHM6Ly9zcXMudXMtZWFzdC0yLmFtYXpvbmF3cy5jb20vNDYyMzgwMjI1NzIyL1Rlc3RGSUZPU1FTVG9waWNWMl9UZXN0U2VuZFJlY2VpdmVJbnZhbGlkTm9EZWR1cGxpY2F0aW9uSUQtdG9wLTEuZmlmbyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:14 GMT" + ], + "X-Amzn-Requestid": [ + "70c6bccc-fcf9-5394-890f-e218b8a3ee40" + ] + }, + "Body": "" + } + }, + { + "ID": "295ccc1c86c5adf5", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "184" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJNZXNzYWdlQm9keSI6ImhlbGxvIHdvcmxkIn1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vRGVkdXBsaWNhdGlvbklELXRvcC0xLmZpZm8ifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "135" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:14 GMT" + ], + "X-Amzn-Query-Error": [ + "InvalidParameterValue;Sender" + ], + "X-Amzn-Requestid": [ + "8f9fa8f3-579c-5344-9a93-f62713c6fe90" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uLmNvcmFsLnNlcnZpY2UjSW52YWxpZFBhcmFtZXRlclZhbHVlRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSByZXF1ZXN0IG11c3QgY29udGFpbiB0aGUgcGFyYW1ldGVyIE1lc3NhZ2VHcm91cElkLiJ9" + } + }, + { + "ID": "2bb6505bef40e020", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "133" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vRGVkdXBsaWNhdGlvbklELXRvcC0xLmZpZm8ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:14 GMT" + ], + "X-Amzn-Requestid": [ + "a92d077d-a742-594c-9f12-59a9e3184498" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSQSTopic/TestSendReceiveInvalidNoMessageGroupID.replay b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSQSTopic/TestSendReceiveInvalidNoMessageGroupID.replay new file mode 100644 index 000000000..a93cb92d5 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSQSTopic/TestSendReceiveInvalidNoMessageGroupID.replay @@ -0,0 +1,325 @@ +{ + "Initial": "AQAAAA7d7DkZK1G+aQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "6366424e88b30d8f", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "153" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IkNvbnRlbnRCYXNlZERlZHVwbGljYXRpb24iOiJ0cnVlIiwiRmlmb1F1ZXVlIjoidHJ1ZSJ9LCJRdWV1ZU5hbWUiOiJUZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vTWVzc2FnZUdyb3VwSUQtdG9wLTEuZmlmbyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "132" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:13 GMT" + ], + "X-Amzn-Requestid": [ + "26c22a4d-366e-57ae-8ecc-74997237919c" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vTWVzc2FnZUdyb3VwSUQtdG9wLTEuZmlmbyJ9" + } + }, + { + "ID": "3a2c883514b69b62", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "162" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vTWVzc2FnZUdyb3VwSUQtdG9wLTEuZmlmbyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "133" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:14 GMT" + ], + "X-Amzn-Requestid": [ + "b0785a50-4d25-5f0b-9f70-0484097f2939" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ2MjM4MDIyNTcyMjpUZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vTWVzc2FnZUdyb3VwSUQtdG9wLTEuZmlmbyJ9fQ==" + } + }, + { + "ID": "ab18dd9635cce259", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "550" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDYyMzgwMjI1NzIyOlRlc3RGSUZPU1FTVG9waWNWMl9UZXN0U2VuZFJlY2VpdmVJbnZhbGlkTm9NZXNzYWdlR3JvdXBJRC10b3AtMS5maWZvXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NjIzODAyMjU3MjIvVGVzdEZJRk9TUVNUb3BpY1YyX1Rlc3RTZW5kUmVjZWl2ZUludmFsaWROb01lc3NhZ2VHcm91cElELXRvcC0xLmZpZm8ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:14 GMT" + ], + "X-Amzn-Requestid": [ + "a38c8ae8-cee8-510a-b76d-d43c8ab20738" + ] + }, + "Body": "" + } + }, + { + "ID": "11a7cff7dccb146c", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "292" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJDTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "135" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:14 GMT" + ], + "X-Amzn-Query-Error": [ + "InvalidParameterValue;Sender" + ], + "X-Amzn-Requestid": [ + "cd8c196e-fb59-50fa-8b61-47babf03a6c8" + ] + }, + "Body": "eyJfX3R5cGUiOiJjb20uYW1hem9uLmNvcmFsLnNlcnZpY2UjSW52YWxpZFBhcmFtZXRlclZhbHVlRXhjZXB0aW9uIiwibWVzc2FnZSI6IlRoZSByZXF1ZXN0IG11c3QgY29udGFpbiB0aGUgcGFyYW1ldGVyIE1lc3NhZ2VHcm91cElkLiJ9" + } + }, + { + "ID": "2b0f583db6179994", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "132" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlSW52YWxpZE5vTWVzc2FnZUdyb3VwSUQtdG9wLTEuZmlmbyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:14 GMT" + ], + "X-Amzn-Requestid": [ + "6947b160-652e-58bd-923a-efb42174ce8f" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSQSTopic/TestSendReceiveValid.replay b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSQSTopic/TestSendReceiveValid.replay new file mode 100644 index 000000000..94f567313 --- /dev/null +++ b/go-cloud/pubsub/awssnssqs/testdata/TestFIFO/TestSQSTopic/TestSendReceiveValid.replay @@ -0,0 +1,432 @@ +{ + "Initial": "AQAAAA7d7DkZArpthgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "0b80062d7e7d1cf4", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "135" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.CreateQueue" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IkNvbnRlbnRCYXNlZERlZHVwbGljYXRpb24iOiJ0cnVlIiwiRmlmb1F1ZXVlIjoidHJ1ZSJ9LCJRdWV1ZU5hbWUiOiJUZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmbyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "114" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:13 GMT" + ], + "X-Amzn-Requestid": [ + "a3942545-7353-58bb-8c80-7b91370ab888" + ] + }, + "Body": "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmbyJ9" + } + }, + { + "ID": "37296bc76bc72205", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "144" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.GetQueueAttributes" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJRdWV1ZUFybiJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmbyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "115" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:13 GMT" + ], + "X-Amzn-Requestid": [ + "f6b9c333-cc21-5112-9137-9de788786121" + ] + }, + "Body": "eyJBdHRyaWJ1dGVzIjp7IlF1ZXVlQXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0yOjQ2MjM4MDIyNTcyMjpUZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmbyJ9fQ==" + } + }, + { + "ID": "b872a000f87315c7", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "514" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SetQueueAttributes" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVzIjp7IlBvbGljeSI6Intcblx0XHRcIlZlcnNpb25cIjogXCIyMDEyLTEwLTE3XCIsXG5cdFx0XCJJZFwiOiBcIkFsbG93UXVldWVcIixcblx0XHRcIlN0YXRlbWVudFwiOiBbXG5cdFx0e1xuXHRcdFwiU2lkXCI6IFwiTXlTUVNQb2xpY3kwMDFcIixcblx0XHRcIkVmZmVjdFwiOiBcIkFsbG93XCIsXG5cdFx0XCJQcmluY2lwYWxcIjoge1xuXHRcdFwiQVdTXCI6IFwiKlwiXG5cdFx0fSxcblx0XHRcIkFjdGlvblwiOiBcInNxczpTZW5kTWVzc2FnZVwiLFxuXHRcdFwiUmVzb3VyY2VcIjogXCJhcm46YXdzOnNxczp1cy1lYXN0LTI6NDYyMzgwMjI1NzIyOlRlc3RGSUZPU1FTVG9waWNWMl9UZXN0U2VuZFJlY2VpdmVWYWxpZC10b3AtMS5maWZvXCJcblx0XHR9XG5cdFx0XVxuXHRcdH0ifSwiUXVldWVVcmwiOiJodHRwczovL3Nxcy51cy1lYXN0LTIuYW1hem9uYXdzLmNvbS80NjIzODAyMjU3MjIvVGVzdEZJRk9TUVNUb3BpY1YyX1Rlc3RTZW5kUmVjZWl2ZVZhbGlkLXRvcC0xLmZpZm8ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:13 GMT" + ], + "X-Amzn-Requestid": [ + "eb761631-365a-5f1d-8717-48e572038f2e" + ] + }, + "Body": "" + } + }, + { + "ID": "fb0f07a8000497b0", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "265" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.SendMessageBatch" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJDTEVBUkVE" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "232" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:13 GMT" + ], + "X-Amzn-Requestid": [ + "9662cf02-26b8-5134-8575-91d662e1a107" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAiLCJNRDVPZk1lc3NhZ2VBdHRyaWJ1dGVzIjoiNzZmODkzMTU1Y2NjNmY1ZTAxNzQ3MTU3NWRmZDUwYjUiLCJNRDVPZk1lc3NhZ2VCb2R5IjoiNWViNjNiYmJlMDFlZWVkMDkzY2IyMmJiOGY1YWNkYzMiLCJNZXNzYWdlSWQiOiI5NjIzMWY1OC05ZTdhLTQ1NjYtOWZlMi03NjFmZWVhOWMzMzYiLCJTZXF1ZW5jZU51bWJlciI6IjE4ODg2MzQ1MDE5MjM4MTI3ODcyIn1dfQ==" + } + }, + { + "ID": "ba83c145a0d21888", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "195" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.ReceiveMessage" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJBdHRyaWJ1dGVOYW1lcyI6WyJBbGwiXSwiTWF4TnVtYmVyT2ZNZXNzYWdlcyI6MSwiTWVzc2FnZUF0dHJpYnV0ZU5hbWVzIjpbIkFsbCJdLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmbyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "933" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:13 GMT" + ], + "X-Amzn-Requestid": [ + "c2c8c961-7b9b-5368-b941-97b53fc2435b" + ] + }, + "Body": "eyJNZXNzYWdlcyI6W3siQXR0cmlidXRlcyI6eyJTZW5kZXJJZCI6IkFJREFJNEJTWVE0TzZLNVZJTDIzQyIsIkFwcHJveGltYXRlRmlyc3RSZWNlaXZlVGltZXN0YW1wIjoiMTcxNzE5MTE5MzUzMSIsIkFwcHJveGltYXRlUmVjZWl2ZUNvdW50IjoiMSIsIlNlbnRUaW1lc3RhbXAiOiIxNzE3MTkxMTkzNDcxIiwiU2VxdWVuY2VOdW1iZXIiOiIxODg4NjM0NTAxOTIzODEyNzg3MiIsIk1lc3NhZ2VEZWR1cGxpY2F0aW9uSWQiOiJiOTRkMjdiOTkzNGQzZTA4YTUyZTUyZDdkYTdkYWJmYWM0ODRlZmUzN2E1MzgwZWU5MDg4ZjdhY2UyZWZjZGU5IiwiTWVzc2FnZUdyb3VwSWQiOiIxIn0sIkJvZHkiOiJoZWxsbyB3b3JsZCIsIk1ENU9mQm9keSI6IjVlYjYzYmJiZTAxZWVlZDA5M2NiMjJiYjhmNWFjZGMzIiwiTUQ1T2ZNZXNzYWdlQXR0cmlidXRlcyI6Ijc2Zjg5MzE1NWNjYzZmNWUwMTc0NzE1NzVkZmQ1MGI1IiwiTWVzc2FnZUF0dHJpYnV0ZXMiOnsiTWVzc2FnZUdyb3VwSWQiOnsiRGF0YVR5cGUiOiJTdHJpbmciLCJTdHJpbmdWYWx1ZSI6IjEifX0sIk1lc3NhZ2VJZCI6Ijk2MjMxZjU4LTllN2EtNDU2Ni05ZmUyLTc2MWZlZWE5YzMzNiIsIlJlY2VpcHRIYW5kbGUiOiJBUUVCRXY5d08yNnlJMFI5TnJxR0hwVm9HWnhTejA4djJOb0ZRa3FLYnlNaE5tZWpndEw3b1dGamZhMnNYVGEzM1hDbWlRdzhtRmo1azEwdGJDSnF2WUtBUXZOODA3NVRkdDBXUFpIcy9jZUpFbENCWmdyNHhVVW1VQVZrYkxmQ1JYS0hzMGVNVGEwRUlaSjgxWEt2QW9ONDVpaGora0ZpZk1xSll4SDBvV0RJZEl1MXpoa3ErblV6bUt0NGVzeWlTemRwMlNMQzJKWUlTcW1ZQkQ4L3IvNjZsd1RWbXQ3SldDZkRkVms5TWw1ZGJUZzI5WU12OUpvdEZGRXZhYTY3aFBYcHI5NzZ1TjhRblhEbWViMW1adHZVdmNScmIvUlVidkN5aUNNZ2lUTU0vMEszbFJ0M05iMDhnUW1WUWQ3STZZUU8ifV19" + } + }, + { + "ID": "12af619e194dd77d", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "480" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteMessageBatch" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJFbnRyaWVzIjpbeyJJZCI6IjAiLCJSZWNlaXB0SGFuZGxlIjoiQVFFQkV2OXdPMjZ5STBSOU5ycUdIcFZvR1p4U3owOHYyTm9GUWtxS2J5TWhObWVqZ3RMN29XRmpmYTJzWFRhMzNYQ21pUXc4bUZqNWsxMHRiQ0pxdllLQVF2TjgwNzVUZHQwV1BaSHMvY2VKRWxDQlpncjR4VVVtVUFWa2JMZkNSWEtIczBlTVRhMEVJWko4MVhLdkFvTjQ1aWhqK2tGaWZNcUpZeEgwb1dESWRJdTF6aGtxK25Vem1LdDRlc3lpU3pkcDJTTEMySllJU3FtWUJEOC9yLzY2bHdUVm10N0pXQ2ZEZFZrOU1sNWRiVGcyOVlNdjlKb3RGRkV2YWE2N2hQWHByOTc2dU44UW5YRG1lYjFtWnR2VXZjUnJiL1JVYnZDeWlDTWdpVE1NLzBLM2xSdDNOYjA4Z1FtVlFkN0k2WVFPIn1dLCJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmbyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "27" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:13 GMT" + ], + "X-Amzn-Requestid": [ + "a260c8a0-396f-5536-b34f-96747d362505" + ] + }, + "Body": "eyJTdWNjZXNzZnVsIjpbeyJJZCI6IjAifV19" + } + }, + { + "ID": "f71c8f2024a0c6cf", + "Request": { + "Method": "POST", + "URL": "https://sqs.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "114" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSQS.DeleteQueue" + ] + }, + "MediaType": "application/x-amz-json-1.0", + "BodyParts": [ + "eyJRdWV1ZVVybCI6Imh0dHBzOi8vc3FzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tLzQ2MjM4MDIyNTcyMi9UZXN0RklGT1NRU1RvcGljVjJfVGVzdFNlbmRSZWNlaXZlVmFsaWQtdG9wLTEuZmlmbyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "0" + ], + "Content-Type": [ + "application/x-amz-json-1.0" + ], + "Date": [ + "Fri, 31 May 2024 21:33:13 GMT" + ], + "X-Amzn-Requestid": [ + "96248dd5-5ed5-5984-b591-d3011a8c89b7" + ] + }, + "Body": "" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/pubsub/azuresb/azuresb.go b/go-cloud/pubsub/azuresb/azuresb.go new file mode 100644 index 000000000..38fb5b18f --- /dev/null +++ b/go-cloud/pubsub/azuresb/azuresb.go @@ -0,0 +1,618 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 azuresb provides an implementation of pubsub using Azure Service +// Bus Topic and Subscription. +// See https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messaging-overview for an overview. +// +// # URLs +// +// For pubsub.OpenTopic and pubsub.OpenSubscription, azuresb registers +// for the scheme "azuresb". +// The default URL opener will use a Service Bus Connection String based on +// AZURE_SERVICEBUS_HOSTNAME or SERVICEBUS_CONNECTION_STRING environment variables. +// SERVICEBUS_CONNECTION_STRING takes precedence. +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # Message Delivery Semantics +// +// Azure ServiceBus supports at-least-once semantics in the default Peek-Lock +// mode; messages will be redelivered if they are not Acked, or if they are +// explicitly Nacked. +// +// ServiceBus also supports a Receive-Delete mode, which essentially auto-acks a +// message when it is delivered, resulting in at-most-once semantics. Set +// SubscriberOptions.ReceiveAndDelete to true to tell azuresb.Subscription that +// you've enabled Receive-Delete mode. When enabled, pubsub.Message.Ack is a +// no-op, pubsub.Message.Nackable will return false, and pubsub.Message.Nack +// will panic. +// +// See https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery +// for more background. +// +// # As +// +// azuresb exposes the following types for As: +// - Topic: *servicebus.Topic +// - Subscription: *servicebus.Subscription +// - Message.BeforeSend: *servicebus.Message +// - Message.AfterSend: None +// - Message: *servicebus.Message +// - Error: common.Retryable, *amqp.Error, *amqp.LinkError +package azuresb // import "gocloud.dev/pubsub/azuresb" + +import ( + "context" + "errors" + "fmt" + "net/url" + "os" + "path" + "strconv" + "strings" + "sync" + "time" + + common "github.com/Azure/azure-amqp-common-go/v3" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + servicebus "github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus" + "github.com/Azure/go-amqp" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/batcher" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" +) + +const ( + defaultListenerTimeout = 2 * time.Second +) + +var sendBatcherOpts = &batcher.Options{ + MaxBatchSize: 1, // SendBatch only supports one message at a time + MaxHandlers: 100, // max concurrency for sends +} + +var recvBatcherOpts = &batcher.Options{ + MaxBatchSize: 50, + MaxHandlers: 100, // max concurrency for reads +} + +var ackBatcherOpts = &batcher.Options{ + MaxBatchSize: 1, + MaxHandlers: 100, // max concurrency for acks +} + +func init() { + o := new(defaultOpener) + pubsub.DefaultURLMux().RegisterTopic(Scheme, o) + pubsub.DefaultURLMux().RegisterSubscription(Scheme, o) +} + +// defaultURLOpener creates an URLOpener with ConnectionString initialized from +// AZURE_SERVICEBUS_HOSTNAME or SERVICEBUS_CONNECTION_STRING environment variables. +// SERVICEBUS_CONNECTION_STRING takes precedence. +type defaultOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *defaultOpener) defaultOpener() (*URLOpener, error) { + o.init.Do(func() { + cs := os.Getenv("SERVICEBUS_CONNECTION_STRING") + sbHostname := os.Getenv("AZURE_SERVICEBUS_HOSTNAME") + if cs == "" && sbHostname == "" { + o.err = errors.New("Neither SERVICEBUS_CONNECTION_STRING nor AZURE_SERVICEBUS_HOSTNAME environment variables are set") + return + } + o.opener = &URLOpener{ConnectionString: cs, ServiceBusHostname: sbHostname} + }) + return o.opener, o.err +} + +func (o *defaultOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + opener, err := o.defaultOpener() + if err != nil { + return nil, fmt.Errorf("open topic %v: %v", u, err) + } + return opener.OpenTopicURL(ctx, u) +} + +func (o *defaultOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + opener, err := o.defaultOpener() + if err != nil { + return nil, fmt.Errorf("open subscription %v: %v", u, err) + } + return opener.OpenSubscriptionURL(ctx, u) +} + +// Scheme is the URL scheme azuresb registers its URLOpeners under on pubsub.DefaultMux. +const Scheme = "azuresb" + +// URLOpener opens Azure Service Bus URLs like "azuresb://mytopic" for +// topics or "azuresb://mytopic?subscription=mysubscription" for subscriptions. +// +// - The URL's host+path is used as the topic name. +// - For subscriptions, the subscription name must be provided in the +// "subscription" query parameter. +// - For subscriptions, the ListenerTimeout can be overridden with time.Duration parseable values in "listener_timeout". +// +// No other query parameters are supported. +type URLOpener struct { + // ConnectionString is the Service Bus connection string (required if ServiceBusHostname is not defined). + // https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues + ConnectionString string + + // Azure ServiceBus hostname. + // https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-go-how-to-use-queues?tabs=bash + ServiceBusHostname string + + // ClientOptions are options when creating the Client. + ServiceBusClientOptions *servicebus.ClientOptions + + // Options passed when creating the ServiceBus Topic/Subscription. + ServiceBusSenderOptions *servicebus.NewSenderOptions + ServiceBusReceiverOptions *servicebus.ReceiverOptions + + // TopicOptions specifies the options to pass to OpenTopic. + TopicOptions TopicOptions + // SubscriptionOptions specifies the options to pass to OpenSubscription. + SubscriptionOptions SubscriptionOptions +} + +func (o *URLOpener) sbClient(kind string, u *url.URL) (*servicebus.Client, error) { + if o.ConnectionString == "" && o.ServiceBusHostname == "" { + return nil, fmt.Errorf("open %s %v: one of ConnectionString or ServiceBusHostname is required", kind, u) + } + + // Auth using shared key. + if o.ConnectionString != "" { + client, err := NewClientFromConnectionString(o.ConnectionString, o.ServiceBusClientOptions) + if err != nil { + return nil, fmt.Errorf("open %s %v: invalid connection string %q: %v", kind, u, o.ConnectionString, err) + } + return client, nil + } + + // Auth using Azure AAD Workload Identity/AAD Pod Identities/AKS Kubelet Identity/Service Principal. + client, err := NewClientFromServiceBusHostname(o.ServiceBusHostname, o.ServiceBusClientOptions) + if err != nil { + return nil, fmt.Errorf("open %s %v: invalid service bus hostname %q: %v", kind, u, o.ServiceBusHostname, err) + } + return client, nil +} + +// OpenTopicURL opens a pubsub.Topic based on u. +func (o *URLOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + sbClient, err := o.sbClient("topic", u) + if err != nil { + return nil, err + } + for param := range u.Query() { + return nil, fmt.Errorf("open topic %v: invalid query parameter %q", u, param) + } + topicName := path.Join(u.Host, u.Path) + sbSender, err := NewSender(sbClient, topicName, o.ServiceBusSenderOptions) + if err != nil { + return nil, fmt.Errorf("open topic %v: couldn't open topic %q: %v", u, topicName, err) + } + return OpenTopic(ctx, sbSender, &o.TopicOptions) +} + +// OpenSubscriptionURL opens a pubsub.Subscription based on u. +func (o *URLOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + sbClient, err := o.sbClient("subscription", u) + if err != nil { + return nil, err + } + topicName := path.Join(u.Host, u.Path) + q := u.Query() + subName := q.Get("subscription") + q.Del("subscription") + if subName == "" { + return nil, fmt.Errorf("open subscription %v: missing required query parameter subscription", u) + } + opts := o.SubscriptionOptions + if lts := q.Get("listener_timeout"); lts != "" { + q.Del("listener_timeout") + d, err := time.ParseDuration(lts) + if err != nil { + return nil, fmt.Errorf("open subscription %v: invalid listener_timeout %q: %v", u, lts, err) + } + opts.ListenerTimeout = d + } + if mrbss := q.Get("max_recv_batch_size"); mrbss != "" { + q.Del("max_recv_batch_size") + mrbs, err := strconv.Atoi(mrbss) + if err != nil { + return nil, fmt.Errorf("open subscription %v: invalid max_recv_batch_size %q: %v", u, mrbss, err) + } + opts.ReceiveBatcherOptions.MaxBatchSize = mrbs + } + for param := range q { + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q", u, param) + } + sbReceiver, err := NewReceiver(sbClient, topicName, subName, o.ServiceBusReceiverOptions) + if err != nil { + return nil, fmt.Errorf("open subscription %v: couldn't open subscription %q: %v", u, subName, err) + } + return OpenSubscription(ctx, sbClient, sbReceiver, &opts) +} + +type topic struct { + sbSender *servicebus.Sender +} + +// TopicOptions provides configuration options for an Azure SB Topic. +type TopicOptions struct { + // BatcherOptions adds constraints to the default batching done for sends. + BatcherOptions batcher.Options +} + +// NewClientFromConnectionString returns a *servicebus.Client from a Service Bus connection string, using shared key for auth. +// https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues +func NewClientFromConnectionString(connectionString string, opts *servicebus.ClientOptions) (*servicebus.Client, error) { + return servicebus.NewClientFromConnectionString(connectionString, opts) +} + +// NewClientFromConnectionString returns a *servicebus.Client from a Service Bus connection string, using shared key for auth. +// for example you can use workload identity autorization. +// https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-go-how-to-use-queues?tabs=bash +func NewClientFromServiceBusHostname(serviceBusHostname string, opts *servicebus.ClientOptions) (*servicebus.Client, error) { + cred, err := azidentity.NewDefaultAzureCredential(nil) + if err != nil { + return nil, err + } + client, err := servicebus.NewClient(serviceBusHostname, cred, opts) + if err != nil { + return nil, err + } + return client, nil +} + +// NewSender returns a *servicebus.Sender associated with a Service Bus Client. +func NewSender(sbClient *servicebus.Client, topicName string, opts *servicebus.NewSenderOptions) (*servicebus.Sender, error) { + return sbClient.NewSender(topicName, opts) +} + +// NewReceiver returns a *servicebus.Receiver associated with a Service Bus Topic. +func NewReceiver(sbClient *servicebus.Client, topicName, subscriptionName string, opts *servicebus.ReceiverOptions) (*servicebus.Receiver, error) { + return sbClient.NewReceiverForSubscription(topicName, subscriptionName, opts) +} + +// OpenTopic initializes a pubsub Topic on a given Service Bus Sender. +func OpenTopic(ctx context.Context, sbSender *servicebus.Sender, opts *TopicOptions) (*pubsub.Topic, error) { + t, err := openTopic(ctx, sbSender, opts) + if err != nil { + return nil, err + } + if opts == nil { + opts = &TopicOptions{} + } + bo := sendBatcherOpts.NewMergedOptions(&opts.BatcherOptions) + return pubsub.NewTopic(t, bo), nil +} + +// openTopic returns the driver for OpenTopic. This function exists so the test +// harness can get the driver interface implementation if it needs to. +func openTopic(ctx context.Context, sbSender *servicebus.Sender, _ *TopicOptions) (driver.Topic, error) { + if sbSender == nil { + return nil, errors.New("azuresb: OpenTopic requires a Service Bus Sender") + } + return &topic{sbSender: sbSender}, nil +} + +// SendBatch implements driver.Topic.SendBatch. +func (t *topic) SendBatch(ctx context.Context, dms []*driver.Message) error { + if len(dms) != 1 { + panic("azuresb.SendBatch should only get one message at a time") + } + dm := dms[0] + sbms := &servicebus.Message{Body: dm.Body} + if len(dm.Metadata) > 0 { + sbms.ApplicationProperties = map[string]any{} + for k, v := range dm.Metadata { + sbms.ApplicationProperties[k] = v + } + } + if dm.BeforeSend != nil { + asFunc := func(i any) bool { + if p, ok := i.(**servicebus.Message); ok { + *p = sbms + return true + } + return false + } + if err := dm.BeforeSend(asFunc); err != nil { + return err + } + } + err := t.sbSender.SendMessage(ctx, sbms, nil) + if err != nil { + return err + } + if dm.AfterSend != nil { + asFunc := func(i any) bool { return false } + if err := dm.AfterSend(asFunc); err != nil { + return err + } + } + return nil +} + +func (t *topic) IsRetryable(err error) bool { + _, retryable := errorCode(err) + return retryable +} + +func (t *topic) As(i any) bool { + p, ok := i.(**servicebus.Sender) + if !ok { + return false + } + *p = t.sbSender + return true +} + +// ErrorAs implements driver.Topic.ErrorAs +func (*topic) ErrorAs(err error, i any) bool { + return errorAs(err, i) +} + +func errorAs(err error, i any) bool { + switch v := err.(type) { + case *amqp.LinkError: + if p, ok := i.(**amqp.LinkError); ok { + *p = v + return true + } + case *amqp.Error: + if p, ok := i.(**amqp.Error); ok { + *p = v + return true + } + case common.Retryable: + if p, ok := i.(*common.Retryable); ok { + *p = v + return true + } + } + return false +} + +func (*topic) ErrorCode(err error) gcerrors.ErrorCode { + code, _ := errorCode(err) + return code +} + +// Close implements driver.Topic.Close. +func (*topic) Close() error { return nil } + +type subscription struct { + sbReceiver *servicebus.Receiver + opts *SubscriptionOptions +} + +// SubscriptionOptions will contain configuration for subscriptions. +type SubscriptionOptions struct { + // If false, the serviceBus.Subscription MUST be in the default Peek-Lock mode. + // If true, the serviceBus.Subscription MUST be in Receive-and-Delete mode. + // When true: pubsub.Message.Ack will be a no-op, pubsub.Message.Nackable + // will return true, and pubsub.Message.Nack will panic. + ReceiveAndDelete bool + + // ReceiveBatcherOptions adds constraints to the default batching done for receives. + ReceiveBatcherOptions batcher.Options + + // AckBatcherOptions adds constraints to the default batching done for acks. + // Only used when ReceiveAndDelete is false. + AckBatcherOptions batcher.Options + + // ListenerTimeout is the amount of time to wait before timing out the + // ReceiveMessages RPC call. This is used to ensure the receive operation is + // non-blocking as the RPC blocks if there are no messages. + // Defaults to 2 seconds. + ListenerTimeout time.Duration +} + +// OpenSubscription initializes a pubsub Subscription on a given Service Bus Subscription and its parent Service Bus Topic. +func OpenSubscription(ctx context.Context, sbClient *servicebus.Client, sbReceiver *servicebus.Receiver, opts *SubscriptionOptions) (*pubsub.Subscription, error) { + ds, err := openSubscription(ctx, sbClient, sbReceiver, opts) + if err != nil { + return nil, err + } + if opts == nil { + opts = &SubscriptionOptions{} + } + rbo := recvBatcherOpts.NewMergedOptions(&opts.ReceiveBatcherOptions) + abo := ackBatcherOpts.NewMergedOptions(&opts.AckBatcherOptions) + return pubsub.NewSubscription(ds, rbo, abo), nil +} + +// openSubscription returns a driver.Subscription. +func openSubscription(ctx context.Context, sbClient *servicebus.Client, sbReceiver *servicebus.Receiver, opts *SubscriptionOptions) (driver.Subscription, error) { + if sbClient == nil { + return nil, errors.New("azuresb: OpenSubscription requires a Service Bus Client") + } + if sbReceiver == nil { + return nil, errors.New("azuresb: OpenSubscription requires a Service Bus Receiver") + } + if opts == nil { + opts = &SubscriptionOptions{} + } + if opts.ListenerTimeout == 0 { + opts.ListenerTimeout = defaultListenerTimeout + } + return &subscription{sbReceiver: sbReceiver, opts: opts}, nil +} + +// IsRetryable implements driver.Subscription.IsRetryable. +func (s *subscription) IsRetryable(err error) bool { + _, retryable := errorCode(err) + return retryable +} + +// As implements driver.Subscription.As. +func (s *subscription) As(i any) bool { + p, ok := i.(**servicebus.Receiver) + if !ok { + return false + } + *p = s.sbReceiver + return true +} + +// ErrorAs implements driver.Subscription.ErrorAs +func (s *subscription) ErrorAs(err error, i any) bool { + return errorAs(err, i) +} + +func (s *subscription) ErrorCode(err error) gcerrors.ErrorCode { + code, _ := errorCode(err) + return code +} + +// ReceiveBatch implements driver.Subscription.ReceiveBatch. +func (s *subscription) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + // ReceiveMessages will block until rctx is Done; we want to return after + // a reasonably short delay even if there are no messages. So, create a + // sub context for the RPC. + rctx, cancel := context.WithTimeout(ctx, s.opts.ListenerTimeout) + defer cancel() + + var messages []*driver.Message + sbmsgs, err := s.sbReceiver.ReceiveMessages(rctx, maxMessages, nil) + for _, sbmsg := range sbmsgs { + metadata := map[string]string{} + for key, value := range sbmsg.ApplicationProperties { + if strVal, ok := value.(string); ok { + metadata[key] = strVal + } + } + messages = append(messages, &driver.Message{ + LoggableID: sbmsg.MessageID, + Body: sbmsg.Body, + Metadata: metadata, + AckID: sbmsg, + AsFunc: messageAsFunc(sbmsg), + }) + } + // Mask rctx timeouts, they are expected if no messages are available. + if err == rctx.Err() { + err = nil + } + return messages, err +} + +func messageAsFunc(sbmsg *servicebus.ReceivedMessage) func(any) bool { + return func(i any) bool { + p, ok := i.(**servicebus.ReceivedMessage) + if !ok { + return false + } + *p = sbmsg + return true + } +} + +// SendAcks implements driver.Subscription.SendAcks. +func (s *subscription) SendAcks(ctx context.Context, ids []driver.AckID) error { + if s.opts.ReceiveAndDelete { + // Ack is a no-op in Receive-and-Delete mode. + return nil + } + var err error + for _, id := range ids { + oneErr := s.sbReceiver.CompleteMessage(ctx, id.(*servicebus.ReceivedMessage), nil) + if oneErr != nil { + err = oneErr + } + } + return err +} + +// CanNack implements driver.CanNack. +func (s *subscription) CanNack() bool { + if s == nil { + return false + } + return !s.opts.ReceiveAndDelete +} + +// SendNacks implements driver.Subscription.SendNacks. +func (s *subscription) SendNacks(ctx context.Context, ids []driver.AckID) error { + if !s.CanNack() { + panic("unreachable") + } + var err error + for _, id := range ids { + oneErr := s.sbReceiver.AbandonMessage(ctx, id.(*servicebus.ReceivedMessage), nil) + if oneErr != nil { + err = oneErr + } + } + return err +} + +// errorCode returns an error code and whether err is retryable. +func errorCode(err error) (gcerrors.ErrorCode, bool) { + // Unfortunately Azure sometimes returns common.Retryable or even + // errors.errorString, which don't expose anything other than the error + // string :-(. + if strings.Contains(err.Error(), "status code 404") { + return gcerrors.NotFound, false + } + if strings.Contains(err.Error(), "status code 401") { + return gcerrors.PermissionDenied, false + } + var cond amqp.ErrCond + var aderr *amqp.LinkError + var aerr *amqp.Error + if errors.As(err, &aderr) { + if aderr.RemoteErr == nil { + return gcerrors.NotFound, false + } + cond = aderr.RemoteErr.Condition + } else if errors.As(err, &aerr) { + cond = aerr.Condition + } + switch cond { + case amqp.ErrCondNotFound: + return gcerrors.NotFound, false + + case amqp.ErrCondPreconditionFailed: + return gcerrors.FailedPrecondition, false + + case amqp.ErrCondInternalError: + return gcerrors.Internal, true + + case amqp.ErrCondNotImplemented: + return gcerrors.Unimplemented, false + + case amqp.ErrCondUnauthorizedAccess, amqp.ErrCondNotAllowed: + return gcerrors.PermissionDenied, false + + case amqp.ErrCondResourceLimitExceeded: + return gcerrors.ResourceExhausted, true + + case amqp.ErrCondInvalidField: + return gcerrors.InvalidArgument, false + } + return gcerrors.Unknown, true +} + +// Close implements driver.Subscription.Close. +func (*subscription) Close() error { return nil } diff --git a/go-cloud/pubsub/azuresb/azuresb_test.go b/go-cloud/pubsub/azuresb/azuresb_test.go new file mode 100644 index 000000000..73dc960c9 --- /dev/null +++ b/go-cloud/pubsub/azuresb/azuresb_test.go @@ -0,0 +1,463 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 azuresb + +import ( + "context" + "fmt" + "os" + "strings" + "sync/atomic" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/drivertest" + + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + servicebus "github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus" + "github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus/admin" +) + +var ( + // See docs below on how to provision an Azure Service Bus Namespace and obtaining the connection string. + // https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues + connString = os.Getenv("SERVICEBUS_CONNECTION_STRING") + sbHostname = os.Getenv("AZURE_SERVICEBUS_HOSTNAME") +) + +const ( + nonexistentTopicName = "nonexistent-topic" + + // Try to keep the entity name under Azure limits. + // https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-quotas + // says 50, but there appears to be some additional overhead. 40 works. + maxNameLen = 40 +) + +type harness struct { + adminClient *admin.Client + sbClient *servicebus.Client + numTopics uint32 // atomic + numSubs uint32 // atomic + closer func() + autodelete bool + topics map[driver.Topic]string +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + if connString == "" && sbHostname == "" { + return nil, fmt.Errorf("azuresb: test harness requires environment variable SERVICEBUS_CONNECTION_STRING or AZURE_SERVICEBUS_HOSTNAME to run") + } + adminClient, err := admin.NewClientFromConnectionString(connString, nil) + if err != nil { + return nil, err + } + sbClient, err := NewClientFromConnectionString(connString, nil) + if err != nil { + return nil, err + } + noop := func() {} + return &harness{ + adminClient: adminClient, + sbClient: sbClient, + closer: noop, + topics: map[driver.Topic]string{}, + }, nil +} + +func newHarnessUsingAutodelete(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + h, err := newHarness(ctx, t) + if err == nil { + h.(*harness).autodelete = true + } + return h, err +} + +func (h *harness) CreateTopic(ctx context.Context, testName string) (dt driver.Topic, cleanup func(), err error) { + topicName := sanitize(fmt.Sprintf("%s-top-%d", testName, atomic.AddUint32(&h.numTopics, 1))) + if err := createTopic(ctx, topicName, h.adminClient, nil); err != nil { + return nil, nil, err + } + + sbSender, err := NewSender(h.sbClient, topicName, nil) + dt, err = openTopic(ctx, sbSender, nil) + if err != nil { + return nil, nil, err + } + h.topics[dt] = topicName + cleanup = func() { + sbSender.Close(ctx) + deleteTopic(ctx, topicName, h.adminClient) + } + return dt, cleanup, nil +} + +func (h *harness) MakeNonexistentTopic(ctx context.Context) (driver.Topic, error) { + sbSender, err := NewSender(h.sbClient, nonexistentTopicName, nil) + if err != nil { + return nil, err + } + dt, err := openTopic(ctx, sbSender, nil) + if err != nil { + return nil, err + } + h.topics[dt] = nonexistentTopicName + return dt, nil +} + +func (h *harness) CreateSubscription(ctx context.Context, dt driver.Topic, testName string) (ds driver.Subscription, cleanup func(), err error) { + subName := sanitize(fmt.Sprintf("%s-sub-%d", testName, atomic.AddUint32(&h.numSubs, 1))) + topicName := h.topics[dt] + err = createSubscription(ctx, topicName, subName, h.adminClient, nil) + if err != nil { + return nil, nil, err + } + + var opts servicebus.ReceiverOptions + if h.autodelete { + opts.ReceiveMode = servicebus.ReceiveModeReceiveAndDelete + } + sbReceiver, err := NewReceiver(h.sbClient, topicName, subName, &opts) + if err != nil { + return nil, nil, err + } + + sopts := SubscriptionOptions{} + if h.autodelete { + sopts.ReceiveAndDelete = true + } + ds, err = openSubscription(ctx, h.sbClient, sbReceiver, &sopts) + if err != nil { + return nil, nil, err + } + + cleanup = func() { + sbReceiver.Close(ctx) + deleteSubscription(ctx, topicName, subName, h.adminClient) + } + return ds, cleanup, nil +} + +func (h *harness) MakeNonexistentSubscription(ctx context.Context) (driver.Subscription, func(), error) { + const topicName = "topic-for-nonexistent-sub" + _, cleanup, err := h.CreateTopic(ctx, topicName) + if err != nil { + return nil, nil, err + } + sbReceiver, err := NewReceiver(h.sbClient, topicName, "nonexistent-subscription", nil) + if err != nil { + return nil, cleanup, err + } + sub, err := openSubscription(ctx, h.sbClient, sbReceiver, nil) + return sub, cleanup, err +} + +func (h *harness) Close() { + h.closer() +} + +func (h *harness) MaxBatchSizes() (int, int) { return sendBatcherOpts.MaxBatchSize, 0 } + +func (h *harness) SupportsMultipleSubscriptions() bool { return true } + +// Please run the TestConformance with an extended timeout since each test needs to perform CRUD for ServiceBus Topics and Subscriptions. +// Example: C:\Go\bin\go.exe test -timeout 60s gocloud.dev/pubsub/azuresb -run ^TestConformance$ +func TestConformance(t *testing.T) { + if !*setup.Record { + t.Skip("replaying is not yet supported for Azure pubsub") + } + asTests := []drivertest.AsTest{sbAsTest{}} + drivertest.RunConformanceTests(t, newHarness, asTests) +} + +func TestConformanceWithAutodelete(t *testing.T) { + if !*setup.Record { + t.Skip("replaying is not yet supported for Azure pubsub") + } + asTests := []drivertest.AsTest{sbAsTest{}} + drivertest.RunConformanceTests(t, newHarnessUsingAutodelete, asTests) +} + +type sbAsTest struct{} + +func (sbAsTest) Name() string { + return "azure" +} + +func (sbAsTest) TopicCheck(topic *pubsub.Topic) error { + var t2 servicebus.Sender + if topic.As(&t2) { + return fmt.Errorf("cast succeeded for %T, want failure", &t2) + } + var t3 *servicebus.Sender + if !topic.As(&t3) { + return fmt.Errorf("cast failed for %T", &t3) + } + return nil +} + +func (sbAsTest) SubscriptionCheck(sub *pubsub.Subscription) error { + var s2 servicebus.Receiver + if sub.As(&s2) { + return fmt.Errorf("cast succeeded for %T, want failure", &s2) + } + var s3 *servicebus.Receiver + if !sub.As(&s3) { + return fmt.Errorf("cast failed for %T", &s3) + } + return nil +} + +func (sbAsTest) TopicErrorCheck(t *pubsub.Topic, err error) error { + return nil +} + +func (sbAsTest) SubscriptionErrorCheck(s *pubsub.Subscription, err error) error { + return nil +} + +func (sbAsTest) MessageCheck(m *pubsub.Message) error { + var m2 servicebus.ReceivedMessage + if m.As(&m2) { + return fmt.Errorf("cast succeeded for %T, want failure", &m2) + } + var m3 *servicebus.ReceivedMessage + if !m.As(&m3) { + return fmt.Errorf("cast failed for %T", &m3) + } + return nil +} + +func (sbAsTest) BeforeSend(as func(any) bool) error { + var m *servicebus.Message + if !as(&m) { + return fmt.Errorf("cast failed for %T", &m) + } + return nil +} + +func (sbAsTest) AfterSend(as func(any) bool) error { + return nil +} + +func sanitize(s string) string { + // First trim some not-so-useful strings that are part of all test names. + s = strings.Replace(s, "TestConformance/Test", "", 1) + s = strings.Replace(s, "TestConformanceWithAutodelete/Test", "", 1) + s = strings.Replace(s, "/", "_", -1) + if len(s) > maxNameLen { + // Drop prefix, not suffix, because suffix includes something to make + // entities unique within a test. + s = s[len(s)-maxNameLen:] + } + return s +} + +// createTopic ensures the existence of a Service Bus Topic on a given Namespace. +func createTopic(ctx context.Context, topicName string, adminClient *admin.Client, properties *admin.TopicProperties) error { + t, _ := adminClient.GetTopic(ctx, topicName, nil) + if t != nil { + _, _ = adminClient.DeleteTopic(ctx, topicName, nil) + } + opts := admin.CreateTopicOptions{ + Properties: properties, + } + _, err := adminClient.CreateTopic(ctx, topicName, &opts) + return err +} + +// deleteTopic removes a Service Bus Topic on a given Namespace. +func deleteTopic(ctx context.Context, topicName string, adminClient *admin.Client) error { + t, _ := adminClient.GetTopic(ctx, topicName, nil) + if t != nil { + _, err := adminClient.DeleteTopic(ctx, topicName, nil) + return err + } + return nil +} + +// createSubscription ensures the existence of a Service Bus Subscription on a given Namespace and Topic. +func createSubscription(ctx context.Context, topicName, subscriptionName string, adminClient *admin.Client, properties *admin.SubscriptionProperties) error { + s, _ := adminClient.GetSubscription(ctx, topicName, subscriptionName, nil) + if s != nil { + _, _ = adminClient.DeleteSubscription(ctx, topicName, subscriptionName, nil) + } + opts := admin.CreateSubscriptionOptions{ + Properties: properties, + } + _, err := adminClient.CreateSubscription(ctx, topicName, subscriptionName, &opts) + return err +} + +// deleteSubscription removes a Service Bus Subscription on a given Namespace and Topic. +func deleteSubscription(ctx context.Context, topicName, subscriptionName string, adminClient *admin.Client) error { + se, _ := adminClient.GetSubscription(ctx, topicName, subscriptionName, nil) + if se != nil { + _, err := adminClient.DeleteSubscription(ctx, topicName, subscriptionName, nil) + return err + } + return nil +} + +// to run test using Azure Entra credentials: +// 1. grant access to ${AZURE_CLIENT_ID} to Service Bus namespace +// 2. run test: +// AZURE_CLIENT_SECRET='secret' \ +// AZURE_CLIENT_ID=client_id_uud \ +// AZURE_TENANT_ID=tenant_id_uuid \ +// AZURE_SERVICEBUS_HOSTNAME=hostname go test -benchmem -run=^$ -bench ^BenchmarkAzureServiceBusPubSub$ gocloud.dev/pubsub/azuresb +func BenchmarkAzureServiceBusPubSub(b *testing.B) { + const ( + benchmarkTopicName = "benchmark-topic" + benchmarkSubscriptionName = "benchmark-subscription" + ) + ctx := context.Background() + + var adminClient *admin.Client + var sbClient *servicebus.Client + var err error + + if connString == "" && sbHostname == "" { + b.Fatal("azuresb: benchmark requires environment variable SERVICEBUS_CONNECTION_STRING or AZURE_SERVICEBUS_HOSTNAME to run") + } + + if connString != "" { + adminClient, err = admin.NewClientFromConnectionString(connString, nil) + if err != nil { + b.Fatal(err) + } + sbClient, err = NewClientFromConnectionString(connString, nil) + if err != nil { + b.Fatal(err) + } + } else if sbHostname != "" { + cred, err := azidentity.NewDefaultAzureCredential(nil) + if err != nil { + b.Fatal(err) + } + adminClient, err = admin.NewClient(sbHostname, cred, nil) + if err != nil { + b.Fatal(err) + } + sbClient, err = NewClientFromServiceBusHostname(sbHostname, nil) + if err != nil { + b.Fatal(err) + } + } + + // Make topic. + if err := createTopic(ctx, benchmarkTopicName, adminClient, nil); err != nil { + b.Fatal(err) + } + defer deleteTopic(ctx, benchmarkTopicName, adminClient) + + sbSender, err := NewSender(sbClient, benchmarkTopicName, nil) + if err != nil { + b.Fatal(err) + } + defer sbSender.Close(ctx) + topic, err := OpenTopic(ctx, sbSender, nil) + if err != nil { + b.Fatal(err) + } + defer topic.Shutdown(ctx) + + // Make subscription. + if err := createSubscription(ctx, benchmarkTopicName, benchmarkSubscriptionName, adminClient, nil); err != nil { + b.Fatal(err) + } + sbReceiver, err := NewReceiver(sbClient, benchmarkTopicName, benchmarkSubscriptionName, nil) + if err != nil { + b.Fatal(err) + } + sub, err := OpenSubscription(ctx, sbClient, sbReceiver, nil) + if err != nil { + b.Fatal(err) + } + defer sub.Shutdown(ctx) + + drivertest.RunBenchmarks(b, topic, sub) +} + +func fakeConnectionStringInEnv() func() { + oldEnvVal := os.Getenv("SERVICEBUS_CONNECTION_STRING") + os.Setenv("SERVICEBUS_CONNECTION_STRING", "Endpoint=sb://foo.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=mykey") + return func() { + os.Setenv("SERVICEBUS_CONNECTION_STRING", oldEnvVal) + } +} + +func TestOpenTopicFromURL(t *testing.T) { + cleanup := fakeConnectionStringInEnv() + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"azuresb://mytopic", false}, + // Invalid parameter. + {"azuresb://mytopic?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + topic, err := pubsub.OpenTopic(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if topic != nil { + topic.Shutdown(ctx) + } + } +} + +func TestOpenSubscriptionFromURL(t *testing.T) { + cleanup := fakeConnectionStringInEnv() + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"azuresb://mytopic?subscription=mysub", false}, + // Missing subscription. + {"azuresb://mytopic", true}, + // Setting listener_timeout. + {"azuresb://mytopic?subscription=mysub&listener_timeout=10s", false}, + // Invalid listener_timeout. + {"azuresb://mytopic?subscription=mysub&listener_timeout=xxx", true}, + // Invalid parameter. + {"azuresb://mytopic?subscription=mysub¶m=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + sub, err := pubsub.OpenSubscription(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if sub != nil { + sub.Shutdown(ctx) + } + } +} diff --git a/go-cloud/pubsub/azuresb/example_test.go b/go-cloud/pubsub/azuresb/example_test.go new file mode 100644 index 000000000..b398bad81 --- /dev/null +++ b/go-cloud/pubsub/azuresb/example_test.go @@ -0,0 +1,156 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 azuresb_test + +import ( + "context" + "log" + "os" + + servicebus "github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/azuresb" +) + +func ExampleOpenTopic() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Change these as needed for your application. + connString := os.Getenv("SERVICEBUS_CONNECTION_STRING") + topicName := "test-topic" + + if connString == "" { + log.Fatal("Service Bus ConnectionString is not set") + } + + // Connect to Azure Service Bus for the given topic. + sbClient, err := azuresb.NewClientFromConnectionString(connString, nil) + if err != nil { + log.Fatal(err) + } + sbSender, err := azuresb.NewSender(sbClient, topicName, nil) + if err != nil { + log.Fatal(err) + } + defer sbSender.Close(ctx) + + // Construct a *pubsub.Topic. + topic, err := azuresb.OpenTopic(ctx, sbSender, nil) + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func Example_openTopicFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/azuresb" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenTopic creates a *pubsub.Topic from a URL. + // This URL will open the topic "mytopic" using a connection string + // from the environment variable SERVICEBUS_CONNECTION_STRING. + topic, err := pubsub.OpenTopic(ctx, "azuresb://mytopic") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func ExampleOpenSubscription() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Change these as needed for your application. + serviceBusConnString := os.Getenv("SERVICEBUS_CONNECTION_STRING") + const topicName = "test-topic" + const subscriptionName = "test-subscription" + + // Connect to Azure Service Bus for the given subscription. + sbClient, err := azuresb.NewClientFromConnectionString(serviceBusConnString, nil) + if err != nil { + log.Fatal(err) + } + sbReceiver, err := azuresb.NewReceiver(sbClient, topicName, subscriptionName, nil) + if err != nil { + log.Fatal(err) + } + defer sbReceiver.Close(ctx) + + // Construct a *pubsub.Subscription. + subscription, err := azuresb.OpenSubscription(ctx, sbClient, sbReceiver, nil) + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} + +func Example_openSubscriptionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/azuresb" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenSubscription creates a *pubsub.Subscription from a URL. + // This URL will open the subscription "mysubscription" for the topic + // "mytopic" using a connection string from the environment variable + // SERVICEBUS_CONNECTION_STRING. + subscription, err := pubsub.OpenSubscription(ctx, + "azuresb://mytopic?subscription=mysubscription") + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} + +func ExampleOpenSubscription_inReceiveAndDeleteMode() { + ctx := context.Background() + + // Change these as needed for your application. + serviceBusConnString := os.Getenv("SERVICEBUS_CONNECTION_STRING") + const topicName = "test-topic" + const subscriptionName = "test-subscription" + + // Connect to Azure Service Bus for the given subscription. + sbClient, err := azuresb.NewClientFromConnectionString(serviceBusConnString, nil) + if err != nil { + log.Fatal(err) + } + // Create the azuresb.Subscription, configuring it with the + // ReceiveAndDelete option. + // See https://godoc.org/github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus#SubscriptionWithReceiveAndDelete. + sbReceiverOptions := &servicebus.ReceiverOptions{ + ReceiveMode: servicebus.ReceiveModeReceiveAndDelete, + } + sbReceiver, err := azuresb.NewReceiver(sbClient, topicName, subscriptionName, sbReceiverOptions) + if err != nil { + log.Fatal(err) + } + defer sbReceiver.Close(ctx) + + // Construct a *pubsub.Subscription. Since we configured + // the azuresb.Subscription with ReceiveAndDelete mode, we need + // to set SubscriptionOptions.ReceiveAndDelete = true. + subscription, err := azuresb.OpenSubscription(ctx, + sbClient, sbReceiver, &azuresb.SubscriptionOptions{ReceiveAndDelete: true}) + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} diff --git a/go-cloud/pubsub/azuresb/testdata/README b/go-cloud/pubsub/azuresb/testdata/README new file mode 100644 index 000000000..17d5ffaa7 --- /dev/null +++ b/go-cloud/pubsub/azuresb/testdata/README @@ -0,0 +1,2 @@ +This directory is here just so that the prerelease script (internal/testing/prerelease.sh) +will run this package's tests with -record. diff --git a/go-cloud/pubsub/batcher/batcher.go b/go-cloud/pubsub/batcher/batcher.go new file mode 100644 index 000000000..e8829fbb5 --- /dev/null +++ b/go-cloud/pubsub/batcher/batcher.go @@ -0,0 +1,301 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 batcher supports batching of items. Create a Batcher with a handler and +// add items to it. Items are accumulated while handler calls are in progress; when +// the handler returns, it will be called again with items accumulated since the last +// call. Multiple concurrent calls to the handler are supported. +package batcher // import "gocloud.dev/pubsub/batcher" + +import ( + "context" + "errors" + "reflect" + "sync" +) + +// Split determines how to split n (representing n items) into batches based on +// opts. It returns a slice of batch sizes. +// +// For example, Split(10) might return [10], [5, 5], or [2, 2, 2, 2, 2] +// depending on opts. opts may be nil to accept defaults. +// +// Split will return nil if n is less than o.MinBatchSize. +// +// The sum of returned batches may be less than n (e.g., if n is 10x larger +// than o.MaxBatchSize, but o.MaxHandlers is less than 10). +func Split(n int, opts *Options) []int { + o := newOptionsWithDefaults(opts) + if n < o.MinBatchSize { + // No batch yet. + return nil + } + if o.MaxBatchSize == 0 { + // One batch is fine. + return []int{n} + } + + // TODO(rvangent): Consider trying to even out the batch sizes. + // For example, n=10 with MaxBatchSize 9 and MaxHandlers 2 will Split + // to [9, 1]; it could be [5, 5]. + var batches []int + for n >= o.MinBatchSize && len(batches) < o.MaxHandlers { + b := o.MaxBatchSize + if b > n { + b = n + } + batches = append(batches, b) + n -= b + } + return batches +} + +// A Batcher batches items. +type Batcher struct { + opts Options + handler func(any) error + itemSliceZero reflect.Value // nil (zero value) for slice of items + wg sync.WaitGroup // tracks active Add calls + + mu sync.Mutex + pending []waiter // items waiting to be handled + nHandlers int // number of currently running handler goroutines + shutdown bool +} + +// Message is larger than the maximum batch byte size +var ErrMessageTooLarge = errors.New("batcher: message too large") + +type sizableItem interface { + ByteSize() int +} + +type waiter struct { + item any + errc chan error +} + +// Options sets options for Batcher. +type Options struct { + // Maximum number of concurrent handlers. Defaults to 1. + MaxHandlers int + // Minimum size of a batch. Defaults to 1. + // May be ignored during shutdown. + MinBatchSize int + // Maximum size of a batch. 0 means no limit. + MaxBatchSize int + // Maximum bytesize of a batch. 0 means no limit. + MaxBatchByteSize int +} + +// newOptionsWithDefaults returns Options with defaults applied to opts. +// opts may be nil to accept all defaults. +func newOptionsWithDefaults(opts *Options) Options { + var o Options + if opts != nil { + o = *opts + } + if o.MaxHandlers == 0 { + o.MaxHandlers = 1 + } + if o.MinBatchSize == 0 { + o.MinBatchSize = 1 + } + return o +} + +// newMergedOptions returns o merged with opts. +func (o *Options) NewMergedOptions(opts *Options) *Options { + maxH := o.MaxHandlers + if opts.MaxHandlers != 0 && (maxH == 0 || opts.MaxHandlers < maxH) { + maxH = opts.MaxHandlers + } + minB := o.MinBatchSize + if opts.MinBatchSize != 0 && (minB == 0 || opts.MinBatchSize > minB) { + minB = opts.MinBatchSize + } + maxB := o.MaxBatchSize + if opts.MaxBatchSize != 0 && (maxB == 0 || opts.MaxBatchSize < maxB) { + maxB = opts.MaxBatchSize + } + maxBB := o.MaxBatchByteSize + if opts.MaxBatchByteSize != 0 && (maxBB == 0 || opts.MaxBatchByteSize < maxBB) { + maxBB = opts.MaxBatchByteSize + } + c := &Options{ + MaxHandlers: maxH, + MinBatchSize: minB, + MaxBatchSize: maxB, + MaxBatchByteSize: maxBB, + } + return c +} + +// New creates a new Batcher. +// +// itemType is type that will be batched. For example, if you +// want to create batches of *Entry, pass reflect.TypeOf(&Entry{}) for itemType. +// +// opts can be nil to accept defaults. +// +// handler is a function that will be called on each bundle. If itemExample is +// of type T, the argument to handler is of type []T. +func New(itemType reflect.Type, opts *Options, handler func(any) error) *Batcher { + return &Batcher{ + opts: newOptionsWithDefaults(opts), + handler: handler, + itemSliceZero: reflect.Zero(reflect.SliceOf(itemType)), + } +} + +// Add adds an item to the batcher. It blocks until the handler has +// processed the item and reports the error that the handler returned. +// If Shutdown has been called, Add immediately returns an error. +func (b *Batcher) Add(ctx context.Context, item any) error { + c := b.AddNoWait(item) + // Wait until either our result is ready or the context is done. + select { + case err := <-c: + return err + case <-ctx.Done(): + return ctx.Err() + } +} + +// AddNoWait adds an item to the batcher and returns immediately. When the handler is +// called on the item, the handler's error return value will be sent to the channel +// returned from AddNoWait. +func (b *Batcher) AddNoWait(item any) <-chan error { + b.mu.Lock() + defer b.mu.Unlock() + + // Create a channel to receive the error from the handler. + c := make(chan error, 1) + if b.shutdown { + c <- errors.New("batcher: shut down") + return c + } + + if b.opts.MaxBatchByteSize > 0 { + if sizable, ok := item.(sizableItem); ok { + if sizable.ByteSize() > b.opts.MaxBatchByteSize { + c <- ErrMessageTooLarge + return c + } + } + } + + // Add the item to the pending list. + b.pending = append(b.pending, waiter{item, c}) + if b.nHandlers < b.opts.MaxHandlers { + // If we can start a handler, do so with the item just added and any others that are pending. + b.handleBatch(b.nextBatch()) + } + // If we can't start a handler, then one of the currently running handlers will + // take our item. + return c +} + +// Requires b.mu be held. +func (b *Batcher) handleBatch(batch []waiter) { + if len(batch) == 0 { + return + } + b.wg.Add(1) + go func() { + b.callHandler(batch) + b.wg.Done() + }() + b.nHandlers++ +} + +// nextBatch returns the batch to process, and updates b.pending. +// It returns nil if there's no batch ready for processing. +// b.mu must be held. +func (b *Batcher) nextBatch() []waiter { + // If we're not shutting down, respect minimums. If we're shutting down + // though, we ignore minimums to make sure everything is flushed. + if !b.shutdown && len(b.pending) < b.opts.MinBatchSize { + return nil + } + + if b.opts.MaxBatchByteSize == 0 && (b.opts.MaxBatchSize == 0 || len(b.pending) <= b.opts.MaxBatchSize) { + // Send it all! + batch := b.pending + b.pending = nil + return batch + } + + batch := make([]waiter, 0, len(b.pending)) + batchByteSize := 0 + for _, msg := range b.pending { + itemByteSize := 0 + if sizable, ok := msg.item.(sizableItem); ok { + itemByteSize = sizable.ByteSize() + } + reachedMaxSize := b.opts.MaxBatchSize > 0 && len(batch)+1 > b.opts.MaxBatchSize + reachedMaxByteSize := b.opts.MaxBatchByteSize > 0 && batchByteSize+itemByteSize > b.opts.MaxBatchByteSize + + if reachedMaxSize || reachedMaxByteSize { + break + } + batch = append(batch, msg) + batchByteSize = batchByteSize + itemByteSize + } + + b.pending = b.pending[len(batch):] + return batch +} + +func (b *Batcher) callHandler(batch []waiter) { + for batch != nil { + + // Collect the items into a slice of the example type. + items := b.itemSliceZero + for _, m := range batch { + items = reflect.Append(items, reflect.ValueOf(m.item)) + } + // Call the handler and report the result to all waiting + // callers of Add. + err := b.handler(items.Interface()) + for _, m := range batch { + m.errc <- err + } + b.mu.Lock() + // If there is more work, keep running; otherwise exit. Take the new batch + // and decrement the handler count atomically, so that newly added items will + // always get to run. + batch = b.nextBatch() + if batch == nil { + b.nHandlers-- + } + b.mu.Unlock() + } +} + +// Shutdown waits for all active calls to Add to finish, then +// returns. After Shutdown is called, all subsequent calls to Add fail. +// Shutdown should be called only once. +func (b *Batcher) Shutdown() { + b.mu.Lock() + b.shutdown = true + // If there aren't any handlers running, there might be a partial + // batch. Make sure it gets flushed even if it hasn't reached the + // minimums. + if b.nHandlers == 0 { + b.handleBatch(b.nextBatch()) + } + b.mu.Unlock() + b.wg.Wait() +} diff --git a/go-cloud/pubsub/batcher/batcher_test.go b/go-cloud/pubsub/batcher/batcher_test.go new file mode 100644 index 000000000..21e217ba9 --- /dev/null +++ b/go-cloud/pubsub/batcher/batcher_test.go @@ -0,0 +1,316 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 batcher_test + +import ( + "bytes" + "context" + "errors" + "io" + "reflect" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/batcher" +) + +func TestSplit(t *testing.T) { + tests := []struct { + n int + opts *batcher.Options + want []int + }{ + // Defaults. + {0, nil, nil}, + {1, nil, []int{1}}, + {10, nil, []int{10}}, + // MinBatchSize. + {4, &batcher.Options{MinBatchSize: 5}, nil}, + {8, &batcher.Options{MinBatchSize: 5, MaxBatchSize: 7}, []int{7}}, + // <= MaxBatchSize. + {5, &batcher.Options{MaxBatchSize: 5}, []int{5}}, + {9, &batcher.Options{MaxBatchSize: 10}, []int{9}}, + // > MaxBatchSize with MaxHandlers = 1. + {5, &batcher.Options{MaxBatchSize: 4}, []int{4}}, + {999, &batcher.Options{MaxBatchSize: 10}, []int{10}}, + // MaxBatchSize with MaxHandlers > 1. + {10, &batcher.Options{MaxBatchSize: 4, MaxHandlers: 2}, []int{4, 4}}, + {10, &batcher.Options{MaxBatchSize: 5, MaxHandlers: 2}, []int{5, 5}}, + {10, &batcher.Options{MaxBatchSize: 9, MaxHandlers: 2}, []int{9, 1}}, + {9, &batcher.Options{MaxBatchSize: 4, MaxHandlers: 3}, []int{4, 4, 1}}, + {10, &batcher.Options{MaxBatchSize: 4, MaxHandlers: 3}, []int{4, 4, 2}}, + // All 3 options together. + {8, &batcher.Options{MinBatchSize: 5, MaxBatchSize: 7, MaxHandlers: 2}, []int{7}}, + } + + for _, test := range tests { + got := batcher.Split(test.n, test.opts) + if diff := cmp.Diff(got, test.want); diff != "" { + t.Errorf("%d/%#v: got %v want %v diff %s", test.n, test.opts, got, test.want, diff) + } + } +} + +func TestSequential(t *testing.T) { + // Verify that sequential non-concurrent Adds to a batcher produce single-item batches. + // Since there is no concurrent work, the Batcher will always produce the items one at a time. + ctx := context.Background() + var got []int + e := errors.New("e") + b := batcher.New(reflect.TypeOf(int(0)), nil, func(items any) error { + got = items.([]int) + return e + }) + for i := 0; i < 10; i++ { + err := b.Add(ctx, i) + if err != e { + t.Errorf("got %v, want %v", err, e) + } + want := []int{i} + if !cmp.Equal(got, want) { + t.Errorf("got %+v, want %+v", got, want) + } + } +} + +type sizableItem struct { + byteSize int +} + +func (i *sizableItem) ByteSize() int { + return i.byteSize +} + +func TestPreventsAddingItemsLargerThanBatchMaxByteSize(t *testing.T) { + ctx := context.Background() + itemType := reflect.TypeOf(&sizableItem{}) + b := batcher.New(itemType, &batcher.Options{MaxBatchByteSize: 1}, func(items any) error { + return nil + }) + + err := b.Add(ctx, &sizableItem{2}) + e := batcher.ErrMessageTooLarge + if err != e { + t.Errorf("got %v, want %v", err, e) + } + + err = b.Add(ctx, &sizableItem{1}) + if err != nil { + t.Errorf("got error %v, want nil", err) + } +} + +func TestBatchingConsidersMaxSizeAndMaxByteSize(t *testing.T) { + ctx := context.Background() + itemType := reflect.TypeOf(&sizableItem{}) + tests := []struct { + itemCount int + itemSize int + opts *batcher.Options + wantBatchCount int + }{ + {10, 0, &batcher.Options{MaxBatchSize: 2, MinBatchSize: 2}, 5}, + {10, 10, &batcher.Options{MaxBatchByteSize: 10, MinBatchSize: 1}, 10}, + {10, 5, &batcher.Options{MaxBatchByteSize: 10, MinBatchSize: 2}, 5}, + } + + for _, test := range tests { + var got [][]*sizableItem + b := batcher.New(itemType, test.opts, func(items any) error { + got = append(got, items.([]*sizableItem)) + return nil + }) + + var wg sync.WaitGroup + item := &sizableItem{test.itemSize} + for i := 0; i < test.itemCount; i++ { + wg.Add(1) + go func() { + defer wg.Done() + if err := b.Add(ctx, item); err != nil { + t.Errorf("b.Add(ctx, item) error: %v", err) + } + }() + } + wg.Wait() + if len(got) != test.wantBatchCount { + t.Errorf("got %d batches, want %d", len(got), test.wantBatchCount) + } + } +} + +func TestMinBatchSize(t *testing.T) { + // Verify the MinBatchSize option works. + var got [][]int + b := batcher.New(reflect.TypeOf(int(0)), &batcher.Options{MinBatchSize: 3}, func(items any) error { + got = append(got, items.([]int)) + return nil + }) + for i := 0; i < 6; i++ { + b.AddNoWait(i) + } + b.Shutdown() + want := [][]int{{0, 1, 2}, {3, 4, 5}} + if !cmp.Equal(got, want) { + t.Errorf("got %+v, want %+v", got, want) + } +} + +func TestSaturation(t *testing.T) { + // Verify that under high load the maximum number of handlers are running. + ctx := context.Background() + const ( + maxHandlers = 10 + maxBatchSize = 50 + ) + var ( + mu sync.Mutex + outstanding, max int // number of handlers + maxBatch int // size of largest batch + count = map[int]int{} // how many of each item the handlers observe + ) + b := batcher.New(reflect.TypeOf(int(0)), &batcher.Options{MaxHandlers: maxHandlers, MaxBatchSize: maxBatchSize}, func(x any) error { + items := x.([]int) + mu.Lock() + outstanding++ + if outstanding > max { + max = outstanding + } + for _, x := range items { + count[x]++ + } + if len(items) > maxBatch { + maxBatch = len(items) + } + mu.Unlock() + defer func() { mu.Lock(); outstanding--; mu.Unlock() }() + // Sleep a little to increase the likelihood of saturation. + time.Sleep(10 * time.Millisecond) + return nil + }) + var wg sync.WaitGroup + const nItems = 1000 + for i := 0; i < nItems; i++ { + i := i + wg.Add(1) + go func() { + defer wg.Done() + // Sleep a little to increase the likelihood of saturation. + time.Sleep(time.Millisecond) + if err := b.Add(ctx, i); err != nil { + t.Errorf("b.Add(ctx, %d) error: %v", i, err) + } + }() + } + wg.Wait() + // Check that we saturated the batcher. + if max != maxHandlers { + t.Errorf("max concurrent handlers = %d, want %d", max, maxHandlers) + } + // Check that at least one batch had more than one item. + if maxBatch <= 1 || maxBatch > maxBatchSize { + t.Errorf("got max batch size of %d, expected > 1 and <= %d", maxBatch, maxBatchSize) + } + // Check that handlers saw every item exactly once. + want := map[int]int{} + for i := 0; i < nItems; i++ { + want[i] = 1 + } + if diff := cmp.Diff(count, want); diff != "" { + t.Errorf("items: %s", diff) + } +} + +func TestShutdown(t *testing.T) { + ctx := context.Background() + var nHandlers int64 // atomic + c := make(chan int, 10) + b := batcher.New(reflect.TypeOf(int(0)), &batcher.Options{MaxHandlers: cap(c)}, func(x any) error { + for range x.([]int) { + c <- 0 + } + atomic.AddInt64(&nHandlers, 1) + defer atomic.AddInt64(&nHandlers, -1) + time.Sleep(time.Second) // we want handlers to be active on Shutdown + return nil + }) + for i := 0; i < cap(c); i++ { + go func() { + err := b.Add(ctx, 0) + if err != nil { + t.Errorf("b.Add error: %v", err) + } + }() + } + // Make sure all goroutines have started. + for i := 0; i < cap(c); i++ { + <-c + } + b.Shutdown() + + if got := atomic.LoadInt64(&nHandlers); got != 0 { + t.Fatalf("%d Handlers still active after Shutdown returns", got) + } + if err := b.Add(ctx, 1); err == nil { + t.Error("got nil, want error from Add after Shutdown") + } +} + +// TestMinBatchSizeFlushesOnShutdown ensures that Shutdown() flushes batches, even if +// the pending count is less than the minimum batch size. +func TestMinBatchSizeFlushesOnShutdown(t *testing.T) { + var got [][]int + + batchSize := 3 + b := batcher.New(reflect.TypeOf(int(0)), &batcher.Options{MinBatchSize: batchSize}, func(items interface{}) error { + got = append(got, items.([]int)) + return nil + }) + for i := 0; i < (batchSize - 1); i++ { + b.AddNoWait(i) + } + + // Ensure that we've received nothing + if len(got) > 0 { + t.Errorf("got batch unexpectedly: %+v", got) + } + + b.Shutdown() + + want := [][]int{{0, 1}} + if !cmp.Equal(got, want) { + t.Errorf("got %+v, want %+v on shutdown", got, want) + } +} + +func TestItemCanBeInterface(t *testing.T) { + readerType := reflect.TypeOf([]io.Reader{}).Elem() + called := false + b := batcher.New(readerType, nil, func(items any) error { + called = true + _, ok := items.([]io.Reader) + if !ok { + t.Fatal("items is not a []io.Reader") + } + return nil + }) + b.Add(context.Background(), &bytes.Buffer{}) + if !called { + t.Fatal("handler not called") + } +} diff --git a/go-cloud/pubsub/benchmark_test.go b/go-cloud/pubsub/benchmark_test.go new file mode 100644 index 000000000..8ae76c8ba --- /dev/null +++ b/go-cloud/pubsub/benchmark_test.go @@ -0,0 +1,313 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 pubsub + +import ( + "context" + "errors" + "fmt" + "math/rand" + "sync" + "testing" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" + "golang.org/x/sync/errgroup" +) + +const ( + // How long to run the test. + runFor = 25 * time.Second + // How long the "warmup period" is, during which we report more frequently. + reportWarmup = 500 * time.Millisecond + // Minimum frequency for reporting throughput, during warmup and after that. + reportPeriodWarmup = 50 * time.Millisecond + reportPeriod = 1 * time.Second + // Number of output lines per test. We set this to a constant so that it's + // easy to copy/paste the output into a Google Sheet with pre-created graphs. + // Should be above runFor / reportPeriod + reportWarmup / reportPeriodWarmup. + numLinesPerTest = 50 + // Number of data points to smooth msgs/sec and RPCs/sec over. + smoothing = 5 +) + +type fakeSub struct { + driver.Subscription + start time.Time + profile func(bool, int) (int, time.Duration) + msgs []*driver.Message +} + +func (*fakeSub) SendAcks(ctx context.Context, ackIDs []driver.AckID) error { return nil } +func (*fakeSub) CanNack() bool { return false } +func (*fakeSub) Close() error { return nil } + +func (s *fakeSub) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + n, delay := s.profile(s.inMiddleThird(), maxMessages) + if delay > 0 { + time.Sleep(delay) + } + return s.msgs[:n], nil +} + +// inMiddleThird returns true if this test is in the middle third of the running +// time; used for burstiness tests. +func (s *fakeSub) inMiddleThird() bool { + elapsed := time.Since(s.start) + return elapsed > runFor/3 && elapsed < runFor*2/3 +} + +// TestReceivePerformance enables characterization of Receive under various +// situations, characterized in "tests" below. +func TestReceivePerformance(t *testing.T) { + t.Skip("Skipped by default") + + const defaultNumGoRoutines = 100 + defaultReceiveProfile := func(_ bool, maxMessages int) (int, time.Duration) { return maxMessages, 0 } + defaultProcessProfile := func(bool) time.Duration { return 0 } + + tests := []struct { + description string + // See the defaults above. + numGoRoutines int + receiveProfile func(bool, int) (int, time.Duration) + processProfile func(bool) time.Duration + }{ + { + description: "baseline", + }, + { + description: "1 goroutine", + numGoRoutines: 1, + }, + { + description: "receive 100ms", + receiveProfile: func(_ bool, maxMessages int) (int, time.Duration) { return maxMessages, 100 * time.Millisecond }, + }, + { + description: "receive 1s", + receiveProfile: func(_ bool, maxMessages int) (int, time.Duration) { return maxMessages, 1 * time.Second }, + }, + { + description: "process 100ms", + processProfile: func(bool) time.Duration { return 100 * time.Millisecond }, + }, + { + description: "process 1s", + processProfile: func(bool) time.Duration { return 1 * time.Second }, + }, + { + description: "receive 1s process 70ms", + receiveProfile: func(_ bool, maxMessages int) (int, time.Duration) { + return maxMessages, 1 * time.Second + }, + processProfile: func(bool) time.Duration { return 70 * time.Millisecond }, + }, + { + description: "receive 250ms+stddev 150ms, process 10ms + stddev 5ms", + receiveProfile: func(_ bool, maxMessages int) (int, time.Duration) { + return maxMessages, time.Duration(rand.NormFloat64()*150+250) * time.Millisecond + }, + processProfile: func(bool) time.Duration { return time.Duration(rand.NormFloat64()*5+10) * time.Millisecond }, + }, + { + description: "bursty message arrival", + receiveProfile: func(inMiddleThird bool, maxMessages int) (int, time.Duration) { + // When in the middle third of the running time, return 0 messages. + n := maxMessages + if inMiddleThird { + n = 0 + } + return n, time.Duration(rand.NormFloat64()*25+100) * time.Millisecond + }, + processProfile: func(bool) time.Duration { return time.Duration(rand.NormFloat64()*5+10) * time.Millisecond }, + }, + { + description: "bursty receive time", + receiveProfile: func(inMiddleThird bool, maxMessages int) (int, time.Duration) { + // When in the middle third of the running time, 10x the RPC time. + d := time.Duration(rand.NormFloat64()*25+100) * time.Millisecond + if inMiddleThird { + d *= 10 + } + return maxMessages, d + }, + processProfile: func(bool) time.Duration { return time.Duration(rand.NormFloat64()*5+10) * time.Millisecond }, + }, + { + description: "bursty process time", + receiveProfile: func(_ bool, maxMessages int) (int, time.Duration) { + return maxMessages, time.Duration(rand.NormFloat64()*25+100) * time.Millisecond + }, + processProfile: func(inMiddleThird bool) time.Duration { + d := time.Duration(rand.NormFloat64()*5+10) * time.Millisecond + if inMiddleThird { + d *= 100 + } + return d + }, + }, + { + description: "intermittent", + receiveProfile: func(_ bool, maxMessages int) (int, time.Duration) { + n := rand.Int() % 2 + return n, 250 * time.Millisecond + }, + }, + } + + for _, test := range tests { + if test.numGoRoutines == 0 { + test.numGoRoutines = defaultNumGoRoutines + } + if test.receiveProfile == nil { + test.receiveProfile = defaultReceiveProfile + } + if test.processProfile == nil { + test.processProfile = defaultProcessProfile + } + t.Run(test.description, func(t *testing.T) { + runBenchmark(t, test.description, test.numGoRoutines, test.receiveProfile, test.processProfile) + }) + } +} + +func runBenchmark(t *testing.T, description string, numGoRoutines int, receiveProfile func(bool, int) (int, time.Duration), processProfile func(bool) time.Duration) { + t.Helper() + + msgs := make([]*driver.Message, maxBatchSize) + for i := range msgs { + msgs[i] = &driver.Message{} + } + + fake := &fakeSub{msgs: msgs, profile: receiveProfile, start: time.Now()} + sub := newSubscription(fake, nil, nil) + defer sub.Shutdown(context.Background()) + + // Header row. + fmt.Printf("%s\tmsgs/sec\tRPCs/sec\tbatchsize\n", description) + + var mu sync.Mutex + start := time.Now() + var lastReport time.Time + numMsgs := 0 + var prevMsgsPerSec, prevRPCsPerSec []float64 // last datapoints + var runningMsgsPerSec, runningRPCsPerSec float64 // sum of values in above slices + numRPCs := 0 + lastMaxMessages := 0 + nLines := 1 // header + + // mu must be locked when called. + reportLine := func(now time.Time) { + elapsed := now.Sub(start) + elapsedSinceReport := now.Sub(lastReport) + + // Smooth msgsPerSec over the last datapoints. + msgsPerSec := float64(numMsgs) / elapsedSinceReport.Seconds() + prevMsgsPerSec = append(prevMsgsPerSec, msgsPerSec) + runningMsgsPerSec += msgsPerSec + if len(prevMsgsPerSec) > smoothing { + runningMsgsPerSec -= prevMsgsPerSec[0] + if runningMsgsPerSec < 0 { + runningMsgsPerSec = 0 + } + prevMsgsPerSec = prevMsgsPerSec[1:] + } + + // Smooth rpcsPerSec over the last datapoints. + rpcsPerSec := float64(numRPCs) / elapsedSinceReport.Seconds() + prevRPCsPerSec = append(prevRPCsPerSec, rpcsPerSec) + runningRPCsPerSec += rpcsPerSec + if len(prevRPCsPerSec) > smoothing { + runningRPCsPerSec -= prevRPCsPerSec[0] + if runningRPCsPerSec < 0 { + runningRPCsPerSec = 0 + } + prevRPCsPerSec = prevRPCsPerSec[1:] + } + + fmt.Printf("%f\t%f\t%f\t%d\n", elapsed.Seconds(), runningMsgsPerSec/float64(len(prevMsgsPerSec)), runningRPCsPerSec/float64(len(prevRPCsPerSec)), lastMaxMessages) + nLines++ + + lastReport = now + numMsgs = 0 + numRPCs = 0 + } + + sub.preReceiveBatchHook = func(maxMessages int) { + mu.Lock() + defer mu.Unlock() + lastMaxMessages = maxMessages + numRPCs++ + if lastReport.IsZero() { + reportLine(time.Now()) + } + } + + ctx, cancel := context.WithTimeout(context.Background(), runFor) + defer cancel() + done := make(chan struct{}) + go func() { + period := reportPeriodWarmup + for { + select { + case now := <-time.After(period): + mu.Lock() + reportLine(now) + mu.Unlock() + if now.Sub(start) > reportWarmup { + period = reportPeriod + } + case <-ctx.Done(): + close(done) + return + } + } + }() + + var grp errgroup.Group + for i := 0; i < numGoRoutines; i++ { + grp.Go(func() error { + // Each goroutine loops until ctx is canceled. + for { + m, err := sub.Receive(ctx) + if errors.Is(err, context.DeadlineExceeded) { + return nil + } + if err != nil { + return err + } + mu.Lock() + numMsgs++ + mu.Unlock() + delay := processProfile(fake.inMiddleThird()) + if delay > 0 { + time.Sleep(delay) + } + m.Ack() + } + }) + } + if err := grp.Wait(); err != nil { + t.Errorf("%s: %v", description, err) + } + <-done + if nLines > numLinesPerTest { + t.Errorf("produced too many lines (%d)", nLines) + } + for n := nLines; n < numLinesPerTest; n++ { + fmt.Println() + } +} diff --git a/go-cloud/pubsub/driver/driver.go b/go-cloud/pubsub/driver/driver.go new file mode 100644 index 000000000..b2601e308 --- /dev/null +++ b/go-cloud/pubsub/driver/driver.go @@ -0,0 +1,221 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 driver defines interfaces to be implemented by pubsub drivers, which +// will be used by the pubsub package to interact with the underlying services. +// Application code should use package pubsub. +package driver // import "gocloud.dev/pubsub/driver" + +import ( + "context" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +// AckID is the identifier of a message for purposes of acknowledgement. +type AckID any + +// AckInfo represents an action on an AckID. +type AckInfo struct { + // AckID is the AckID the action is for. + AckID AckID + // IsAck is true if the AckID should be acked, false if it should be nacked. + IsAck bool +} + +// Message is data to be published (sent) to a topic and later received from +// subscriptions on that topic. +type Message struct { + // LoggableID should be set to an opaque message identifer for + // received messages. + LoggableID string + + // Body contains the content of the message. + Body []byte + + // Metadata has key/value pairs describing the message. + Metadata map[string]string + + // AckID should be set to something identifying the message on the + // server. It may be passed to Subscription.SendAcks to acknowledge + // the message, or to Subscription.SendNacks. This field should only + // be set by methods implementing Subscription.ReceiveBatch. + AckID AckID + + // AsFunc allows drivers to expose driver-specific types; + // see Topic.As for more details. + // AsFunc must be populated on messages returned from ReceiveBatch. + AsFunc func(any) bool + + // BeforeSend is a callback used when sending a message. It should remain + // nil on messages returned from ReceiveBatch. + // + // The callback must be called exactly once, before the message is sent. + // + // asFunc converts its argument to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + BeforeSend func(asFunc func(any) bool) error + + // AfterSend is a callback used when sending a message. It should remain + // nil on messages returned from ReceiveBatch. + // + // The callback must be called at most once, after the message is sent. + // If Send returns an error, AfterSend will not be called. + // + // asFunc converts its argument to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + AfterSend func(asFunc func(any) bool) error +} + +// ByteSize estimates the size in bytes of the message for the purpose of restricting batch sizes. +func (m *Message) ByteSize() int { + return len(m.Body) +} + +// Topic publishes messages. +// Drivers may optionally also implement io.Closer; Close will be called +// when the pubsub.Topic is Shutdown. +type Topic interface { + // SendBatch should publish all the messages in ms. It should + // return only after all the messages are sent, an error occurs, or the + // context is done. + // + // Only the Body and (optionally) Metadata fields of the Messages in ms + // will be set by the caller of SendBatch. + // + // If any message in the batch fails to send, SendBatch should return an + // error. + // + // If there is a transient failure, this method should not retry but + // should return an error for which IsRetryable returns true. The + // concrete API takes care of retry logic. + // + // The slice ms should not be retained past the end of the call to + // SendBatch. + // + // SendBatch may be called concurrently from multiple goroutines. + // + // Drivers can control the number of messages sent in a single batch + // and the concurrency of calls to SendBatch via a batcher.Options + // passed to pubsub.NewTopic. + SendBatch(ctx context.Context, ms []*Message) error + + // IsRetryable should report whether err can be retried. + // err will always be a non-nil error returned from SendBatch. + IsRetryable(err error) bool + + // As allows drivers to expose driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + As(i any) bool + + // ErrorAs allows drivers to expose driver-specific types for errors. + // See https://gocloud.dev/concepts/as/ for background information. + ErrorAs(error, any) bool + + // ErrorCode should return a code that describes the error, which was returned by + // one of the other methods in this interface. + ErrorCode(error) gcerrors.ErrorCode + + // Close cleans up any resources used by the Topic. Once Close is called, + // there will be no method calls to the Topic other than As, ErrorAs, and + // ErrorCode. + Close() error +} + +// Subscription receives published messages. +// Drivers may optionally also implement io.Closer; Close will be called +// when the pubsub.Subscription is Shutdown. +type Subscription interface { + // ReceiveBatch should return a batch of messages that have queued up + // for the subscription on the server, up to maxMessages. + // + // If there is a transient failure, this method should not retry but + // should return a nil slice and an error. The concrete API will take + // care of retry logic. + // + // If no messages are currently available, this method should block for + // no more than about 1 second. It can return an empty + // slice of messages and no error. ReceiveBatch will be called again + // immediately, so implementations should try to wait for messages for some + // non-zero amount of time before returning zero messages. If the underlying + // service doesn't support waiting, then a time.Sleep can be used. + // + // ReceiveBatch may be called concurrently from multiple goroutines. + // + // Drivers can control the maximum value of maxMessages and the concurrency + // of calls to ReceiveBatch via a batcher.Options passed to + // pubsub.NewSubscription. + ReceiveBatch(ctx context.Context, maxMessages int) ([]*Message, error) + + // SendAcks should acknowledge the messages with the given ackIDs on + // the server so that they will not be received again for this + // subscription if the server gets the acks before their deadlines. + // This method should return only after all the ackIDs are sent, an + // error occurs, or the context is done. + // + // It is acceptable for SendAcks to be a no-op for drivers that don't + // support message acknowledgement. + // + // Drivers should suppress errors caused by double-acking a message. + // + // SendAcks may be called concurrently from multiple goroutines. + // + // Drivers can control the maximum size of ackIDs and the concurrency + // of calls to SendAcks/SendNacks via a batcher.Options passed to + // pubsub.NewSubscription. + SendAcks(ctx context.Context, ackIDs []AckID) error + + // CanNack must return true iff the driver supports Nacking messages. + // + // If CanNack returns false, SendNacks will never be called, and Nack will + // panic if called. + CanNack() bool + + // SendNacks should notify the server that the messages with the given ackIDs + // are not being processed by this client, so that they will be received + // again later, potentially by another subscription. + // This method should return only after all the ackIDs are sent, an + // error occurs, or the context is done. + // + // If the service does not suppport nacking of messages, return false from + // CanNack, and SendNacks will never be called. + // + // SendNacks may be called concurrently from multiple goroutines. + // + // Drivers can control the maximum size of ackIDs and the concurrency + // of calls to SendAcks/Nacks via a batcher.Options passed to + // pubsub.NewSubscription. + SendNacks(ctx context.Context, ackIDs []AckID) error + + // IsRetryable should report whether err can be retried. + // err will always be a non-nil error returned from ReceiveBatch or SendAcks. + IsRetryable(err error) bool + + // As converts i to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + As(i any) bool + + // ErrorAs allows drivers to expose driver-specific types for errors. + // See https://gocloud.dev/concepts/as/ for background information. + ErrorAs(error, any) bool + + // ErrorCode should return a code that describes the error, which was returned by + // one of the other methods in this interface. + ErrorCode(error) gcerrors.ErrorCode + + // Close cleans up any resources used by the Topic. Once Close is called, + // there will be no method calls to the Topic other than As, ErrorAs, and + // ErrorCode. + Close() error +} diff --git a/go-cloud/pubsub/drivertest/drivertest.go b/go-cloud/pubsub/drivertest/drivertest.go new file mode 100644 index 000000000..6540080ef --- /dev/null +++ b/go-cloud/pubsub/drivertest/drivertest.go @@ -0,0 +1,1129 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 drivertest provides a conformance test for implementations of +// driver. +package drivertest // import "gocloud.dev/pubsub/drivertest" + +import ( + "bytes" + "context" + "errors" + "sort" + "strconv" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/escape" + "github.com/DataDog/iceberg-go/go-cloud/internal/retry" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/batcher" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" + "golang.org/x/sync/errgroup" +) + +// Harness descibes the functionality test harnesses must provide to run +// conformance tests. +type Harness interface { + // CreateTopic creates a new topic and returns a driver.Topic + // for testing. The topic may have to be removed manually if the test is + // abruptly terminated or the network connection fails. + CreateTopic(ctx context.Context, testName string) (dt driver.Topic, cleanup func(), err error) + + // MakeNonexistentTopic makes a driver.Topic referencing a topic that + // does not exist. + MakeNonexistentTopic(ctx context.Context) (driver.Topic, error) + + // CreateSubscription creates a new subscription, subscribed + // to the given topic, and returns a driver.Subscription for testing. The + // subscription may have to be cleaned up manually if the test is abruptly + // terminated or the network connection fails. + CreateSubscription(ctx context.Context, t driver.Topic, testName string) (ds driver.Subscription, cleanup func(), err error) + + // MakeNonexistentSubscription makes a driver.Subscription referencing a + // subscription that does not exist. + MakeNonexistentSubscription(ctx context.Context) (ds driver.Subscription, cleanup func(), err error) + + // Close closes resources used by the harness, but does not call Close + // on the Topics and Subscriptions generated by the Harness. + Close() + + // MaxBatchSizes returns the maximum size of SendBatch/Send(Na|A)cks, or 0 + // if there's no max. + MaxBatchSizes() (int, int) + + // SupportsMultipleSubscriptions reports whether the driver supports + // multiple subscriptions for the same topic. + SupportsMultipleSubscriptions() bool +} + +// HarnessMaker describes functions that construct a harness for running tests. +// It is called exactly once per test; Harness.Close() will be called when the test is complete. +type HarnessMaker func(ctx context.Context, t *testing.T) (Harness, error) + +// AsTest represents a test of As functionality. +// The conformance test: +// 1. Calls TopicCheck. +// 2. Calls SubscriptionCheck. +// 3. Sends a message, setting Message.BeforeSend to BeforeSend +// +// and Message.AfterSend to AfterSend. +// +// 4. Receives the message and calls MessageCheck. +// 5. Calls TopicErrorCheck. +// 6. Calls SubscriptionErrorCheck. +type AsTest interface { + // Name should return a descriptive name for the test. + Name() string + // TopicCheck will be called to allow verifcation of Topic.As. + TopicCheck(t *pubsub.Topic) error + // SubscriptionCheck will be called to allow verification of Subscription.As. + SubscriptionCheck(s *pubsub.Subscription) error + // TopicErrorCheck will be called to allow verification of Topic.ErrorAs. + // The error will be the one returned from SendBatch when called with + // a non-existent topic. + TopicErrorCheck(t *pubsub.Topic, err error) error + // SubscriptionErrorCheck will be called to allow verification of + // Subscription.ErrorAs. + // The error will be the one returned from ReceiveBatch when called with + // a non-existent subscription. + SubscriptionErrorCheck(s *pubsub.Subscription, err error) error + // MessageCheck will be called to allow verification of Message.As. + MessageCheck(m *pubsub.Message) error + // BeforeSend will be used as Message.BeforeSend as part of sending a test + // message. + BeforeSend(as func(any) bool) error + // AfterSend will be used as Message.AfterSend as part of sending a test + // message. + AfterSend(as func(any) bool) error +} + +// Many tests set the maximum batch size to 1 to make record/replay stable. +var batchSizeOne = &batcher.Options{MaxBatchSize: 1, MaxHandlers: 1} + +type verifyAsFailsOnNil struct{} + +func (verifyAsFailsOnNil) Name() string { + return "verify As returns false when passed nil" +} + +func (verifyAsFailsOnNil) TopicCheck(t *pubsub.Topic) error { + if t.As(nil) { + return errors.New("want Topic.As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) SubscriptionCheck(s *pubsub.Subscription) error { + if s.As(nil) { + return errors.New("want Subscription.As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) TopicErrorCheck(t *pubsub.Topic, err error) (ret error) { + defer func() { + if recover() == nil { + ret = errors.New("want Topic.ErrorAs to panic when passed nil") + } + }() + t.ErrorAs(err, nil) + return nil +} + +func (verifyAsFailsOnNil) SubscriptionErrorCheck(s *pubsub.Subscription, err error) (ret error) { + defer func() { + if recover() == nil { + ret = errors.New("want Subscription.ErrorAs to panic when passed nil") + } + }() + s.ErrorAs(err, nil) + return nil +} + +func (verifyAsFailsOnNil) MessageCheck(m *pubsub.Message) error { + if m.As(nil) { + return errors.New("want Message.As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) BeforeSend(as func(any) bool) error { + if as(nil) { + return errors.New("want Message.BeforeSend's As function to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) AfterSend(as func(any) bool) error { + if as(nil) { + return errors.New("want Message.AfterSend's As function to return false when passed nil") + } + return nil +} + +// RunConformanceTests runs conformance tests for driver implementations of pubsub. +func RunConformanceTests(t *testing.T, newHarness HarnessMaker, asTests []AsTest) { + t.Helper() + + tests := map[string]func(t *testing.T, newHarness HarnessMaker){ + "TestSendReceive": testSendReceive, + "TestSendReceiveTwo": testSendReceiveTwo, + "TestSendReceiveJSON": testSendReceiveJSON, + "TestNack": testNack, + "TestBatching": testBatching, + "TestDoubleAck": testDoubleAck, + "TestErrorOnSendToClosedTopic": testErrorOnSendToClosedTopic, + "TestErrorOnReceiveFromClosedSubscription": testErrorOnReceiveFromClosedSubscription, + "TestCancelSendReceive": testCancelSendReceive, + "TestNonExistentTopicSucceedsOnOpenButFailsOnSend": testNonExistentTopicSucceedsOnOpenButFailsOnSend, + "TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive": testNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive, + "TestMetadata": testMetadata, + "TestNonUTF8MessageBody": testNonUTF8MessageBody, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { test(t, newHarness) }) + } + + asTests = append(asTests, verifyAsFailsOnNil{}) + t.Run("TestAs", func(t *testing.T) { + for _, st := range asTests { + if st.Name() == "" { + t.Fatalf("AsTest.Name is required") + } + t.Run(st.Name(), func(t *testing.T) { testAs(t, newHarness, st) }) + } + }) +} + +// RunBenchmarks runs benchmarks for driver implementations of pubsub. +func RunBenchmarks(b *testing.B, topic *pubsub.Topic, sub *pubsub.Subscription) { + b.Helper() + + b.Run("BenchmarkReceive", func(b *testing.B) { + benchmark(b, topic, sub, false) + }) + b.Run("BenchmarkSend", func(b *testing.B) { + benchmark(b, topic, sub, true) + }) +} + +func testNonExistentTopicSucceedsOnOpenButFailsOnSend(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + // Set up. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + dt, err := h.MakeNonexistentTopic(ctx) + if err != nil { + // Failure shouldn't happen for non-existent topics until messages are sent + // to them. + t.Fatalf("creating a local topic that doesn't exist on the server: %v", err) + } + topic := pubsub.NewTopic(dt, nil) + defer func() { + if err := topic.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + + m := &pubsub.Message{} + err = topic.Send(ctx, m) + if err == nil || gcerrors.Code(err) != gcerrors.NotFound { + t.Errorf("got error %v for send to non-existent topic, want code=NotFound", err) + } +} + +func testNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + // Set up. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + ds, cleanup, err := h.MakeNonexistentSubscription(ctx) + if err != nil { + t.Fatalf("failed to make non-existent subscription: %v", err) + } + defer cleanup() + sub := pubsub.NewSubscription(ds, batchSizeOne, batchSizeOne) + defer func() { + if err := sub.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + + // The test will hang here if the message isn't available, so use a shorter timeout. + ctx2, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + _, err = sub.Receive(ctx2) + if err == nil || ctx2.Err() != nil || gcerrors.Code(err) != gcerrors.NotFound { + t.Errorf("got error %v for receive from non-existent subscription, want code=NotFound", err) + } +} + +func testSendReceive(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + // Set up. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + topic, sub, cleanup, err := makePair(ctx, t, h) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + want := publishN(ctx, t, topic, 3) + got := receiveN(ctx, t, sub, len(want)) + + // Verify LoggableID is set. + for _, msg := range got { + if msg.LoggableID == "" { + t.Errorf("msg.LoggableID was empty, should be set") + } + } + + // Check that the received messages match the sent ones. + if diff := diffMessageSets(got, want); diff != "" { + t.Error(diff) + } +} + +// Receive from two subscriptions to the same topic. +// Verify both get all the messages. +func testSendReceiveTwo(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + // Set up. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + if !h.SupportsMultipleSubscriptions() { + t.Skip("multiple subscriptions to a topic not supported") + } + + dt, cleanup, err := h.CreateTopic(ctx, t.Name()) + if err != nil { + t.Fatal(err) + } + defer cleanup() + topic := pubsub.NewTopic(dt, batchSizeOne) + defer func() { + if err := topic.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + + var ss []*pubsub.Subscription + for i := 0; i < 2; i++ { + ds, cleanup, err := h.CreateSubscription(ctx, dt, t.Name()) + if err != nil { + t.Fatal(err) + } + defer cleanup() + s := pubsub.NewSubscription(ds, batchSizeOne, batchSizeOne) + defer func() { + if err := s.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + ss = append(ss, s) + } + want := publishN(ctx, t, topic, 3) + for i, s := range ss { + got := receiveN(ctx, t, s, len(want)) + if diff := diffMessageSets(got, want); diff != "" { + t.Errorf("sub #%d: %s", i, diff) + } + } +} + +func testSendReceiveJSON(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const json = `{"Foo": "Bar"}` + // Set up. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + topic, sub, cleanup, err := makePair(ctx, t, h) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + sendM := &pubsub.Message{Body: []byte(json)} + if err := topic.Send(ctx, sendM); err != nil { + t.Fatal(err) + } + ctx2, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + receiveM, err := sub.Receive(ctx2) + if err != nil { + t.Fatal(err) + } + receiveM.Ack() + if diff := diffMessageSets([]*pubsub.Message{receiveM}, []*pubsub.Message{sendM}); diff != "" { + t.Error(diff) + } +} + +func testNack(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const nMessages = 2 + + // Set up. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + dt, topicCleanup, err := h.CreateTopic(ctx, t.Name()) + if err != nil { + t.Fatal(err) + } + defer topicCleanup() + ds, subCleanup, err := h.CreateSubscription(ctx, dt, t.Name()) + if err != nil { + t.Fatal(err) + } + defer subCleanup() + if !ds.CanNack() { + t.Skip("Nack not supported") + } + topic := pubsub.NewTopic(dt, batchSizeOne) + defer func() { + if err := topic.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + sub := pubsub.NewSubscription(ds, batchSizeOne, batchSizeOne) + defer func() { + if err := sub.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + + want := publishN(ctx, t, topic, nMessages) + + // Get the messages, but nack them. + // Make sure to nack after receiving all of them; otherwise, we could + // receive one of the messages twice instead of receiving all nMessages. + // The test will hang here if the messages aren't redelivered, so use a shorter timeout. + ctx2, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + var got []*pubsub.Message + for i := 0; i < nMessages; i++ { + m, err := sub.Receive(ctx2) + if err != nil { + t.Fatal(err) + } + got = append(got, m) + } + for _, m := range got { + m.Nack() + } + // Check that the received messages match the sent ones. + if diff := diffMessageSets(got, want); diff != "" { + t.Error(diff) + } + // The test will hang here if the messages aren't redelivered, so use a shorter timeout. + ctx2, cancel = context.WithTimeout(ctx, 30*time.Second) + defer cancel() + + got = nil + for i := 0; i < nMessages; i++ { + m, err := sub.Receive(ctx2) + if err != nil { + t.Fatal(err) + } + got = append(got, m) + m.Ack() + } + if diff := diffMessageSets(got, want); diff != "" { + t.Error(diff) + } +} + +func testBatching(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const nMessages = 12 // must be divisible by 2 + const batchSize = nMessages / 2 + + // Set up. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + maxSendBatch, maxAckBatch := h.MaxBatchSizes() + + dt, topicCleanup, err := h.CreateTopic(ctx, t.Name()) + if err != nil { + t.Fatal(err) + } + defer topicCleanup() + ds, subCleanup, err := h.CreateSubscription(ctx, dt, t.Name()) + if err != nil { + t.Fatal(err) + } + defer subCleanup() + + sendBatchOpts := &batcher.Options{MinBatchSize: batchSize, MaxBatchSize: batchSize} + // If the driver doesn't support batchSize batches, fall back to size 1. + if maxSendBatch != 0 && batchSize > maxSendBatch { + sendBatchOpts = batchSizeOne + } + topic := pubsub.NewTopic(dt, sendBatchOpts) + defer func() { + if err := topic.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + ackBatchOpts := &batcher.Options{MinBatchSize: batchSize, MaxBatchSize: batchSize} + // If the driver doesn't support batchSize batches, fall back to size 1. + if maxAckBatch != 0 && batchSize > maxAckBatch { + ackBatchOpts = batchSizeOne + } + sub := pubsub.NewSubscription(ds, batchSizeOne, ackBatchOpts) + defer func() { + if err := sub.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + + // Publish nMessages. We have to do them asynchronously because topic.Send + // blocks until the message is sent, and these messages won't be sent until + // all batchSize are queued. + // Note: this test uses the same Body for each message, because the order + // that they appear in the SendBatch is not stable. + gr, grctx := errgroup.WithContext(ctx) + var want []*pubsub.Message + for i := 0; i < nMessages; i++ { + m := &pubsub.Message{Body: []byte("hello world")} + want = append(want, m) + gr.Go(func() error { return topic.Send(grctx, m) }) + } + if err := gr.Wait(); err != nil { + t.Fatal(err) + } + + // Get the messages. + // The test will hang here if the messages aren't delivered, so use a shorter timeout. + ctx2, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + var got []*pubsub.Message + for i := 0; i < nMessages; i++ { + m, err := sub.Receive(ctx2) + if err != nil { + t.Fatal(err) + } + got = append(got, m) + m.Ack() + } + if diff := diffMessageSets(got, want); diff != "" { + t.Error(diff) + } +} + +func testDoubleAck(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + // Set up. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + dt, topicCleanup, err := h.CreateTopic(ctx, t.Name()) + if err != nil { + t.Fatal(err) + } + defer topicCleanup() + ds, subCleanup, err := h.CreateSubscription(ctx, dt, t.Name()) + if err != nil { + t.Fatal(err) + } + defer subCleanup() + + // Publish 3 messages. + for i := 0; i < 3; i++ { + err := dt.SendBatch(ctx, []*driver.Message{{Body: []byte(strconv.Itoa(i))}}) + if err != nil { + t.Fatal(err) + } + } + + // Retrieve the messages. + // The test will hang here if the messages aren't delivered, so use a shorter timeout. + ctx2, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + var dms []*driver.Message + for len(dms) != 3 { + curdms, err := ds.ReceiveBatch(ctx2, 3) + if err != nil { + t.Fatal(err) + } + if err := ctx2.Err(); err != nil { + t.Fatalf("never received expected messages: %v", err) + } + dms = append(dms, curdms...) + } + + // Ack the first two messages. + err = ds.SendAcks(ctx, []driver.AckID{dms[0].AckID, dms[1].AckID}) + if err != nil { + t.Fatal(err) + } + + // Ack them again; this should succeed even though we've acked them before. + // If services return an error for this, drivers should drop them. + err = ds.SendAcks(ctx, []driver.AckID{dms[0].AckID, dms[1].AckID}) + if err != nil { + t.Fatal(err) + } + + if !ds.CanNack() { + return + } + + // Nack all 3 messages. This should also succeed, and the nack of the third + // message should take effect, so we should be able to fetch it again. + // Note that the other messages *may* also be re-sent, because we're nacking + // them here (even though we acked them earlier); it depends on service + // semantics and time-sensitivity. + err = ds.SendNacks(ctx, []driver.AckID{dms[0].AckID, dms[1].AckID, dms[2].AckID}) + if err != nil { + t.Fatal(err) + } + + // The test will hang here if the message isn't redelivered, so use a shorter timeout. + ctx2, cancel = context.WithTimeout(ctx, 30*time.Second) + defer cancel() + + // We're looking to re-receive dms[2]. +Loop: + for { + curdms, err := ds.ReceiveBatch(ctx2, 1) + if err != nil { + t.Fatal(err) + } + for _, curdm := range curdms { + if bytes.Equal(curdm.Body, dms[2].Body) { + // Found it! + break Loop + } + } + } +} + +// Publish n different messages to the topic. Return the messages. +func publishN(ctx context.Context, t *testing.T, topic *pubsub.Topic, n int) []*pubsub.Message { + t.Helper() + + var ms []*pubsub.Message + for i := 0; i < n; i++ { + m := &pubsub.Message{ + Body: []byte(strconv.Itoa(i)), + Metadata: map[string]string{"a": strconv.Itoa(i)}, + } + if err := topic.Send(ctx, m); err != nil { + t.Fatal(err) + } + ms = append(ms, m) + } + return ms +} + +// Receive and ack n messages from sub. +func receiveN(ctx context.Context, t *testing.T, sub *pubsub.Subscription, n int) []*pubsub.Message { + t.Helper() + + // The test will hang here if the message(s) aren't available, so use a shorter timeout. + ctx2, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + var ms []*pubsub.Message + for i := 0; i < n; i++ { + m, err := sub.Receive(ctx2) + if err != nil { + t.Fatal(err) + } + ms = append(ms, m) + m.Ack() + } + return ms +} + +// Find the differences between two sets of messages. +func diffMessageSets(got, want []*pubsub.Message) string { + for _, m := range got { + m.LoggableID = "" + } + less := func(x, y *pubsub.Message) bool { return bytes.Compare(x.Body, y.Body) < 0 } + return cmp.Diff(got, want, cmpopts.SortSlices(less), cmpopts.IgnoreUnexported(pubsub.Message{})) +} + +func testErrorOnSendToClosedTopic(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + // Set up. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + dt, cleanup, err := h.CreateTopic(ctx, t.Name()) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + topic := pubsub.NewTopic(dt, batchSizeOne) + if err := topic.Shutdown(ctx); err != nil { + t.Error(err) + } + + // Check that sending to the closed topic fails. + m := &pubsub.Message{} + if err := topic.Send(ctx, m); err == nil { + t.Error("topic.Send returned nil, want error") + } + if err := topic.Shutdown(ctx); err == nil { + t.Error("wanted error on double Shutdown") + } +} + +func testErrorOnReceiveFromClosedSubscription(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + dt, cleanup, err := h.CreateTopic(ctx, t.Name()) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + ds, cleanup, err := h.CreateSubscription(ctx, dt, t.Name()) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + sub := pubsub.NewSubscription(ds, batchSizeOne, batchSizeOne) + if err := sub.Shutdown(ctx); err != nil { + t.Error(err) + } + if _, err = sub.Receive(ctx); err == nil { + t.Error("sub.Receive returned nil, want error") + } + if err := sub.Shutdown(ctx); err == nil { + t.Error("wanted error on double Shutdown") + } +} + +func testCancelSendReceive(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + topic, sub, cleanup, err := makePair(ctx, t, h) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + ctx, cancel := context.WithCancel(ctx) + cancel() + + m := &pubsub.Message{} + if err := topic.Send(ctx, m); !isCanceled(err) { + t.Errorf("topic.Send returned %v (%T), want context.Canceled", err, err) + } + if _, err := sub.Receive(ctx); !isCanceled(err) { + t.Errorf("sub.Receive returned %v (%T), want context.Canceled", err, err) + } + + // It would be nice to add a test that cancels an in-flight blocking Receive. + // However, because pubsub.Subscription.Receive repeatedly calls + // driver.ReceiveBatch if it returns 0 messages, it's difficult to write + // such a test without it being flaky for drivers with record/replay + // (the number of times driver.ReceiveBatch is called is timing-dependent). +} + +func testMetadata(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + // Set up. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + // Some services limit the number of metadata per message. + // Sort the escape.WeirdStrings values for record/replay consistency, + // then break the weird strings up into groups of at most maxMetadataKeys. + const maxMetadataKeys = 10 + var weirdStrings []string + for _, v := range escape.WeirdStrings { + weirdStrings = append(weirdStrings, v) + } + sort.Slice(weirdStrings, func(i, j int) bool { return weirdStrings[i] < weirdStrings[j] }) + + weirdMetaDataGroups := []map[string]string{{}} + i := 0 + for _, k := range weirdStrings { + weirdMetaDataGroups[i][k] = k + if len(weirdMetaDataGroups[i]) == maxMetadataKeys { + weirdMetaDataGroups = append(weirdMetaDataGroups, map[string]string{}) + i++ + } + } + + topic, sub, cleanup, err := makePair(ctx, t, h) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + for _, wm := range weirdMetaDataGroups { + m := &pubsub.Message{ + Body: []byte("hello world"), + Metadata: wm, + } + if err := topic.Send(ctx, m); err != nil { + t.Fatal(err) + } + + // The test will hang here if the messages aren't delivered, so use a shorter timeout. + ctx2, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + m, err = sub.Receive(ctx2) + if err != nil { + t.Fatal(err) + } + m.Ack() + + if diff := cmp.Diff(m.Metadata, wm); diff != "" { + t.Fatalf("got\n%v\nwant\n%v\ndiff\n%s", m.Metadata, wm, diff) + } + } + + // Verify that non-UTF8 strings in metadata key or value fail. + m := &pubsub.Message{ + Body: []byte("hello world"), + Metadata: map[string]string{escape.NonUTF8String: "bar"}, + } + if err := topic.Send(ctx, m); err == nil { + t.Error("got nil error, expected error for using non-UTF8 string as metadata key") + } + m.Metadata = map[string]string{"foo": escape.NonUTF8String} + if err := topic.Send(ctx, m); err == nil { + t.Error("got nil error, expected error for using non-UTF8 string as metadata value") + } +} + +func testNonUTF8MessageBody(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + // Set up. + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + + topic, sub, cleanup, err := makePair(ctx, t, h) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + // Sort the WeirdStrings map for record/replay consistency. + var weirdStrings [][]string // [0] = key, [1] = value + for k, v := range escape.WeirdStrings { + weirdStrings = append(weirdStrings, []string{k, v}) + } + sort.Slice(weirdStrings, func(i, j int) bool { return weirdStrings[i][0] < weirdStrings[j][0] }) + + // Construct a message body with the weird strings and some non-UTF-8 bytes. + var body []byte + for _, v := range weirdStrings { + body = append(body, []byte(v[1])...) + } + body = append(body, []byte(escape.NonUTF8String)...) + m := &pubsub.Message{Body: body} + + if err := topic.Send(ctx, m); err != nil { + t.Fatal(err) + } + // The test will hang here if the messages aren't delivered, so use a shorter timeout. + ctx2, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + m, err = sub.Receive(ctx2) + if err != nil { + t.Fatal(err) + } + m.Ack() + + if diff := cmp.Diff(m.Body, body); diff != "" { + t.Fatalf("got\n%v\nwant\n%v\ndiff\n%s", m.Body, body, diff) + } +} + +func isCanceled(err error) bool { + if err == context.Canceled { + return true + } + if cerr, ok := err.(*retry.ContextError); ok { + return cerr.CtxErr == context.Canceled + } + return gcerrors.Code(err) == gcerrors.Canceled +} + +func makePair(ctx context.Context, t *testing.T, h Harness) (*pubsub.Topic, *pubsub.Subscription, func(), error) { + t.Helper() + + dt, topicCleanup, err := h.CreateTopic(ctx, t.Name()) + if err != nil { + return nil, nil, nil, err + } + ds, subCleanup, err := h.CreateSubscription(ctx, dt, t.Name()) + if err != nil { + topicCleanup() + return nil, nil, nil, err + } + topic := pubsub.NewTopic(dt, batchSizeOne) + sub := pubsub.NewSubscription(ds, batchSizeOne, batchSizeOne) + cleanup := func() { + if err := topic.Shutdown(ctx); err != nil { + t.Error(err) + } + if err := sub.Shutdown(ctx); err != nil { + t.Error(err) + } + subCleanup() + topicCleanup() + } + return topic, sub, cleanup, nil +} + +// testAs tests the various As functions, using AsTest. +func testAs(t *testing.T, newHarness HarnessMaker, st AsTest) { + t.Helper() + + ctx := context.Background() + h, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + topic, sub, cleanup, err := makePair(ctx, t, h) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + if err := st.TopicCheck(topic); err != nil { + t.Error(err) + } + + if err := st.SubscriptionCheck(sub); err != nil { + t.Error(err) + } + + msg := &pubsub.Message{ + Body: []byte("x"), + BeforeSend: st.BeforeSend, + AfterSend: st.AfterSend, + } + if err := topic.Send(ctx, msg); err != nil { + t.Fatal(err) + } + // The test will hang here if the messages aren't delivered, so use a shorter timeout. + ctx2, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + m, err := sub.Receive(ctx2) + if err != nil { + t.Fatal(err) + } + if err := st.MessageCheck(m); err != nil { + t.Error(err) + } + m.Ack() + + // Make a nonexistent topic and try to to send on it, to get an error we can + // use to call TopicErrorCheck. + dt, err := h.MakeNonexistentTopic(ctx) + if err != nil { + t.Fatal(err) + } + nonexistentTopic := pubsub.NewTopic(dt, batchSizeOne) + defer func() { + if err := nonexistentTopic.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + // The test will hang here if Send doesn't fail quickly, so set a shorter timeout. + ctx2, cancel = context.WithTimeout(ctx, 30*time.Second) + defer cancel() + topicErr := nonexistentTopic.Send(ctx2, &pubsub.Message{}) + if topicErr == nil || gcerrors.Code(topicErr) != gcerrors.NotFound { + t.Errorf("got error %v sending to nonexistent topic, want Code=NotFound", topicErr) + } else if err := st.TopicErrorCheck(topic, topicErr); err != nil { + t.Error(err) + } + + // Make a nonexistent subscription and try to receive from it, to get an error + // we can use to call SubscriptionErrorCheck. + ds, cleanup, err := h.MakeNonexistentSubscription(ctx) + if err != nil { + t.Fatal(err) + } + defer cleanup() + nonExistentSub := pubsub.NewSubscription(ds, batchSizeOne, batchSizeOne) + defer func() { + if err := nonExistentSub.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + + // The test will hang here if Receive doesn't fail quickly, so set a shorter timeout. + ctx2, cancel = context.WithTimeout(ctx, 30*time.Second) + defer cancel() + _, subErr := nonExistentSub.Receive(ctx2) + if subErr == nil || ctx2.Err() != nil || gcerrors.Code(subErr) != gcerrors.NotFound { + t.Errorf("got error %v receiving from nonexistent subscription, want Code=NotFound", subErr) + } else if err := st.SubscriptionErrorCheck(nonExistentSub, subErr); err != nil { + t.Error(err) + } +} + +// Publishes a large number of messages to topic concurrently, and then times +// how long it takes to send (if timeSend is true) or receive (if timeSend +// is false) them all. +func benchmark(b *testing.B, topic *pubsub.Topic, sub *pubsub.Subscription, timeSend bool) { + b.Helper() + + attrs := map[string]string{"label": "value"} + body := []byte("hello, world") + const ( + nMessages = 10000 + concurrencySend = 100 + concurrencyReceive = 100 + ) + if nMessages%concurrencySend != 0 || nMessages%concurrencyReceive != 0 { + b.Fatal("nMessages must be divisible by # of sending/receiving goroutines") + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + if !timeSend { + b.StopTimer() + } + if err := publishNConcurrently(topic, nMessages, concurrencySend, attrs, body); err != nil { + b.Fatalf("publishing: %v", err) + } + b.Logf("published %d messages", nMessages) + if timeSend { + b.StopTimer() + } else { + b.StartTimer() + } + if err := receiveNConcurrently(sub, nMessages, concurrencyReceive); err != nil { + b.Fatalf("receiving: %v", err) + } + b.SetBytes(nMessages * 1e6) + b.Log("MB/s is actually number of messages received per second") + if timeSend { + b.StartTimer() + } + } +} + +func publishNConcurrently(topic *pubsub.Topic, nMessages, nGoroutines int, attrs map[string]string, body []byte) error { + return runConcurrently(nMessages, nGoroutines, func(ctx context.Context) error { + return topic.Send(ctx, &pubsub.Message{Metadata: attrs, Body: body}) + }) +} + +func receiveNConcurrently(sub *pubsub.Subscription, nMessages, nGoroutines int) error { + return runConcurrently(nMessages, nGoroutines, func(ctx context.Context) error { + m, err := sub.Receive(ctx) + if err != nil { + return err + } + m.Ack() + return nil + }) +} + +// Call function f n times concurrently, using g goroutines. g must divide n. +// Wait until all calls complete. If any fail, cancel the remaining ones. +func runConcurrently(n, g int, f func(context.Context) error) error { + gr, ctx := errgroup.WithContext(context.Background()) + ng := n / g + for i := 0; i < g; i++ { + gr.Go(func() error { + for j := 0; j < ng; j++ { + if err := f(ctx); err != nil { + return err + } + } + return nil + }) + } + return gr.Wait() +} diff --git a/go-cloud/pubsub/example_test.go b/go-cloud/pubsub/example_test.go new file mode 100644 index 000000000..7c3511098 --- /dev/null +++ b/go-cloud/pubsub/example_test.go @@ -0,0 +1,224 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 pubsub_test + +import ( + "context" + "fmt" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + + pbraw "cloud.google.com/go/pubsub/apiv1" + pbapi "cloud.google.com/go/pubsub/apiv1/pubsubpb" + "google.golang.org/grpc/status" +) + +func ExampleTopic_Send() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var topic *pubsub.Topic + + err := topic.Send(ctx, &pubsub.Message{ + Body: []byte("Hello, World!\n"), + // Metadata is optional and can be nil. + Metadata: map[string]string{ + // These are examples of metadata. + // There is nothing special about the key names. + "language": "en", + "importance": "high", + }, + }) + if err != nil { + log.Fatal(err) + } +} + +func ExampleSubscription_Receive() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var subscription *pubsub.Subscription + + // Loop on received messages. + for { + msg, err := subscription.Receive(ctx) + if err != nil { + // Errors from Receive indicate that Receive will no longer succeed. + log.Printf("Receiving message: %v", err) + break + } + // Do work based on the message, for example: + fmt.Printf("Got message: %q\n", msg.Body) + // Messages must always be acknowledged with Ack. + msg.Ack() + } +} + +func ExampleSubscription_Receive_concurrent() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var subscription *pubsub.Subscription + + // Loop on received messages. We can use a channel as a semaphore to limit how + // many goroutines we have active at a time as well as wait on the goroutines + // to finish before exiting. + const maxHandlers = 10 + sem := make(chan struct{}, maxHandlers) +recvLoop: + for { + msg, err := subscription.Receive(ctx) + if err != nil { + // Errors from Receive indicate that Receive will no longer succeed. + log.Printf("Receiving message: %v", err) + break + } + + // Wait if there are too many active handle goroutines and acquire the + // semaphore. If the context is canceled, stop waiting and start shutting + // down. + select { + case sem <- struct{}{}: + case <-ctx.Done(): + break recvLoop + } + + // Handle the message in a new goroutine. + go func() { + defer func() { <-sem }() // Release the semaphore. + defer msg.Ack() // Messages must always be acknowledged with Ack. + + // Do work based on the message, for example: + fmt.Printf("Got message: %q\n", msg.Body) + }() + } + + // We're no longer receiving messages. Wait to finish handling any + // unacknowledged messages by totally acquiring the semaphore. + for n := 0; n < maxHandlers; n++ { + sem <- struct{}{} + } +} + +func ExampleMessage_As() { + // This example is specific to the gcppubsub implementation; it demonstrates + // access to the underlying PubsubMessage type. + // The types exposed for As by gcppubsub are documented in + // https://godoc.org/gocloud.dev/pubsub/gcppubsub#hdr-As + + ctx := context.Background() + sub, err := pubsub.OpenSubscription(ctx, "gcppubsub://project/topic") + if err != nil { + log.Fatal(err) + } + defer sub.Shutdown(ctx) + + msg, err := sub.Receive(ctx) + if err != nil { + log.Fatal(err) + } + var pm *pbapi.PubsubMessage + if msg.As(&pm) { + _ = pm.GetAttributes() + } + msg.Ack() +} + +func ExampleSubscription_As() { + // This example is specific to the gcppubsub implementation; it demonstrates + // access to the underlying SubscriberClient type. + // The types exposed for As by gcppubsub are documented in + // https://godoc.org/gocloud.dev/pubsub/gcppubsub#hdr-As + + ctx := context.Background() + sub, err := pubsub.OpenSubscription(ctx, "gcppubsub://project/topic") + if err != nil { + log.Fatal(err) + } + defer sub.Shutdown(ctx) + + var sc *pbraw.SubscriberClient + if sub.As(&sc) { + _ = sc.CallOptions + } +} + +func ExampleSubscription_ErrorAs() { + // This example is specific to the gcppubsub implementation; it demonstrates + // access to the underlying Status type. + // The types exposed for As by gcppubsub are documented in + // https://godoc.org/gocloud.dev/pubsub/gcppubsub#hdr-As + + ctx := context.Background() + sub, err := pubsub.OpenSubscription(ctx, "gcppubsub://project/badtopic") + if err != nil { + log.Fatal(err) + } + defer sub.Shutdown(ctx) + + msg, err := sub.Receive(ctx) + if err != nil { + var s *status.Status + if sub.ErrorAs(err, &s) { + _ = s.Code() + } + log.Fatal(err) + } + msg.Ack() +} + +func ExampleTopic_As() { + // This example is specific to the gcppubsub implementation; it demonstrates + // access to the underlying PublisherClient type. + // The types exposed for As by gcppubsub are documented in + // https://godoc.org/gocloud.dev/pubsub/gcppubsub#hdr-As + + ctx := context.Background() + topic, err := pubsub.OpenTopic(ctx, "gcppubsub://project/topic") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) + + var pc *pbraw.PublisherClient + if topic.As(&pc) { + _ = pc + } +} + +func ExampleTopic_ErrorAs() { + // This example is specific to the gcppubsub implementation; it demonstrates + // access to the underlying Status type. + // The types exposed for As by gcppubsub are documented in + // https://godoc.org/gocloud.dev/pubsub/gcppubsub#hdr-As + + ctx := context.Background() + topic, err := pubsub.OpenTopic(ctx, "gcppubsub://project/topic") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) + + err = topic.Send(ctx, &pubsub.Message{Body: []byte("hello")}) + if err != nil { + var s *status.Status + if topic.ErrorAs(err, &s) { + _ = s.Code() + } + log.Fatal(err) + } +} diff --git a/go-cloud/pubsub/gcppubsub/example_test.go b/go-cloud/pubsub/gcppubsub/example_test.go new file mode 100644 index 000000000..3c2d72207 --- /dev/null +++ b/go-cloud/pubsub/gcppubsub/example_test.go @@ -0,0 +1,168 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcppubsub_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/gcppubsub" + + raw "cloud.google.com/go/pubsub/apiv1" + pb "cloud.google.com/go/pubsub/apiv1/pubsubpb" +) + +func ExampleOpenTopic() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Your GCP credentials. + // See https://cloud.google.com/docs/authentication/production + // for more info on alternatives. + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + log.Fatal(err) + } + // Open a gRPC connection to the GCP Pub/Sub API. + conn, cleanup, err := gcppubsub.Dial(ctx, creds.TokenSource) + if err != nil { + log.Fatal(err) + } + defer cleanup() + + // Construct a PublisherClient using the connection. + pubClient, err := gcppubsub.PublisherClient(ctx, conn) + if err != nil { + log.Fatal(err) + } + defer pubClient.Close() + + // Construct a *pubsub.Topic. + topic, err := gcppubsub.OpenTopicByPath(pubClient, "projects/myprojectID/topics/example-topic", nil) + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func Example_openTopicFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/gcppubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + topic, err := pubsub.OpenTopic(ctx, "gcppubsub://projects/myproject/topics/mytopic") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func ExampleOpenSubscription() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Your GCP credentials. + // See https://cloud.google.com/docs/authentication/production + // for more info on alternatives. + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + log.Fatal(err) + } + + // Open a gRPC connection to the GCP Pub/Sub API. + conn, cleanup, err := gcppubsub.Dial(ctx, creds.TokenSource) + if err != nil { + log.Fatal(err) + } + defer cleanup() + + // Construct a SubscriberClient using the connection. + subClient, err := gcppubsub.SubscriberClient(ctx, conn) + if err != nil { + log.Fatal(err) + } + defer subClient.Close() + + // Construct a *pubsub.Subscription. + subscription, err := gcppubsub.OpenSubscriptionByPath( + subClient, "projects/myprojectID/subscriptions/example-subscription", nil) + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} + +func Example_extendingAckDeadline() { + ctx := context.Background() + + // Construct a *pubsub.Subscription, in this example using a URL. + const subName = "projects/myprojectID/subscriptions/example-subscription" + subscription, err := pubsub.OpenSubscription(ctx, "gcppubsub://"+subName) + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) + + // Get the underlying SubscriberClient. If you used the constructor to create + // the subscription (e.g., gcppubsub.OpenSubscriptionByPath), you may already + // have the client. + var client *raw.SubscriberClient + if !subscription.As(&client) { + log.Fatal("Couldn't get SubscriberClient using As") + } + + // Now assume you've got a message, and processing is going to take a long time; + // you want to extend the default Ack deadline. + msg, err := subscription.Receive(ctx) + if err != nil { + log.Fatalf("Failed to receive message: %v", err) + } + + // Get the underlying ReceivedMessage. + var rm *pb.ReceivedMessage + if !msg.As(&rm) { + log.Fatal("Couldn't get ReceivedMessage using As") + } + + // Call ModifyAckDeadline. + if err := client.ModifyAckDeadline(ctx, &pb.ModifyAckDeadlineRequest{ + Subscription: subName, + AckIds: []string{rm.AckId}, + AckDeadlineSeconds: 30 * 60, // 30m, or whatever you need + }); err != nil { + log.Fatalf("Failed to ModifyAckDeadline: %v", err) + } + // ... eventually Ack the message. + msg.Ack() +} + +func Example_openSubscriptionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/gcppubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + subscription, err := pubsub.OpenSubscription(ctx, + "gcppubsub://projects/my-project/subscriptions/my-subscription") + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} diff --git a/go-cloud/pubsub/gcppubsub/gcppubsub.go b/go-cloud/pubsub/gcppubsub/gcppubsub.go new file mode 100644 index 000000000..244c24686 --- /dev/null +++ b/go-cloud/pubsub/gcppubsub/gcppubsub.go @@ -0,0 +1,656 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcppubsub provides a pubsub implementation that uses GCP +// PubSub. Use OpenTopic to construct a *pubsub.Topic, and/or OpenSubscription +// to construct a *pubsub.Subscription. +// +// # URLs +// +// For pubsub.OpenTopic and pubsub.OpenSubscription, gcppubsub registers +// for the scheme "gcppubsub". +// The default URL opener will creating a connection using use default +// credentials from the environment, as described in +// https://cloud.google.com/docs/authentication/production. +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// GCP Pub/Sub emulator is supported as per https://cloud.google.com/pubsub/docs/emulator +// So, when environment variable 'PUBSUB_EMULATOR_HOST' is set +// driver connects to the specified emulator host by default. +// +// # Message Delivery Semantics +// +// GCP Pub/Sub supports at-least-once semantics; applications must +// call Message.Ack after processing a message, or it will be redelivered. +// See https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery +// for more background. +// +// # As +// +// gcppubsub exposes the following types for As: +// - Topic: *raw.PublisherClient +// - Subscription: *raw.SubscriberClient +// - Message.BeforeSend: *pb.PubsubMessage +// - Message.AfterSend: *string for the pb.PublishResponse.MessageIds entry corresponding to the message. +// - Message: *pb.PubsubMessage, *pb.ReceivedMessage +// - Error: *google.golang.org/grpc/status.Status +package gcppubsub // import "gocloud.dev/pubsub/gcppubsub" + +import ( + "context" + "fmt" + "net/url" + "os" + "path" + "regexp" + "strconv" + "strings" + "sync" + "time" + + raw "cloud.google.com/go/pubsub/apiv1" + pb "cloud.google.com/go/pubsub/apiv1/pubsubpb" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/useragent" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/batcher" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" + "google.golang.org/api/option" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/credentials/oauth" + "google.golang.org/grpc/status" +) + +var endPoint = "pubsub.googleapis.com:443" + +var sendBatcherOpts = &batcher.Options{ + MaxBatchSize: 1000, // The PubSub service limits the number of messages in a single Publish RPC + MaxHandlers: 2, + // The PubSub service limits the size of the request body in a single Publish RPC. + // The limit is currently documented as "10MB (total size)" and "10MB (data field)" per message. + // We are enforcing 9MiB to give ourselves some headroom for message attributes since those + // are currently not considered when computing the byte size of a message. + MaxBatchByteSize: 9 * 1024 * 1024, +} + +var defaultRecvBatcherOpts = &batcher.Options{ + // GCP Pub/Sub returns at most 1000 messages per RPC. + MaxBatchSize: 1000, + MaxHandlers: 10, +} + +var ackBatcherOpts = &batcher.Options{ + // The PubSub service limits the size of Acknowledge/ModifyAckDeadline RPCs. + // (E.g., "Request payload size exceeds the limit: 524288 bytes."). + MaxBatchSize: 1000, + MaxHandlers: 2, +} + +func init() { + o := new(lazyCredsOpener) + pubsub.DefaultURLMux().RegisterTopic(Scheme, o) + pubsub.DefaultURLMux().RegisterSubscription(Scheme, o) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + Dial, + PublisherClient, + SubscriberClient, + wire.Struct(new(SubscriptionOptions)), + wire.Struct(new(TopicOptions)), + wire.Struct(new(URLOpener), "Conn", "TopicOptions", "SubscriptionOptions"), +) + +// lazyCredsOpener obtains Application Default Credentials on the first call +// to OpenTopicURL/OpenSubscriptionURL. +type lazyCredsOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazyCredsOpener) defaultConn(ctx context.Context) (*URLOpener, error) { + o.init.Do(func() { + var conn *grpc.ClientConn + var err error + if e := os.Getenv("PUBSUB_EMULATOR_HOST"); e != "" { + // Connect to the GCP pubsub emulator by overriding the default endpoint + // if the 'PUBSUB_EMULATOR_HOST' environment variable is set. + // Check https://cloud.google.com/pubsub/docs/emulator for more info. + endPoint = e + conn, err = dialEmulator(ctx, e) + if err != nil { + o.err = err + return + } + } else { + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + o.err = err + return + } + + conn, _, err = Dial(ctx, creds.TokenSource) + if err != nil { + o.err = err + return + } + } + o.opener = &URLOpener{Conn: conn} + }) + return o.opener, o.err +} + +func (o *lazyCredsOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + opener, err := o.defaultConn(ctx) + if err != nil { + return nil, fmt.Errorf("open topic %v: failed to open default connection: %v", u, err) + } + return opener.OpenTopicURL(ctx, u) +} + +func (o *lazyCredsOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + opener, err := o.defaultConn(ctx) + if err != nil { + return nil, fmt.Errorf("open subscription %v: failed to open default connection: %v", u, err) + } + return opener.OpenSubscriptionURL(ctx, u) +} + +// Scheme is the URL scheme gcppubsub registers its URLOpeners under on pubsub.DefaultMux. +const Scheme = "gcppubsub" + +// URLOpener opens GCP Pub/Sub URLs like "gcppubsub://projects/myproject/topics/mytopic" for +// topics or "gcppubsub://projects/myproject/subscriptions/mysub" for subscriptions. +// +// The shortened forms "gcppubsub://myproject/mytopic" for topics or +// "gcppubsub://myproject/mysub" for subscriptions are also supported. +// +// The following query parameters are supported: +// +// - max_recv_batch_size: sets SubscriptionOptions.MaxBatchSize. +// - max_send_batch_size: sets TopicOptions.BatcherOptions.MaxBatchSize. +// - nacklazy: sets SubscriberOptions.NackLazy. The value must be parseable by `strconv.ParseBool`. +// +// Currently their use is limited to subscribers. +type URLOpener struct { + // Conn must be set to a non-nil ClientConn authenticated with + // Cloud Pub/Sub scope or equivalent. + Conn *grpc.ClientConn + + // TopicOptions specifies the options to pass to OpenTopic. + TopicOptions TopicOptions + // SubscriptionOptions specifies the options to pass to OpenSubscription. + SubscriptionOptions SubscriptionOptions +} + +// OpenTopicURL opens a pubsub.Topic based on u. +func (o *URLOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + opts := o.TopicOptions + + for param, value := range u.Query() { + switch param { + case "max_send_batch_size": + maxBatchSize, err := queryParameterInt(value) + if err != nil { + return nil, fmt.Errorf("open topic %v: invalid query parameter %q: %v", u, param, err) + } + + if maxBatchSize <= 0 || maxBatchSize > 1000 { + return nil, fmt.Errorf("open topic %v: invalid query parameter %q: must be between 1 and 1000", u, param) + } + + opts.BatcherOptions.MaxBatchSize = maxBatchSize + default: + return nil, fmt.Errorf("open topic %v: invalid query parameter %q", u, param) + } + } + pc, err := PublisherClient(ctx, o.Conn) + if err != nil { + return nil, err + } + topicPath := path.Join(u.Host, u.Path) + if topicPathRE.MatchString(topicPath) { + return OpenTopicByPath(pc, topicPath, &opts) + } + // Shortened form? + topicName := strings.TrimPrefix(u.Path, "/") + return OpenTopic(pc, gcp.ProjectID(u.Host), topicName, &opts), nil +} + +// OpenSubscriptionURL opens a pubsub.Subscription based on u. +func (o *URLOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + // Set subscription options to use defaults + opts := o.SubscriptionOptions + + for param, value := range u.Query() { + switch param { + case "max_recv_batch_size": + maxBatchSize, err := queryParameterInt(value) + if err != nil { + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q: %v", u, param, err) + } + + if maxBatchSize <= 0 || maxBatchSize > 1000 { + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q: must be between 1 and 1000", u, param) + } + + opts.MaxBatchSize = maxBatchSize + case "nacklazy": + var err error + nackLazy, err := queryParameterBool(value) + if err != nil { + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q: %v", u, param, err) + } + opts.NackLazy = nackLazy + default: + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q", u, param) + } + } + sc, err := SubscriberClient(ctx, o.Conn) + if err != nil { + return nil, err + } + subPath := path.Join(u.Host, u.Path) + if subscriptionPathRE.MatchString(subPath) { + return OpenSubscriptionByPath(sc, subPath, &opts) + } + // Shortened form? + subName := strings.TrimPrefix(u.Path, "/") + return OpenSubscription(sc, gcp.ProjectID(u.Host), subName, &opts), nil +} + +type topic struct { + path string + client *raw.PublisherClient +} + +// Dial opens a gRPC connection to the GCP Pub Sub API. +// +// The second return value is a function that can be called to clean up +// the connection opened by Dial. +func Dial(ctx context.Context, ts gcp.TokenSource) (*grpc.ClientConn, func(), error) { + conn, err := grpc.DialContext(ctx, endPoint, + grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), + grpc.WithPerRPCCredentials(oauth.TokenSource{TokenSource: ts}), + // The default message size limit for gRPC is 4MB, while GCP + // PubSub supports messages up to 10MB. Aside from the message itself + // there is also other data in the gRPC response, bringing the maximum + // response size above 10MB. Tell gRPC to support up to 11MB. + // https://github.com/googleapis/google-cloud-node/issues/1991 + grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(1024*1024*11)), + useragent.GRPCDialOption("pubsub"), + ) + if err != nil { + return nil, nil, err + } + return conn, func() { conn.Close() }, nil +} + +// dialEmulator opens a gRPC connection to the GCP Pub Sub API. +func dialEmulator(ctx context.Context, e string) (*grpc.ClientConn, error) { + conn, err := grpc.DialContext(ctx, e, + grpc.WithTransportCredentials(insecure.NewCredentials()), + useragent.GRPCDialOption("pubsub")) + if err != nil { + return nil, err + } + return conn, nil +} + +// PublisherClient returns a *raw.PublisherClient that can be used in OpenTopic. +func PublisherClient(ctx context.Context, conn *grpc.ClientConn) (*raw.PublisherClient, error) { + return raw.NewPublisherClient(ctx, option.WithGRPCConn(conn)) +} + +// SubscriberClient returns a *raw.SubscriberClient that can be used in OpenSubscription. +func SubscriberClient(ctx context.Context, conn *grpc.ClientConn) (*raw.SubscriberClient, error) { + return raw.NewSubscriberClient(ctx, option.WithGRPCConn(conn)) +} + +// TopicOptions will contain configuration for topics. +type TopicOptions struct { + // BatcherOptions adds constraints to the default batching done for sends. + BatcherOptions batcher.Options +} + +// OpenTopic returns a *pubsub.Topic backed by an existing GCP PubSub topic +// in the given projectID. topicName is the last part of the full topic +// path, e.g., "foo" from "projects//topic/foo". +// See the package documentation for an example. +func OpenTopic(client *raw.PublisherClient, projectID gcp.ProjectID, topicName string, opts *TopicOptions) *pubsub.Topic { + topicPath := fmt.Sprintf("projects/%s/topics/%s", projectID, topicName) + if opts == nil { + opts = &TopicOptions{} + } + bo := sendBatcherOpts.NewMergedOptions(&opts.BatcherOptions) + return pubsub.NewTopic(openTopic(client, topicPath), bo) +} + +var topicPathRE = regexp.MustCompile("^projects/.+/topics/.+$") + +// OpenTopicByPath returns a *pubsub.Topic backed by an existing GCP PubSub +// topic. topicPath must be of the form "projects//topic/". +// See the package documentation for an example. +func OpenTopicByPath(client *raw.PublisherClient, topicPath string, opts *TopicOptions) (*pubsub.Topic, error) { + if !topicPathRE.MatchString(topicPath) { + return nil, fmt.Errorf("invalid topicPath %q; must match %v", topicPath, topicPathRE) + } + if opts == nil { + opts = &TopicOptions{} + } + bo := sendBatcherOpts.NewMergedOptions(&opts.BatcherOptions) + return pubsub.NewTopic(openTopic(client, topicPath), bo), nil +} + +// openTopic returns the driver for OpenTopic. This function exists so the test +// harness can get the driver interface implementation if it needs to. +func openTopic(client *raw.PublisherClient, topicPath string) driver.Topic { + return &topic{topicPath, client} +} + +// SendBatch implements driver.Topic.SendBatch. +func (t *topic) SendBatch(ctx context.Context, dms []*driver.Message) error { + var ms []*pb.PubsubMessage + for _, dm := range dms { + psm := &pb.PubsubMessage{Data: dm.Body, Attributes: dm.Metadata} + if dm.BeforeSend != nil { + asFunc := func(i any) bool { + if p, ok := i.(**pb.PubsubMessage); ok { + *p = psm + return true + } + return false + } + if err := dm.BeforeSend(asFunc); err != nil { + return err + } + } + ms = append(ms, psm) + } + req := &pb.PublishRequest{Topic: t.path, Messages: ms} + pr, err := t.client.Publish(ctx, req) + if err != nil { + return err + } + if len(pr.MessageIds) == len(dms) { + for n, dm := range dms { + if dm.AfterSend != nil { + asFunc := func(i any) bool { + if p, ok := i.(*string); ok { + *p = pr.MessageIds[n] + return true + } + return false + } + if err := dm.AfterSend(asFunc); err != nil { + return err + } + } + } + } + return nil +} + +// IsRetryable implements driver.Topic.IsRetryable. +func (t *topic) IsRetryable(error) bool { + // The client handles retries. + return false +} + +// As implements driver.Topic.As. +func (t *topic) As(i any) bool { + c, ok := i.(**raw.PublisherClient) + if !ok { + return false + } + *c = t.client + return true +} + +// ErrorAs implements driver.Topic.ErrorAs +func (*topic) ErrorAs(err error, i any) bool { + return errorAs(err, i) +} + +func errorAs(err error, i any) bool { + s, ok := status.FromError(err) + if !ok { + return false + } + p, ok := i.(**status.Status) + if !ok { + return false + } + *p = s + return true +} + +func (*topic) ErrorCode(err error) gcerrors.ErrorCode { + return gcerr.GRPCCode(err) +} + +// Close implements driver.Topic.Close. +func (*topic) Close() error { return nil } + +type subscription struct { + client *raw.SubscriberClient + path string + options *SubscriptionOptions +} + +// SubscriptionOptions will contain configuration for subscriptions. +type SubscriptionOptions struct { + // MaxBatchSize caps the maximum batch size used when retrieving messages. It defaults to 1000. + MaxBatchSize int + + // NackLazy determines what Nack does. + // + // By default, Nack uses ModifyAckDeadline to set the ack deadline + // for the nacked message to 0, so that it will be redelivered immediately. + // Set NackLazy to true to bypass this behavior; Nack will do nothing, + // and the message will be redelivered after the existing ack deadline + // expires. + NackLazy bool + + // ReceiveBatcherOptions adds constraints to the default batching done for receives. + ReceiveBatcherOptions batcher.Options + + // AckBatcherOptions adds constraints to the default batching done for acks. + AckBatcherOptions batcher.Options +} + +// OpenSubscription returns a *pubsub.Subscription backed by an existing GCP +// PubSub subscription subscriptionName in the given projectID. See the package +// documentation for an example. +func OpenSubscription(client *raw.SubscriberClient, projectID gcp.ProjectID, subscriptionName string, opts *SubscriptionOptions) *pubsub.Subscription { + path := fmt.Sprintf("projects/%s/subscriptions/%s", projectID, subscriptionName) + + dsub := openSubscription(client, path, opts) + recvOpts := *defaultRecvBatcherOpts + recvOpts.MaxBatchSize = dsub.options.MaxBatchSize + rbo := recvOpts.NewMergedOptions(&dsub.options.ReceiveBatcherOptions) + abo := ackBatcherOpts.NewMergedOptions(&dsub.options.AckBatcherOptions) + return pubsub.NewSubscription(dsub, rbo, abo) +} + +var subscriptionPathRE = regexp.MustCompile("^projects/.+/subscriptions/.+$") + +// OpenSubscriptionByPath returns a *pubsub.Subscription backed by an existing +// GCP PubSub subscription. subscriptionPath must be of the form +// "projects//subscriptions/". +// See the package documentation for an example. +func OpenSubscriptionByPath(client *raw.SubscriberClient, subscriptionPath string, opts *SubscriptionOptions) (*pubsub.Subscription, error) { + if !subscriptionPathRE.MatchString(subscriptionPath) { + return nil, fmt.Errorf("invalid subscriptionPath %q; must match %v", subscriptionPath, subscriptionPathRE) + } + + dsub := openSubscription(client, subscriptionPath, opts) + recvOpts := *defaultRecvBatcherOpts + recvOpts.MaxBatchSize = dsub.options.MaxBatchSize + rbo := recvOpts.NewMergedOptions(&dsub.options.ReceiveBatcherOptions) + abo := ackBatcherOpts.NewMergedOptions(&dsub.options.AckBatcherOptions) + return pubsub.NewSubscription(dsub, rbo, abo), nil +} + +// openSubscription returns a driver.Subscription. +func openSubscription(client *raw.SubscriberClient, subscriptionPath string, opts *SubscriptionOptions) *subscription { + if opts == nil { + opts = &SubscriptionOptions{} + } + if opts.MaxBatchSize == 0 { + opts.MaxBatchSize = defaultRecvBatcherOpts.MaxBatchSize + } + return &subscription{client, subscriptionPath, opts} +} + +// ReceiveBatch implements driver.Subscription.ReceiveBatch. +func (s *subscription) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + // Whether to ask Pull to return immediately, or wait for some messages to + // arrive. If we're making multiple RPCs, we don't want any of them to wait; + // we might have gotten messages from one of the other RPCs. + // maxMessages will only be high enough to set this to true in high-throughput + // situations, so the likelihood of getting 0 messages is small anyway. + returnImmediately := maxMessages == s.options.MaxBatchSize + + req := &pb.PullRequest{ + Subscription: s.path, + ReturnImmediately: returnImmediately, + MaxMessages: int32(maxMessages), + } + resp, err := s.client.Pull(ctx, req) + if err != nil { + return nil, err + } + if len(resp.ReceivedMessages) == 0 { + // If we did happen to get 0 messages, and we didn't ask the server to wait + // for messages, sleep a bit to avoid spinning. + if returnImmediately { + time.Sleep(100 * time.Millisecond) + } + return nil, nil + } + + ms := make([]*driver.Message, 0, len(resp.ReceivedMessages)) + for _, rm := range resp.ReceivedMessages { + rm := rm + rmm := rm.Message + m := &driver.Message{ + LoggableID: rmm.MessageId, + Body: rmm.Data, + Metadata: rmm.Attributes, + AckID: rm.AckId, + AsFunc: messageAsFunc(rmm, rm), + } + ms = append(ms, m) + } + return ms, nil +} + +func messageAsFunc(pm *pb.PubsubMessage, rm *pb.ReceivedMessage) func(any) bool { + return func(i any) bool { + ip, ok := i.(**pb.PubsubMessage) + if ok { + *ip = pm + return true + } + rp, ok := i.(**pb.ReceivedMessage) + if ok { + *rp = rm + return true + } + return false + } +} + +// SendAcks implements driver.Subscription.SendAcks. +func (s *subscription) SendAcks(ctx context.Context, ids []driver.AckID) error { + ids2 := make([]string, 0, len(ids)) + for _, id := range ids { + ids2 = append(ids2, id.(string)) + } + return s.client.Acknowledge(ctx, &pb.AcknowledgeRequest{Subscription: s.path, AckIds: ids2}) +} + +// CanNack implements driver.CanNack. +func (s *subscription) CanNack() bool { return true } + +// SendNacks implements driver.Subscription.SendNacks. +func (s *subscription) SendNacks(ctx context.Context, ids []driver.AckID) error { + if s.options.NackLazy { + return nil + } + ids2 := make([]string, 0, len(ids)) + for _, id := range ids { + ids2 = append(ids2, id.(string)) + } + return s.client.ModifyAckDeadline(ctx, &pb.ModifyAckDeadlineRequest{ + Subscription: s.path, + AckIds: ids2, + AckDeadlineSeconds: 0, + }) +} + +// IsRetryable implements driver.Subscription.IsRetryable. +func (s *subscription) IsRetryable(err error) bool { + // The client mostly handles retries, but does not + // include DeadlineExceeded for some reason. + return s.ErrorCode(err) == gcerrors.DeadlineExceeded +} + +// As implements driver.Subscription.As. +func (s *subscription) As(i any) bool { + c, ok := i.(**raw.SubscriberClient) + if !ok { + return false + } + *c = s.client + return true +} + +// ErrorAs implements driver.Subscription.ErrorAs +func (*subscription) ErrorAs(err error, i any) bool { + return errorAs(err, i) +} + +func (*subscription) ErrorCode(err error) gcerrors.ErrorCode { + return gcerr.GRPCCode(err) +} + +// Close implements driver.Subscription.Close. +func (*subscription) Close() error { return nil } + +func queryParameterInt(value []string) (int, error) { + if len(value) > 1 { + return 0, fmt.Errorf("expected only one parameter value, got: %v", len(value)) + } + + return strconv.Atoi(value[0]) +} + +func queryParameterBool(value []string) (bool, error) { + if len(value) > 1 { + return false, fmt.Errorf("expected only one parameter value, got: %v", len(value)) + } + + return strconv.ParseBool(value[0]) +} diff --git a/go-cloud/pubsub/gcppubsub/gcppubsub_test.go b/go-cloud/pubsub/gcppubsub/gcppubsub_test.go new file mode 100644 index 000000000..5deb14d11 --- /dev/null +++ b/go-cloud/pubsub/gcppubsub/gcppubsub_test.go @@ -0,0 +1,445 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcppubsub + +import ( + "context" + "fmt" + "path" + "strings" + "sync/atomic" + "testing" + + raw "cloud.google.com/go/pubsub/apiv1" + "cloud.google.com/go/pubsub/apiv1/pubsubpb" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/drivertest" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// projectID is the project ID that was used during the last test run using +// --record. +const projectID = "go-cloud-test-216917" + +type harness struct { + closer func() + pubClient *raw.PublisherClient + subClient *raw.SubscriberClient + numTopics uint32 // atomic + numSubs uint32 // atomic +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + conn, done := setup.NewGCPgRPCConn(ctx, t, endPoint, "pubsub") + pubClient, err := PublisherClient(ctx, conn) + if err != nil { + return nil, fmt.Errorf("making publisher client: %v", err) + } + subClient, err := SubscriberClient(ctx, conn) + if err != nil { + return nil, fmt.Errorf("making subscription client: %v", err) + } + return &harness{closer: done, pubClient: pubClient, subClient: subClient, numTopics: 0, numSubs: 0}, nil +} + +func (h *harness) CreateTopic(ctx context.Context, testName string) (dt driver.Topic, cleanup func(), err error) { + // We may encounter topics that were created by a previous test run and were + // not properly cleaned up. In such a case delete the existing topic and create + // a new topic with a higher topic number (to avoid cool-off issues between + // deletion and re-creation). + for { + topicName := fmt.Sprintf("%s-topic-%d", sanitize(testName), atomic.AddUint32(&h.numTopics, 1)) + topicPath := fmt.Sprintf("projects/%s/topics/%s", projectID, topicName) + dt, cleanup, err := createTopic(ctx, h.pubClient, topicName, topicPath) + if err != nil && status.Code(err) == codes.AlreadyExists { + // Delete the topic and retry. + h.pubClient.DeleteTopic(ctx, &pubsubpb.DeleteTopicRequest{Topic: topicPath}) + continue + } + return dt, cleanup, err + } +} + +func createTopic(ctx context.Context, pubClient *raw.PublisherClient, topicName, topicPath string) (dt driver.Topic, cleanup func(), err error) { + _, err = pubClient.CreateTopic(ctx, &pubsubpb.Topic{Name: topicPath}) + if err != nil { + return nil, nil, err + } + dt = openTopic(pubClient, path.Join("projects", projectID, "topics", topicName)) + cleanup = func() { + pubClient.DeleteTopic(ctx, &pubsubpb.DeleteTopicRequest{Topic: topicPath}) + } + return dt, cleanup, nil +} + +func (h *harness) MakeNonexistentTopic(ctx context.Context) (driver.Topic, error) { + return openTopic(h.pubClient, path.Join("projects", projectID, "topics", "nonexistent-topic")), nil +} + +func (h *harness) CreateSubscription(ctx context.Context, dt driver.Topic, testName string) (ds driver.Subscription, cleanup func(), err error) { + // We may encounter subscriptions that were created by a previous test run + // and were not properly cleaned up. In such a case delete the existing + // subscription and create a new subscription with a higher subscription + // number (to avoid cool-off issues between deletion and re-creation). + for { + subName := fmt.Sprintf("%s-subscription-%d", sanitize(testName), atomic.AddUint32(&h.numSubs, 1)) + subPath := fmt.Sprintf("projects/%s/subscriptions/%s", projectID, subName) + ds, cleanup, err := createSubscription(ctx, h.subClient, dt, subName, subPath) + if err != nil && status.Code(err) == codes.AlreadyExists { + // Delete the subscription and retry. + h.subClient.DeleteSubscription(ctx, &pubsubpb.DeleteSubscriptionRequest{Subscription: subPath}) + continue + } + return ds, cleanup, err + } +} + +func createSubscription(ctx context.Context, subClient *raw.SubscriberClient, dt driver.Topic, subName, subPath string) (ds driver.Subscription, cleanup func(), err error) { + t := dt.(*topic) + _, err = subClient.CreateSubscription(ctx, &pubsubpb.Subscription{ + Name: subPath, + Topic: t.path, + }) + if err != nil { + return nil, nil, err + } + ds = openSubscription(subClient, path.Join("projects", projectID, "subscriptions", subName), nil) + cleanup = func() { + subClient.DeleteSubscription(ctx, &pubsubpb.DeleteSubscriptionRequest{Subscription: subPath}) + } + return ds, cleanup, nil +} + +func (h *harness) MakeNonexistentSubscription(ctx context.Context) (driver.Subscription, func(), error) { + return openSubscription(h.subClient, path.Join("projects", projectID, "subscriptions", "nonexistent-subscription"), nil), func() {}, nil +} + +func (h *harness) Close() { + h.pubClient.Close() + h.subClient.Close() + h.closer() +} + +func (h *harness) MaxBatchSizes() (int, int) { + return sendBatcherOpts.MaxBatchSize, ackBatcherOpts.MaxBatchSize +} + +func (*harness) SupportsMultipleSubscriptions() bool { return true } + +func TestConformance(t *testing.T) { + asTests := []drivertest.AsTest{gcpAsTest{}} + drivertest.RunConformanceTests(t, newHarness, asTests) +} + +func BenchmarkGcpPubSub(b *testing.B) { + ctx := context.Background() + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + b.Fatal(err) + } + + // Connect. + conn, cleanup, err := Dial(ctx, gcp.CredentialsTokenSource(creds)) + if err != nil { + b.Fatal(err) + } + defer cleanup() + + // Make topic. + pc, err := PublisherClient(ctx, conn) + if err != nil { + b.Fatal(err) + } + topicName := fmt.Sprintf("%s-topic", b.Name()) + topicPath := fmt.Sprintf("projects/%s/topics/%s", projectID, topicName) + dt, cleanup1, err := createTopic(ctx, pc, topicName, topicPath) + if err != nil { + b.Fatal(err) + } + defer cleanup1() + topic := pubsub.NewTopic(dt, nil) + defer topic.Shutdown(ctx) + + // Make subscription. + sc, err := SubscriberClient(ctx, conn) + if err != nil { + b.Fatal(err) + } + subName := fmt.Sprintf("%s-subscription", b.Name()) + subPath := fmt.Sprintf("projects/%s/subscriptions/%s", projectID, subName) + ds, cleanup2, err := createSubscription(ctx, sc, dt, subName, subPath) + if err != nil { + b.Fatal(err) + } + defer cleanup2() + sub := pubsub.NewSubscription(ds, defaultRecvBatcherOpts, ackBatcherOpts) + defer sub.Shutdown(ctx) + + drivertest.RunBenchmarks(b, topic, sub) +} + +type gcpAsTest struct{} + +func (gcpAsTest) Name() string { + return "gcp test" +} + +func (gcpAsTest) TopicCheck(topic *pubsub.Topic) error { + var c2 raw.PublisherClient + if topic.As(&c2) { + return fmt.Errorf("cast succeeded for %T, want failure", &c2) + } + var c3 *raw.PublisherClient + if !topic.As(&c3) { + return fmt.Errorf("cast failed for %T", &c3) + } + return nil +} + +func (gcpAsTest) SubscriptionCheck(sub *pubsub.Subscription) error { + var c2 raw.SubscriberClient + if sub.As(&c2) { + return fmt.Errorf("cast succeeded for %T, want failure", &c2) + } + var c3 *raw.SubscriberClient + if !sub.As(&c3) { + return fmt.Errorf("cast failed for %T", &c3) + } + return nil +} + +func (gcpAsTest) TopicErrorCheck(t *pubsub.Topic, err error) error { + var s *status.Status + if !t.ErrorAs(err, &s) { + return fmt.Errorf("failed to convert %v (%T) to a gRPC Status", err, err) + } + if s.Code() != codes.NotFound { + return fmt.Errorf("got code %s, want NotFound", s.Code()) + } + return nil +} + +func (gcpAsTest) SubscriptionErrorCheck(sub *pubsub.Subscription, err error) error { + var s *status.Status + if !sub.ErrorAs(err, &s) { + return fmt.Errorf("failed to convert %v (%T) to a gRPC Status", err, err) + } + if s.Code() != codes.NotFound { + return fmt.Errorf("got code %s, want NotFound", s.Code()) + } + return nil +} + +func (gcpAsTest) MessageCheck(m *pubsub.Message) error { + var pm pubsubpb.PubsubMessage + if m.As(&pm) { + return fmt.Errorf("cast succeeded for %T, want failure", &pm) + } + var ppm *pubsubpb.PubsubMessage + if !m.As(&ppm) { + return fmt.Errorf("cast failed for %T", &ppm) + } + var prm *pubsubpb.ReceivedMessage + if !m.As(&prm) { + return fmt.Errorf("cast failed for %T", &prm) + } + return nil +} + +func (gcpAsTest) BeforeSend(as func(any) bool) error { + var ppm *pubsubpb.PubsubMessage + if !as(&ppm) { + return fmt.Errorf("cast failed for %T", &ppm) + } + return nil +} + +func (gcpAsTest) AfterSend(as func(any) bool) error { + var msgId string + if !as(&msgId) { + return fmt.Errorf("cast failed for %T", &msgId) + } + return nil +} + +func sanitize(testName string) string { + return strings.Replace(testName, "/", "_", -1) +} + +func TestOpenTopic(t *testing.T) { + ctx := context.Background() + creds, err := setup.FakeGCPCredentials(ctx) + if err != nil { + t.Fatal(err) + } + projID, err := gcp.DefaultProjectID(creds) + if err != nil { + t.Fatal(err) + } + conn, cleanup, err := Dial(ctx, gcp.CredentialsTokenSource(creds)) + if err != nil { + t.Fatal(err) + } + defer cleanup() + pc, err := PublisherClient(ctx, conn) + if err != nil { + t.Fatal(err) + } + topic := OpenTopic(pc, projID, "my-topic", nil) + defer topic.Shutdown(ctx) + err = topic.Send(ctx, &pubsub.Message{Body: []byte("hello world")}) + if err == nil { + t.Error("got nil, want error") + } + + // Repeat with OpenTopicByPath. + topic, err = OpenTopicByPath(pc, path.Join("projects", string(projID), "topics", "my-topic"), nil) + if err != nil { + t.Fatal(err) + } + defer topic.Shutdown(ctx) + err = topic.Send(ctx, &pubsub.Message{Body: []byte("hello world")}) + if err == nil { + t.Error("got nil, want error") + } + + // Try an invalid path. + _, err = OpenTopicByPath(pc, "my-topic", nil) + if err == nil { + t.Error("got nil, want error") + } +} + +func TestOpenSubscription(t *testing.T) { + ctx := context.Background() + creds, err := setup.FakeGCPCredentials(ctx) + if err != nil { + t.Fatal(err) + } + projID, err := gcp.DefaultProjectID(creds) + if err != nil { + t.Fatal(err) + } + conn, cleanup, err := Dial(ctx, gcp.CredentialsTokenSource(creds)) + if err != nil { + t.Fatal(err) + } + defer cleanup() + sc, err := SubscriberClient(ctx, conn) + if err != nil { + t.Fatal(err) + } + sub := OpenSubscription(sc, projID, "my-subscription", nil) + defer sub.Shutdown(ctx) + _, err = sub.Receive(ctx) + if err == nil { + t.Error("got nil, want error") + } + + // Repeat with OpenSubscriptionByPath. + sub, err = OpenSubscriptionByPath(sc, path.Join("projects", string(projID), "subscriptions", "my-subscription"), nil) + if err != nil { + t.Fatal(err) + } + defer sub.Shutdown(ctx) + _, err = sub.Receive(ctx) + if err == nil { + t.Error("got nil, want error") + } + + // Try an invalid path. + _, err = OpenSubscriptionByPath(sc, "my-subscription", nil) + if err == nil { + t.Error("got nil, want error") + } +} + +func TestOpenTopicFromURL(t *testing.T) { + cleanup := setup.FakeGCPDefaultCredentials(t) + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK, short form. + {"gcppubsub://myproject/mytopic", false}, + // OK, long form. + {"gcppubsub://projects/myproject/topic/mytopic", false}, + // Invalid parameter. + {"gcppubsub://myproject/mytopic?param=value", true}, + // Valid max_send_batch_size + {"gcppubsub://projects/mytopic?max_send_batch_size=1", false}, + // Invalid max_send_batch_size + {"gcppubsub://projects/mytopic?max_send_batch_size=0", true}, + // Invalid max_send_batch_size + {"gcppubsub://projects/mytopic?max_send_batch_size=1001", true}, + } + + ctx := context.Background() + for _, test := range tests { + topic, err := pubsub.OpenTopic(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if topic != nil { + topic.Shutdown(ctx) + } + } +} + +func TestOpenSubscriptionFromURL(t *testing.T) { + cleanup := setup.FakeGCPDefaultCredentials(t) + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK, short form. + {"gcppubsub://myproject/mysub", false}, + // OK, long form. + {"gcppubsub://projects/myproject/subscriptions/mysub", false}, + // Invalid parameter. + {"gcppubsub://myproject/mysub?param=value", true}, + // Valid max_recv_batch_size + {"gcppubsub://projects/myproject/subscriptions/mysub?max_recv_batch_size=1", false}, + // Invalid max_recv_batch_size + {"gcppubsub://projects/myproject/subscriptions/mysub?max_recv_batch_size=0", true}, + // Invalid max_recv_batch_size + {"gcppubsub://projects/myproject/subscriptions/mysub?max_recv_batch_size=1001", true}, + // Valid nacklazy + {"gcppubsub://projects/myproject/subscriptions/mysub?nacklazy=true", false}, + // Invalid nacklazy + {"gcppubsub://projects/myproject/subscriptions/mysub?nacklazy=foo", true}, + } + + ctx := context.Background() + for _, test := range tests { + sub, err := pubsub.OpenSubscription(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if sub != nil { + sub.Shutdown(ctx) + } + } +} diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestAs/gcp_test.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestAs/gcp_test.replay new file mode 100644 index 000000000..9f8a987c3 Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestAs/gcp_test.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..d52cbad92 Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestBatching.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestBatching.replay new file mode 100644 index 000000000..558b915ca Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestBatching.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestCancelSendReceive.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestCancelSendReceive.replay new file mode 100644 index 000000000..d88e38d93 Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestCancelSendReceive.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestDoubleAck.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestDoubleAck.replay new file mode 100644 index 000000000..33667d271 Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestDoubleAck.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestErrorOnReceiveFromClosedSubscription.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestErrorOnReceiveFromClosedSubscription.replay new file mode 100644 index 000000000..63da37af0 Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestErrorOnReceiveFromClosedSubscription.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestErrorOnSendToClosedTopic.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestErrorOnSendToClosedTopic.replay new file mode 100644 index 000000000..2daf3825c Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestErrorOnSendToClosedTopic.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestMetadata.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestMetadata.replay new file mode 100644 index 000000000..bdc7b5690 Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestMetadata.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNack.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNack.replay new file mode 100644 index 000000000..993a36831 Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNack.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay new file mode 100644 index 000000000..d24acaa19 Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNonExistentSubscriptionSucceedsOnOpenButFailsOnReceive.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay new file mode 100644 index 000000000..4b4cbaa3a Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNonExistentTopicSucceedsOnOpenButFailsOnSend.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNonUTF8MessageBody.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNonUTF8MessageBody.replay new file mode 100644 index 000000000..7c5a16040 Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestNonUTF8MessageBody.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestSendReceive.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestSendReceive.replay new file mode 100644 index 000000000..475f02dad Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestSendReceive.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestSendReceiveJSON.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestSendReceiveJSON.replay new file mode 100644 index 000000000..3cb320998 Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestSendReceiveJSON.replay differ diff --git a/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestSendReceiveTwo.replay b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestSendReceiveTwo.replay new file mode 100644 index 000000000..ce544917b Binary files /dev/null and b/go-cloud/pubsub/gcppubsub/testdata/TestConformance/TestSendReceiveTwo.replay differ diff --git a/go-cloud/pubsub/kafkapubsub/example_test.go b/go-cloud/pubsub/kafkapubsub/example_test.go new file mode 100644 index 000000000..8a8836138 --- /dev/null +++ b/go-cloud/pubsub/kafkapubsub/example_test.go @@ -0,0 +1,95 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 kafkapubsub_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/kafkapubsub" +) + +func ExampleOpenTopic() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // The set of brokers in the Kafka cluster. + addrs := []string{"1.2.3.4:9092"} + // The Kafka client configuration to use. + config := kafkapubsub.MinimalConfig() + + // Construct a *pubsub.Topic. + topic, err := kafkapubsub.OpenTopic(addrs, config, "my-topic", nil) + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func ExampleOpenSubscription() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // The set of brokers in the Kafka cluster. + addrs := []string{"1.2.3.4:9092"} + // The Kafka client configuration to use. + config := kafkapubsub.MinimalConfig() + + // Construct a *pubsub.Subscription, joining the consumer group "my-group" + // and receiving messages from "my-topic". + subscription, err := kafkapubsub.OpenSubscription( + addrs, config, "my-group", []string{"my-topic"}, nil) + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} + +func Example_openTopicFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/kafkapubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenTopic creates a *pubsub.Topic from a URL. + // The host + path are the topic name to send to. + // The set of brokers must be in an environment variable KAFKA_BROKERS. + topic, err := pubsub.OpenTopic(ctx, "kafka://my-topic?key_name=x-partition-key") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func Example_openSubscriptionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/kafkapubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenSubscription creates a *pubsub.Subscription from a URL. + // The host + path are used as the consumer group name. + // The "topic" query parameter sets one or more topics to subscribe to. + // The set of brokers must be in an environment variable KAFKA_BROKERS. + subscription, err := pubsub.OpenSubscription(ctx, + "kafka://my-group?topic=my-topic") + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} diff --git a/go-cloud/pubsub/kafkapubsub/go.mod b/go-cloud/pubsub/kafkapubsub/go.mod new file mode 100644 index 000000000..98ba9879f --- /dev/null +++ b/go-cloud/pubsub/kafkapubsub/go.mod @@ -0,0 +1,89 @@ +// Copyright 2018-2019 The Go Cloud Development Kit 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 +// +// https://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. + +module gocloud.dev/pubsub/kafkapubsub + +go 1.24 + +require ( + github.com/IBM/sarama v1.45.2 + github.com/google/go-cmp v0.7.0 + gocloud.dev v0.43.0 +) + +require ( + cloud.google.com/go/auth v0.16.3 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + cloud.google.com/go/compute/metadata v0.7.0 // indirect + github.com/aws/aws-sdk-go v1.55.7 // indirect + github.com/aws/aws-sdk-go-v2 v1.36.5 // indirect + github.com/aws/aws-sdk-go-v2/config v1.29.17 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.70 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 // indirect + github.com/aws/smithy-go v1.22.4 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/eapache/go-resiliency v1.7.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect + github.com/eapache/queue v1.1.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/google/go-replayers/grpcreplay v1.3.0 // indirect + github.com/google/go-replayers/httpreplay v1.2.0 // indirect + github.com/google/martian/v3 v3.3.3 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/google/wire v0.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/jcmturner/aescts/v2 v2.0.0 // indirect + github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect + github.com/jcmturner/gofork v1.7.6 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect + github.com/jcmturner/rpc/v2 v2.0.3 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/pierrec/lz4/v4 v4.1.22 // indirect + github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect + go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/sdk v1.37.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect + go.opentelemetry.io/otel/trace v1.37.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + google.golang.org/api v0.242.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 // indirect + google.golang.org/grpc v1.73.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect +) diff --git a/go-cloud/pubsub/kafkapubsub/go.sum b/go-cloud/pubsub/kafkapubsub/go.sum new file mode 100644 index 000000000..7d1f4b5c8 --- /dev/null +++ b/go-cloud/pubsub/kafkapubsub/go.sum @@ -0,0 +1,717 @@ +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +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.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= +cloud.google.com/go v0.121.4 h1:cVvUiY0sX0xwyxPwdSU2KsF9knOVmtRyAMt8xou0iTs= +cloud.google.com/go v0.121.4/go.mod h1:XEBchUiHFJbz4lKBZwYBDHV/rSyfFktk737TLDU089s= +cloud.google.com/go/auth v0.16.3 h1:kabzoQ9/bobUmnseYnBO6qQG7q4a/CffFRlJSxv2wCc= +cloud.google.com/go/auth v0.16.3/go.mod h1:NucRGjaXfzP1ltpcQ7On/VTZ0H4kWB5Jy+Y9Dnm76fA= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/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/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= +cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +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/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= +cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM= +cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U= +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= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.49.0 h1:5054IkbslnrMCgA2MAEPcsN3Ky+AyMpEZcii/DoySPo= +cloud.google.com/go/pubsub v1.49.0/go.mod h1:K1FswTWP+C1tI/nfi3HQecoVeFvL4HUOB1tdaNXKhUY= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.55.0 h1:NESjdAToN9u1tmhVqhXCaCwYBuvEhZLLv0gBr+2znf0= +cloud.google.com/go/storage v1.55.0/go.mod h1:ztSmTTwzsdXe5syLVS0YsbFxXuvEmEyZj7v7zChEmuY= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo= +github.com/IBM/sarama v1.45.2 h1:8m8LcMCu3REcwpa7fCP6v2fuPuzVwXDAM2DOv3CBrKw= +github.com/IBM/sarama v1.45.2/go.mod h1:ppaoTcVdGv186/z6MEKsMm70A5fwJfRTpstI37kVn3Y= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0= +github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2/config v1.29.17 h1:jSuiQ5jEe4SAMH6lLRMY9OVC+TqJLP5655pBGjmnjr0= +github.com/aws/aws-sdk-go-v2/config v1.29.17/go.mod h1:9P4wwACpbeXs9Pm9w1QTh6BwWwJjwYvJ1iCt5QbCXh8= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70 h1:ONnH5CM16RTXRkS8Z1qg7/s2eDOhHhaXVd72mmyv4/0= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70/go.mod h1:M+lWhhmomVGgtuPOhO85u4pEa3SmssPTdcYpP/5J/xc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 h1:KAXP9JSHO1vKGCr5f4O6WmlVKLFFXgWYAGoJosorxzU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32/go.mod h1:h4Sg6FQdexC1yYG9RDnOvLbW1a/P986++/Y/a+GyEM8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 h1:t0E6FzREdtCsiLIoLCWsYliNsRBgyGD/MCK571qk4MI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17/go.mod h1:ygpklyoaypuyDvOM5ujWGrYWpAK3h7ugnmKCU/76Ys4= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 h1:AIRJ3lfb2w/1/8wOOSqYb9fUKGwQbtysJ2H1MofRUPg= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5/go.mod h1:b7SiVprpU+iGazDUqvRSLf5XmCdn+JtT1on7uNL6Ipc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 h1:BpOxT3yhLwSJ77qIY3DoHAQjZsc4HEGfMCE4NGy3uFg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3/go.mod h1:vq/GQR1gOFLquZMSrxUK/cpvKCNVYibNyJ1m7JrU88E= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 h1:NFOJ/NXEGV4Rq//71Hs1jC/NvPs1ezajK+yQmkwnPV0= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0/go.mod h1:7ph2tGpfQvwzgistp2+zga9f+bCjlQJPkPUmMgDSD7w= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +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= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +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/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA= +github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= +github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= +github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +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= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +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/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= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-replayers/grpcreplay v1.3.0 h1:1Keyy0m1sIpqstQmgz307zhiJ1pV4uIlFds5weTmxbo= +github.com/google/go-replayers/grpcreplay v1.3.0/go.mod h1:v6NgKtkijC0d3e3RW8il6Sy5sqRVUwoQa4mHOGEy8DI= +github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk= +github.com/google/go-replayers/httpreplay v1.2.0/go.mod h1:WahEFFZZ7a1P4VM1qEeHy+tME4bwyqPcwWbNlUI1Mcg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= +github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +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.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +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-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +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/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= +github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 h1:bsUq1dX0N8AOIL7EB/X911+m4EHsnWEHeJ0c+3TTBrg= +github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0 h1:B+WbN9RPsvobe6q4vP6KgM8/9plR/HNjgGBrfcOlweA= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0/go.mod h1:K5zQ3TT7p2ru9Qkzk0bKtCql0RGkPj9pRjpXgZJZ+rU= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 h1:rbRJ8BBoVMsQShESYZ0FkvcITu8X8QNwJogcLUmDNNw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0/go.mod h1:ru6KHrNtNHxM4nD/vd6QrLVWgKhxPYgblq4VAtNawTQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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/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= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +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-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= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/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.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-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/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.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.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +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-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +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.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.242.0 h1:7Lnb1nfnpvbkCiZek6IXKdJ0MFuAZNAJKQfA1ws62xg= +google.golang.org/api v0.242.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= +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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +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= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 h1:Nt6z9UHqSlIdIGJdz6KhTIs2VRx/iOsA5iE8bmQNcxs= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79/go.mod h1:kTmlBHMPqR5uCZPBvwa2B18mvubkjyY3CRLI0c6fj0s= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79 h1:iOye66xuaAK0WnkPuhQPUFy8eJcmwUXqGGP3om6IxX8= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79/go.mod h1:HKJDgKsFUnv5VAGeQjz8kxcgDP0HoE0iZNp0OdZNlhE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 h1:1ZwqphdOdWYXsUHgMpU/101nCtf/kSp9hOrcvFsnl10= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +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.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/go-cloud/pubsub/kafkapubsub/kafka.go b/go-cloud/pubsub/kafkapubsub/kafka.go new file mode 100644 index 000000000..3906208ba --- /dev/null +++ b/go-cloud/pubsub/kafkapubsub/kafka.go @@ -0,0 +1,717 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 kafkapubsub provides an implementation of pubsub for Kafka. +// It requires a minimum Kafka version of 0.11.x for Header support. +// Some functionality may work with earlier versions of Kafka. +// +// See https://kafka.apache.org/documentation.html#semantics for a discussion +// of message semantics in Kafka. sarama.Config exposes many knobs that +// can affect performance and semantics, so review and set them carefully. +// +// kafkapubsub does not support Message.Nack; Message.Nackable will return +// false, and Message.Nack will panic if called. +// +// # URLs +// +// For pubsub.OpenTopic and pubsub.OpenSubscription, kafkapubsub registers +// for the scheme "kafka". +// The default URL opener will connect to a default set of Kafka brokers based +// on the environment variable "KAFKA_BROKERS", expected to be a comma-delimited +// set of server addresses. +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # Escaping +// +// Go CDK supports all UTF-8 strings. No escaping is required for Kafka. +// Message metadata is supported through Kafka Headers, which allow arbitrary +// []byte for both key and value. These are converted to string for use in +// Message.Metadata. +// +// # As +// +// kafkapubsub exposes the following types for As: +// - Topic: sarama.SyncProducer +// - Subscription: sarama.ConsumerGroup, sarama.ConsumerGroupSession (may be nil during session renegotiation, and session may go stale at any time) +// - Message: *sarama.ConsumerMessage +// - Message.BeforeSend: *sarama.ProducerMessage +// - Message.AfterSend: None +// - Error: sarama.ConsumerError, sarama.ConsumerErrors, sarama.ProducerError, sarama.ProducerErrors, sarama.ConfigurationError, sarama.PacketDecodingError, sarama.PacketEncodingError, sarama.KError +package kafkapubsub // import "gocloud.dev/pubsub/kafkapubsub" + +import ( + "context" + "errors" + "fmt" + "net/url" + "os" + "path" + "reflect" + "strings" + "sync" + "time" + + "github.com/IBM/sarama" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/batcher" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" +) + +var sendBatcherOpts = &batcher.Options{ + MaxBatchSize: 100, + MaxHandlers: 100, // max concurrency for sends +} + +var recvBatcherOpts = &batcher.Options{ + // Concurrency doesn't make sense here. + MaxBatchSize: 1, + MaxHandlers: 1, +} + +func init() { + opener := new(defaultOpener) + pubsub.DefaultURLMux().RegisterTopic(Scheme, opener) + pubsub.DefaultURLMux().RegisterSubscription(Scheme, opener) +} + +// defaultOpener create a default opener. +type defaultOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *defaultOpener) defaultOpener() (*URLOpener, error) { + o.init.Do(func() { + brokerList := os.Getenv("KAFKA_BROKERS") + if brokerList == "" { + o.err = errors.New("KAFKA_BROKERS environment variable not set") + return + } + brokers := strings.Split(brokerList, ",") + for i, b := range brokers { + brokers[i] = strings.TrimSpace(b) + } + o.opener = &URLOpener{ + Brokers: brokers, + Config: MinimalConfig(), + } + }) + return o.opener, o.err +} + +func (o *defaultOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + opener, err := o.defaultOpener() + if err != nil { + return nil, fmt.Errorf("open topic %v: %v", u, err) + } + return opener.OpenTopicURL(ctx, u) +} + +func (o *defaultOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + opener, err := o.defaultOpener() + if err != nil { + return nil, fmt.Errorf("open subscription %v: %v", u, err) + } + return opener.OpenSubscriptionURL(ctx, u) +} + +// Scheme is the URL scheme that kafkapubsub registers its URLOpeners under on pubsub.DefaultMux. +const Scheme = "kafka" + +// URLOpener opens Kafka URLs like "kafka://mytopic" for topics and +// "kafka://group?topic=mytopic" for subscriptions. +// +// For topics, the URL's host+path is used as the topic name, +// and the "key_name" query parameter is used to extract the routing key +// from metadata. +// +// For subscriptions, the URL's host+path is used as the group name, +// and the "topic" query parameter(s) are used as the set of topics to +// subscribe to. The "offset" parameter is available to subscribers to set +// the Kafka consumer's initial offset. Where "oldest" starts consuming from +// the oldest offset of the consumer group and "newest" starts consuming from +// the most recent offset on the topic. +type URLOpener struct { + // Brokers is the slice of brokers in the Kafka cluster. + Brokers []string + // Config is the Sarama Config. + // Config.Producer.Return.Success must be set to true. + Config *sarama.Config + + // TopicOptions specifies the options to pass to OpenTopic. + TopicOptions TopicOptions + // SubscriptionOptions specifies the options to pass to OpenSubscription. + SubscriptionOptions SubscriptionOptions +} + +// OpenTopicURL opens a pubsub.Topic based on u. +func (o *URLOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + for param, value := range u.Query() { + switch param { + case "key_name": + if len(value) != 1 || len(value[0]) == 0 { + return nil, fmt.Errorf("open topic %v: invalid query parameter %q", u, param) + } + + o.TopicOptions.KeyName = value[0] + default: + return nil, fmt.Errorf("open topic %v: invalid query parameter %q", u, param) + } + } + + topicName := path.Join(u.Host, u.Path) + return OpenTopic(o.Brokers, o.Config, topicName, &o.TopicOptions) +} + +// OpenSubscriptionURL opens a pubsub.Subscription based on u. +func (o *URLOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + var topics []string + for param, value := range u.Query() { + switch param { + case "topic": + topics = value + case "offset": + if len(value) == 0 { + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q", u, param) + } + + offset := value[0] + switch offset { + case "oldest": + o.Config.Consumer.Offsets.Initial = sarama.OffsetOldest + case "newest": + o.Config.Consumer.Offsets.Initial = sarama.OffsetNewest + default: + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q", u, offset) + } + default: + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q", u, param) + } + } + + group := path.Join(u.Host, u.Path) + return OpenSubscription(o.Brokers, o.Config, group, topics, &o.SubscriptionOptions) +} + +// MinimalConfig returns a minimal sarama.Config. +func MinimalConfig() *sarama.Config { + config := sarama.NewConfig() + config.Version = sarama.V0_11_0_0 // required for Headers + config.Producer.Return.Successes = true // required for SyncProducer + return config +} + +type topic struct { + producer sarama.SyncProducer + topicName string + opts TopicOptions +} + +// TopicOptions contains configuration options for topics. +type TopicOptions struct { + // KeyName optionally sets the Message.Metadata key to use as the optional + // Kafka message key. If set, and if a matching Message.Metadata key is found, + // the value for that key will be used as the message key when sending to + // Kafka, instead of being added to the message headers. + KeyName string + + // BatcherOptions adds constraints to the default batching done for sends. + BatcherOptions batcher.Options +} + +// OpenTopic creates a pubsub.Topic that sends to a Kafka topic. +// +// It uses a sarama.SyncProducer to send messages. Producer options can +// be configured in the Producer section of the sarama.Config: +// https://godoc.org/github.com/IBM/sarama#Config. +// +// Config.Producer.Return.Success must be set to true. +func OpenTopic(brokers []string, config *sarama.Config, topicName string, opts *TopicOptions) (*pubsub.Topic, error) { + dt, err := openTopic(brokers, config, topicName, opts) + if err != nil { + return nil, err + } + bo := sendBatcherOpts.NewMergedOptions(&dt.opts.BatcherOptions) + return pubsub.NewTopic(dt, bo), nil +} + +// openTopic returns the driver for OpenTopic. This function exists so the test +// harness can get the driver interface implementation if it needs to. +func openTopic(brokers []string, config *sarama.Config, topicName string, opts *TopicOptions) (*topic, error) { + if opts == nil { + opts = &TopicOptions{} + } + producer, err := sarama.NewSyncProducer(brokers, config) + if err != nil { + return nil, err + } + return &topic{producer: producer, topicName: topicName, opts: *opts}, nil +} + +// SendBatch implements driver.Topic.SendBatch. +func (t *topic) SendBatch(ctx context.Context, dms []*driver.Message) error { + // Convert the messages to a slice of sarama.ProducerMessage. + ms := make([]*sarama.ProducerMessage, 0, len(dms)) + for _, dm := range dms { + var kafkaKey sarama.Encoder + var headers []sarama.RecordHeader + for k, v := range dm.Metadata { + if k == t.opts.KeyName { + // Use this key's value as the Kafka message key instead of adding it + // to the headers. + kafkaKey = sarama.ByteEncoder(v) + } else { + headers = append(headers, sarama.RecordHeader{Key: []byte(k), Value: []byte(v)}) + } + } + pm := &sarama.ProducerMessage{ + Topic: t.topicName, + Key: kafkaKey, + Value: sarama.ByteEncoder(dm.Body), + Headers: headers, + } + if dm.BeforeSend != nil { + asFunc := func(i any) bool { + if p, ok := i.(**sarama.ProducerMessage); ok { + *p = pm + return true + } + return false + } + if err := dm.BeforeSend(asFunc); err != nil { + return err + } + } + ms = append(ms, pm) + + } + err := t.producer.SendMessages(ms) + if err != nil { + return err + } + for _, dm := range dms { + if dm.AfterSend != nil { + asFunc := func(i any) bool { return false } + if err := dm.AfterSend(asFunc); err != nil { + return err + } + } + } + return nil +} + +// Close implements io.Closer. +func (t *topic) Close() error { + return t.producer.Close() +} + +// IsRetryable implements driver.Topic.IsRetryable. +func (t *topic) IsRetryable(error) bool { + return false +} + +// As implements driver.Topic.As. +func (t *topic) As(i any) bool { + if p, ok := i.(*sarama.SyncProducer); ok { + *p = t.producer + return true + } + return false +} + +// ErrorAs implements driver.Topic.ErrorAs. +func (t *topic) ErrorAs(err error, i any) bool { + return errorAs(err, i) +} + +// ErrorCode implements driver.Topic.ErrorCode. +func (t *topic) ErrorCode(err error) gcerrors.ErrorCode { + return errorCode(err) +} + +func errorCode(err error) gcerrors.ErrorCode { + if pes, ok := err.(sarama.ProducerErrors); ok && len(pes) == 1 { + return errorCode(pes[0]) + } + if pe, ok := err.(*sarama.ProducerError); ok { + return errorCode(pe.Err) + } + if err == sarama.ErrUnknownTopicOrPartition { + return gcerrors.NotFound + } + return gcerrors.Unknown +} + +type subscription struct { + opts SubscriptionOptions + closeCh chan struct{} // closed when we've shut down + joinCh chan struct{} // closed when we join for the first time + cancel func() // cancels the background consumer + closeErr error // fatal error detected by the background consumer + consumerGroup sarama.ConsumerGroup + + mu sync.Mutex + unacked []*ackInfo + sess sarama.ConsumerGroupSession // current session, if any, used for marking offset updates + expectedClaims int // # of expected claims for the current session, they should be added via ConsumeClaim + claims []sarama.ConsumerGroupClaim // claims in the current session +} + +// ackInfo stores info about a message and whether it has been acked. +// It is used as the driver.AckID. +type ackInfo struct { + msg *sarama.ConsumerMessage + acked bool +} + +// SubscriptionOptions contains configuration for subscriptions. +type SubscriptionOptions struct { + // KeyName optionally sets the Message.Metadata key in which to store the + // Kafka message key. If set, and if the Kafka message key is non-empty, + // the key value will be stored in Message.Metadata under KeyName. + KeyName string + + // WaitForJoin causes OpenSubscription to wait for up to WaitForJoin + // to allow the client to join the consumer group. + // Messages sent to the topic before the client joins the group + // may not be received by this subscription. + // OpenSubscription will succeed even if WaitForJoin elapses and + // the subscription still hasn't been joined successfully. + WaitForJoin time.Duration +} + +// OpenSubscription creates a pubsub.Subscription that joins group, receiving +// messages from topics. +// +// It uses a sarama.ConsumerGroup to receive messages. Consumer options can +// be configured in the Consumer section of the sarama.Config: +// https://godoc.org/github.com/IBM/sarama#Config. +func OpenSubscription(brokers []string, config *sarama.Config, group string, topics []string, opts *SubscriptionOptions) (*pubsub.Subscription, error) { + ds, err := openSubscription(brokers, config, group, topics, opts) + if err != nil { + return nil, err + } + return pubsub.NewSubscription(ds, recvBatcherOpts, nil), nil +} + +// openSubscription returns the driver for OpenSubscription. This function +// exists so the test harness can get the driver interface implementation if it +// needs to. +func openSubscription(brokers []string, config *sarama.Config, group string, topics []string, opts *SubscriptionOptions) (driver.Subscription, error) { + if opts == nil { + opts = &SubscriptionOptions{} + } + consumerGroup, err := sarama.NewConsumerGroup(brokers, group, config) + if err != nil { + return nil, err + } + // Create a cancelable context for the background goroutine that + // consumes messages. + ctx, cancel := context.WithCancel(context.Background()) + joinCh := make(chan struct{}) + ds := &subscription{ + opts: *opts, + consumerGroup: consumerGroup, + closeCh: make(chan struct{}), + joinCh: joinCh, + cancel: cancel, + } + // Start a background consumer. It should run until ctx is cancelled + // by Close, or until there's a fatal error (e.g., topic doesn't exist). + // We're registering ds as our ConsumerGroupHandler, so sarama will + // call [Setup, ConsumeClaim (possibly more than once), Cleanup] + // repeatedly as the consumer group is rebalanced. + // See https://godoc.org/github.com/IBM/sarama#ConsumerGroup. + go func() { + for { + ds.closeErr = consumerGroup.Consume(ctx, topics, ds) + if ds.closeErr != nil || ctx.Err() != nil { + consumerGroup.Close() + close(ds.closeCh) + break + } + } + }() + if opts.WaitForJoin > 0 { + // Best effort wait for first consumer group session. + select { + case <-joinCh: + case <-ds.closeCh: + case <-time.After(opts.WaitForJoin): + } + } + return ds, nil +} + +// Setup implements sarama.ConsumerGroupHandler.Setup. It is called whenever +// a new session with the broker is starting. +func (s *subscription) Setup(sess sarama.ConsumerGroupSession) error { + // Record the current session. + s.mu.Lock() + defer s.mu.Unlock() + s.sess = sess + s.expectedClaims = 0 + for _, claims := range sess.Claims() { + s.expectedClaims += len(claims) + } + return nil +} + +// Cleanup implements sarama.ConsumerGroupHandler.Cleanup. +func (s *subscription) Cleanup(sarama.ConsumerGroupSession) error { + // Clear the current session. + s.mu.Lock() + defer s.mu.Unlock() + s.sess = nil + s.expectedClaims = 0 + s.claims = nil + return nil +} + +// ConsumeClaim implements sarama.ConsumerGroupHandler.ConsumeClaim. +// This is where messages are actually delivered, via a channel. +func (s *subscription) ConsumeClaim(sess sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error { + s.mu.Lock() + s.claims = append(s.claims, claim) + // Once all of the expected claims have registered, close joinCh to (possibly) wake up OpenSubscription. + if s.joinCh != nil && len(s.claims) == s.expectedClaims { + close(s.joinCh) + s.joinCh = nil + } + s.mu.Unlock() + <-sess.Context().Done() + return nil +} + +// ReceiveBatch implements driver.Subscription.ReceiveBatch. +func (s *subscription) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + // Try to read maxMessages for up to 100ms before giving up. + maxWaitCtx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) + defer cancel() + + for { + // We'll give up after maxWaitCtx is Done, or if s.closeCh is closed. + // Otherwise, we want to pull a message from one of the channels in the + // claim(s) we've been given. + // + // Note: we could multiplex this by ranging over each claim.Messages(), + // writing the messages to a single ch, and then reading from that ch + // here. However, this results in us reading messages from Kafka and + // essentially queueing them here; when the session is closed for whatever + // reason, those messages are lost, which may or may not be an issue + // depending on the Kafka configuration being used. + // + // It seems safer to use reflect.Select to explicitly only get a single + // message at a time, and hand it directly to the user. + // + // reflect.Select is essentially a "select" statement, but allows us to + // build the cases dynamically. We need that because we need a case for + // each of the claims in s.claims. + s.mu.Lock() + cases := make([]reflect.SelectCase, 0, len(s.claims)+2) + // Add a case for s.closeCh being closed, at index = 0. + cases = append(cases, reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(s.closeCh), + }) + // Add a case for maxWaitCtx being Done, at index = 1. + cases = append(cases, reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(maxWaitCtx.Done()), + }) + // Add a case per claim, reading from the claim's Messages channel. + for _, claim := range s.claims { + cases = append(cases, reflect.SelectCase{ + Dir: reflect.SelectRecv, + Chan: reflect.ValueOf(claim.Messages()), + }) + } + s.mu.Unlock() + i, v, ok := reflect.Select(cases) + if !ok { + // The i'th channel was closed. + switch i { + case 0: // s.closeCh + return nil, s.closeErr + case 1: // maxWaitCtx + // We've tried for a while to get a message, but didn't get any. + // Return an empty slice; the portable type will call us back. + return nil, ctx.Err() + } + // Otherwise, if one of the claim channels closed, we're probably ending + // a session. Just keep trying. + continue + } + msg := v.Interface().(*sarama.ConsumerMessage) + + // We've got a message! It should not be nil. + // Read the metadata from msg.Headers. + md := map[string]string{} + for _, h := range msg.Headers { + md[string(h.Key)] = string(h.Value) + } + // Add a metadata entry for the message key if appropriate. + if len(msg.Key) > 0 && s.opts.KeyName != "" { + md[s.opts.KeyName] = string(msg.Key) + } + ack := &ackInfo{msg: msg} + var loggableID string + if len(msg.Key) == 0 { + loggableID = fmt.Sprintf("partition %d offset %d", msg.Partition, msg.Offset) + } else { + loggableID = string(msg.Key) + } + dm := &driver.Message{ + LoggableID: loggableID, + Body: msg.Value, + Metadata: md, + AckID: ack, + AsFunc: func(i any) bool { + if p, ok := i.(**sarama.ConsumerMessage); ok { + *p = msg + return true + } + return false + }, + } + s.mu.Lock() + defer s.mu.Unlock() + s.unacked = append(s.unacked, ack) + return []*driver.Message{dm}, nil + } +} + +// SendAcks implements driver.Subscription.SendAcks. +func (s *subscription) SendAcks(ctx context.Context, ids []driver.AckID) error { + s.mu.Lock() + defer s.mu.Unlock() + + // Mark them all acked. + for _, id := range ids { + id.(*ackInfo).acked = true + } + if s.sess == nil { + // We don't have a current session, so we can't send offset updates. + // We'll just wait until next time and retry. + return nil + } + // Mark all of the acked messages at the head of the slice. Since Kafka only + // stores a single offset, we can't mark messages that aren't at the head; that + // would move the offset past other as-yet-unacked messages. + for len(s.unacked) > 0 && s.unacked[0].acked { + s.sess.MarkMessage(s.unacked[0].msg, "") + s.unacked = s.unacked[1:] + } + return nil +} + +// CanNack implements driver.CanNack. +func (s *subscription) CanNack() bool { + // Nacking a single message doesn't make sense with the way Kafka maintains + // offsets. + return false +} + +// SendNacks implements driver.Subscription.SendNacks. +func (s *subscription) SendNacks(ctx context.Context, ids []driver.AckID) error { + panic("unreachable") +} + +// Close implements io.Closer. +func (s *subscription) Close() error { + // Cancel the ctx for the background goroutine and wait until it's done. + s.cancel() + <-s.closeCh + return nil +} + +// IsRetryable implements driver.Subscription.IsRetryable. +func (*subscription) IsRetryable(error) bool { + return false +} + +// As implements driver.Subscription.As. +func (s *subscription) As(i any) bool { + if p, ok := i.(*sarama.ConsumerGroup); ok { + *p = s.consumerGroup + return true + } + if p, ok := i.(*sarama.ConsumerGroupSession); ok { + s.mu.Lock() + defer s.mu.Unlock() + *p = s.sess + return true + } + return false +} + +// ErrorAs implements driver.Subscription.ErrorAs. +func (s *subscription) ErrorAs(err error, i any) bool { + return errorAs(err, i) +} + +// ErrorCode implements driver.Subscription.ErrorCode. +func (*subscription) ErrorCode(err error) gcerrors.ErrorCode { + return errorCode(err) +} + +func errorAs(err error, i any) bool { + switch terr := err.(type) { + case sarama.ConsumerError: + if p, ok := i.(*sarama.ConsumerError); ok { + *p = terr + return true + } + case sarama.ConsumerErrors: + if p, ok := i.(*sarama.ConsumerErrors); ok { + *p = terr + return true + } + case sarama.ProducerError: + if p, ok := i.(*sarama.ProducerError); ok { + *p = terr + return true + } + case sarama.ProducerErrors: + if p, ok := i.(*sarama.ProducerErrors); ok { + *p = terr + return true + } + case sarama.ConfigurationError: + if p, ok := i.(*sarama.ConfigurationError); ok { + *p = terr + return true + } + case sarama.PacketDecodingError: + if p, ok := i.(*sarama.PacketDecodingError); ok { + *p = terr + return true + } + case sarama.PacketEncodingError: + if p, ok := i.(*sarama.PacketEncodingError); ok { + *p = terr + return true + } + case sarama.KError: + if p, ok := i.(*sarama.KError); ok { + *p = terr + return true + } + } + return false +} diff --git a/go-cloud/pubsub/kafkapubsub/kafka_test.go b/go-cloud/pubsub/kafkapubsub/kafka_test.go new file mode 100644 index 000000000..f9089e93b --- /dev/null +++ b/go-cloud/pubsub/kafkapubsub/kafka_test.go @@ -0,0 +1,540 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 kafkapubsub // import "gocloud.dev/pubsub/kafkapubsub" + +// To run these tests against a real Kafka server, run localkafka.sh. +// See https://github.com/spotify/docker-kafka for more on the docker container +// that the script runs. + +import ( + "context" + "errors" + "fmt" + "math/rand" + "os" + "strings" + "sync/atomic" + "testing" + "time" + + "github.com/IBM/sarama" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/drivertest" +) + +var ( + localBrokerAddrs = []string{"localhost:9092"} + // Makes OpenSubscription wait ~forever until the subscriber has joined the + // ConsumerGroup. Messages sent to the topic before the subscriber has joined + // won't be received. + subscriptionOptions = &SubscriptionOptions{WaitForJoin: 24 * time.Hour} +) + +type harness struct { + uniqueID int + numSubs uint32 + numTopics uint32 +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + if !setup.HasDockerTestEnvironment() { + t.Skip("Skipping Kafka tests since the Kafka server is not available") + } + return &harness{uniqueID: rand.Int()}, nil +} + +func createKafkaTopic(topicName string, partitions int32) (func(), error) { + // Create the topic. + config := MinimalConfig() + admin, err := sarama.NewClusterAdmin(localBrokerAddrs, config) + if err != nil { + return func() {}, err + } + close1 := func() { admin.Close() } + + topicDetail := &sarama.TopicDetail{ + NumPartitions: partitions, + ReplicationFactor: 1, + } + if err := admin.CreateTopic(topicName, topicDetail, false); err != nil { + return close1, err + } + close2 := func() { + admin.DeleteTopic(topicName) + close1() + } + return close2, nil +} + +func (h *harness) CreateTopic(ctx context.Context, testName string) (driver.Topic, func(), error) { + topicName := fmt.Sprintf("%s-topic-%d-%d", sanitize(testName), h.uniqueID, atomic.AddUint32(&h.numTopics, 1)) + cleanup, err := createKafkaTopic(topicName, 1) + if err != nil { + return nil, cleanup, err + } + + // Open it. + dt, err := openTopic(localBrokerAddrs, MinimalConfig(), topicName, nil) + if err != nil { + return nil, cleanup, err + } + return dt, cleanup, nil +} + +func (h *harness) MakeNonexistentTopic(ctx context.Context) (driver.Topic, error) { + return openTopic(localBrokerAddrs, MinimalConfig(), "nonexistent-topic", nil) +} + +func (h *harness) CreateSubscription(ctx context.Context, dt driver.Topic, testName string) (driver.Subscription, func(), error) { + groupID := fmt.Sprintf("%s-sub-%d-%d", sanitize(testName), h.uniqueID, atomic.AddUint32(&h.numSubs, 1)) + ds, err := openSubscription(localBrokerAddrs, MinimalConfig(), groupID, []string{dt.(*topic).topicName}, subscriptionOptions) + return ds, func() {}, err +} + +func (h *harness) MakeNonexistentSubscription(ctx context.Context) (driver.Subscription, func(), error) { + ds, err := openSubscription(localBrokerAddrs, MinimalConfig(), "unused-group", []string{"nonexistent-topic"}, subscriptionOptions) + return ds, func() {}, err +} + +func (h *harness) Close() {} + +func (h *harness) MaxBatchSizes() (int, int) { return sendBatcherOpts.MaxBatchSize, 0 } + +func (*harness) SupportsMultipleSubscriptions() bool { return true } + +func TestConformance(t *testing.T) { + asTests := []drivertest.AsTest{asTest{}} + drivertest.RunConformanceTests(t, newHarness, asTests) +} + +type asTest struct{} + +func (asTest) Name() string { + return "kafka" +} + +func (asTest) TopicCheck(topic *pubsub.Topic) error { + var sp sarama.SyncProducer + if !topic.As(&sp) { + return fmt.Errorf("cast failed for %T", sp) + } + return nil +} + +func (asTest) SubscriptionCheck(sub *pubsub.Subscription) error { + var cg sarama.ConsumerGroup + if !sub.As(&cg) { + return fmt.Errorf("cast failed for %T", cg) + } + var cgs sarama.ConsumerGroupSession + if !sub.As(&cgs) { + return fmt.Errorf("cast failed for %T", cgs) + } + return nil +} + +func (asTest) TopicErrorCheck(t *pubsub.Topic, err error) error { + var pe sarama.ProducerErrors + if !t.ErrorAs(err, &pe) { + return fmt.Errorf("failed to convert %v (%T)", err, err) + } + return nil +} + +func (asTest) SubscriptionErrorCheck(s *pubsub.Subscription, err error) error { + var ke sarama.KError + if !s.ErrorAs(err, &ke) { + return fmt.Errorf("failed to convert %v (%T)", err, err) + } + return nil +} + +func (asTest) MessageCheck(m *pubsub.Message) error { + var cm *sarama.ConsumerMessage + if !m.As(&cm) { + return fmt.Errorf("cast failed for %T", cm) + } + return nil +} + +func (asTest) BeforeSend(as func(any) bool) error { + var pm *sarama.ProducerMessage + if !as(&pm) { + return fmt.Errorf("cast failed for %T", &pm) + } + return nil +} + +func (asTest) AfterSend(as func(any) bool) error { + return nil +} + +// TestKafkaKey tests sending/receiving a message with the Kafka message key set. +func TestKafkaKey(t *testing.T) { + if !setup.HasDockerTestEnvironment() { + t.Skip("Skipping Kafka tests since the Kafka server is not available") + } + const ( + keyName = "kafkakey" + keyValue = "kafkakeyvalue" + ) + uniqueID := rand.Int() + ctx := context.Background() + + topicName := fmt.Sprintf("%s-topic-%d", sanitize(t.Name()), uniqueID) + topicCleanup, err := createKafkaTopic(topicName, 1) + defer topicCleanup() + if err != nil { + t.Fatal(err) + } + topic, err := OpenTopic(localBrokerAddrs, MinimalConfig(), topicName, &TopicOptions{KeyName: keyName}) + if err != nil { + t.Fatal(err) + } + defer func() { + if err := topic.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + + groupID := fmt.Sprintf("%s-sub-%d", sanitize(t.Name()), uniqueID) + subOpts := *subscriptionOptions + subOpts.KeyName = keyName + sub, err := OpenSubscription(localBrokerAddrs, MinimalConfig(), groupID, []string{topicName}, &subOpts) + if err != nil { + t.Fatal(err) + } + defer func() { + if err := sub.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + + m := &pubsub.Message{ + Metadata: map[string]string{ + "foo": "bar", + keyName: keyValue, + }, + Body: []byte("hello world"), + BeforeSend: func(as func(any) bool) error { + // Verify that the Key field was set correctly on the outgoing Kafka + // message. + var pm *sarama.ProducerMessage + if !as(&pm) { + return errors.New("failed to convert to ProducerMessage") + } + gotKeyBytes, err := pm.Key.Encode() + if err != nil { + return fmt.Errorf("failed to Encode Kafka Key: %v", err) + } + if gotKey := string(gotKeyBytes); gotKey != keyValue { + return errors.New("Kafka key wasn't set appropriately") + } + return nil + }, + } + err = topic.Send(ctx, m) + if err != nil { + t.Fatal(err) + } + + // The test will hang here if the message isn't available, so use a shorter timeout. + ctx2, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + got, err := sub.Receive(ctx2) + if err != nil { + t.Fatal(err) + } + got.Ack() + + m.BeforeSend = nil // don't expect this in the received message + m.LoggableID = keyValue + if diff := cmp.Diff(got, m, cmpopts.IgnoreUnexported(pubsub.Message{})); diff != "" { + t.Errorf("got\n%v\nwant\n%v\ndiff\n%v", got, m, diff) + } + + // Verify that Key was set in the received Kafka message via As. + var cm *sarama.ConsumerMessage + if !got.As(&cm) { + t.Fatal("failed to get message As ConsumerMessage") + } + if gotKey := string(cm.Key); gotKey != keyValue { + t.Errorf("got key %q want %q", gotKey, keyValue) + } +} + +// TestMultiplePartionsWithRebalancing tests use of a topic with multiple +// partitions, including the rebalancing that happens when a new consumer +// appears in the group. +func TestMultiplePartionsWithRebalancing(t *testing.T) { + if !setup.HasDockerTestEnvironment() { + t.Skip("Skipping Kafka tests since the Kafka server is not available") + } + const ( + keyName = "kafkakey" + nMessages = 10 + ) + uniqueID := rand.Int() + ctx := context.Background() + + // Create a topic with 10 partitions. Using 10 instead of just 2 because + // that also tests having multiple claims. + topicName := fmt.Sprintf("%s-topic-%d", sanitize(t.Name()), uniqueID) + topicCleanup, err := createKafkaTopic(topicName, 10) + defer topicCleanup() + if err != nil { + t.Fatal(err) + } + topic, err := OpenTopic(localBrokerAddrs, MinimalConfig(), topicName, &TopicOptions{KeyName: keyName}) + if err != nil { + t.Fatal(err) + } + defer func() { + if err := topic.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + + // Open a subscription. + groupID := fmt.Sprintf("%s-sub-%d", sanitize(t.Name()), uniqueID) + subOpts := *subscriptionOptions + subOpts.KeyName = keyName + sub, err := OpenSubscription(localBrokerAddrs, MinimalConfig(), groupID, []string{topicName}, &subOpts) + if err != nil { + t.Fatal(err) + } + defer func() { + if err := sub.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + + // Send some messages. + send := func() { + for i := 0; i < nMessages; i++ { + m := &pubsub.Message{ + Metadata: map[string]string{ + keyName: fmt.Sprintf("key%d", i), + }, + Body: []byte("hello world"), + } + if err := topic.Send(ctx, m); err != nil { + t.Fatal(err) + } + } + } + send() + + // Receive the messages via the subscription. + got := make(chan int) + done := make(chan error) + read := func(ctx context.Context, subNum int, sub *pubsub.Subscription) { + for { + m, err := sub.Receive(ctx) + if err != nil { + if err == context.Canceled { + // Expected after all messages are received, no error. + done <- nil + } else { + done <- err + } + return + } + m.Ack() + got <- subNum + } + } + // The test will hang here if the messages aren't available, so use a shorter + // timeout. + ctx2, cancel := context.WithTimeout(ctx, 30*time.Second) + go read(ctx2, 0, sub) + for i := 0; i < nMessages; i++ { + select { + case <-got: + case err := <-done: + // Premature error. + if err != nil { + t.Fatal(err) + } + } + } + cancel() + if err := <-done; err != nil { + t.Fatal(err) + } + + // Add another subscription to the same group. Kafka will rebalance the + // consumer group, causing the Cleanup/Setup/ConsumeClaim loop. Each of the + // two subscriptions should get claims for 50% of the partitions. + sub2, err := OpenSubscription(localBrokerAddrs, MinimalConfig(), groupID, []string{topicName}, &subOpts) + if err != nil { + t.Fatal(err) + } + defer func() { + if err := sub2.Shutdown(ctx); err != nil { + t.Error(err) + } + }() + + // Send and receive some messages. + // Now both subscriptions should get some messages. + send() + + // The test will hang here if the message isn't available, so use a shorter timeout. + ctx3, cancel := context.WithTimeout(ctx, 30*time.Second) + go read(ctx3, 0, sub) + go read(ctx3, 1, sub2) + counts := []int{0, 0} + for i := 0; i < nMessages; i++ { + select { + case sub := <-got: + counts[sub]++ + case err := <-done: + // Premature error. + if err != nil { + t.Fatal(err) + } + } + } + cancel() + for i := 0; i < 2; i++ { + if err := <-done; err != nil { + t.Fatal(err) + } + } + if counts[0] == 0 || counts[1] == 0 { + t.Errorf("one of the partitioned subscriptions didn't get any messages: %v", counts) + } +} + +func sanitize(testName string) string { + return strings.Replace(testName, "/", "_", -1) +} + +func BenchmarkKafka(b *testing.B) { + ctx := context.Background() + uniqueID := rand.Int() + + // Create the topic. + topicName := fmt.Sprintf("%s-topic-%d", b.Name(), uniqueID) + cleanup, err := createKafkaTopic(topicName, 1) + defer cleanup() + if err != nil { + b.Fatal(err) + } + + topic, err := OpenTopic(localBrokerAddrs, MinimalConfig(), topicName, nil) + if err != nil { + b.Fatal(err) + } + defer topic.Shutdown(ctx) + + groupID := fmt.Sprintf("%s-subscription-%d", b.Name(), uniqueID) + sub, err := OpenSubscription(localBrokerAddrs, MinimalConfig(), groupID, []string{topicName}, subscriptionOptions) + if err != nil { + b.Fatal(err) + } + defer sub.Shutdown(ctx) + + drivertest.RunBenchmarks(b, topic, sub) +} + +func fakeConnectionStringInEnv() func() { + oldEnvVal := os.Getenv("KAFKA_BROKERS") + os.Setenv("KAFKA_BROKERS", "localhost:10000") + return func() { + os.Setenv("KAFKA_BROKERS", oldEnvVal) + } +} + +func TestOpenTopicFromURL(t *testing.T) { + cleanup := fakeConnectionStringInEnv() + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"kafka://mytopic", false}, + // OK, specifying key_name. + {"kafka://mytopic?key_name=x-partition-key", false}, + // Invalid key_name value. + {"kafka://mytopic?key_name=", true}, + // Invalid parameter. + {"kafka://mytopic?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + topic, err := pubsub.OpenTopic(ctx, test.URL) + if err != nil && errors.Is(err, sarama.ErrOutOfBrokers) { + // Since we don't have a real kafka broker to talk to, we will always get an error when + // opening a topic. This test is checking specifically for query parameter usage, so + // we treat the "no brokers" error message as a nil error. + err = nil + } + + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if topic != nil { + topic.Shutdown(ctx) + } + } +} + +func TestOpenSubscriptionFromURL(t *testing.T) { + cleanup := fakeConnectionStringInEnv() + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"kafka://mygroup?topic=mytopic", false}, + // OK, specifying initial offset. + {"kafka://mygroup?topic=mytopic&offset=oldest", false}, + {"kafka://mygroup?topic=mytopic&offset=newest", false}, + // Invalid offset specified. + {"kafka://mygroup?topic=mytopic&offset=value", true}, + // Invalid parameter. + {"kafka://mygroup?topic=mytopic¶m=value", true}, + } + + ctx := context.Background() + + for _, test := range tests { + sub, err := pubsub.OpenSubscription(ctx, test.URL) + if err != nil && errors.Is(err, sarama.ErrOutOfBrokers) { + // Since we don't have a real kafka broker to talk to, we will always get an error when + // opening a subscription. This test is checking specifically for query parameter usage, so + // we treat the "no brokers" error message as a nil error. + err = nil + } + + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if sub != nil { + sub.Shutdown(ctx) + } + } +} diff --git a/go-cloud/pubsub/kafkapubsub/localkafka.sh b/go-cloud/pubsub/kafkapubsub/localkafka.sh new file mode 100755 index 000000000..096ae8506 --- /dev/null +++ b/go-cloud/pubsub/kafkapubsub/localkafka.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Starts a local Kafka instance (plus supporting Zookeeper) via Docker. + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +set -euo pipefail + +# Clean up and run Zookeeper. +echo "Starting Zookeeper (for Kafka)..." +docker rm -f zookeeper &> /dev/null || : +docker run -d --net=host --name=zookeeper -e ZOOKEEPER_CLIENT_PORT=2181 confluentinc/cp-zookeeper:6.0.1 &> /dev/null +echo "...done. Run \"docker rm -f zookeeper\" to clean up the container." +echo + +# Clean up and run Kafka. +echo "Starting Kafka..." +docker rm -f kafka &> /dev/null || : +docker run -d --net=host -p 9092:9092 --name=kafka -e KAFKA_ZOOKEEPER_CONNECT=localhost:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 -e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 -e KAFKA_AUTO_CREATE_TOPICS_ENABLE=false -e KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS=100 confluentinc/cp-kafka:6.0.1 &> /dev/null +echo "...done. Run \"docker rm -f kafka\" to clean up the container." +echo diff --git a/go-cloud/pubsub/mempubsub/conformance_test.go b/go-cloud/pubsub/mempubsub/conformance_test.go new file mode 100644 index 000000000..c2ece617b --- /dev/null +++ b/go-cloud/pubsub/mempubsub/conformance_test.go @@ -0,0 +1,72 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 mempubsub + +import ( + "context" + "testing" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/drivertest" +) + +type harness struct{} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return &harness{}, nil +} + +func (h *harness) CreateTopic(ctx context.Context, testName string) (dt driver.Topic, cleanup func(), err error) { + cleanup = func() {} + return &topic{}, cleanup, nil +} + +func (h *harness) MakeNonexistentTopic(ctx context.Context) (driver.Topic, error) { + // A nil *topic behaves like a nonexistent topic. + return (*topic)(nil), nil +} + +func (h *harness) CreateSubscription(ctx context.Context, dt driver.Topic, testName string) (ds driver.Subscription, cleanup func(), err error) { + ds = newSubscription(dt.(*topic), time.Second) + cleanup = func() {} + return ds, cleanup, nil +} + +func (h *harness) MakeNonexistentSubscription(ctx context.Context) (driver.Subscription, func(), error) { + return newSubscription(nil, time.Second), func() {}, nil +} + +func (h *harness) Close() {} + +func (h *harness) MaxBatchSizes() (int, int) { return 0, 0 } + +func (*harness) SupportsMultipleSubscriptions() bool { return true } + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, nil) +} + +func BenchmarkMemPubSub(b *testing.B) { + ctx := context.Background() + topic := NewTopic() + defer topic.Shutdown(ctx) + sub := NewSubscription(topic, time.Second) + defer sub.Shutdown(ctx) + + drivertest.RunBenchmarks(b, topic, sub) +} diff --git a/go-cloud/pubsub/mempubsub/example_test.go b/go-cloud/pubsub/mempubsub/example_test.go new file mode 100644 index 000000000..ea1a05dd5 --- /dev/null +++ b/go-cloud/pubsub/mempubsub/example_test.go @@ -0,0 +1,81 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 mempubsub_test + +import ( + "context" + "log" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/mempubsub" +) + +func ExampleNewSubscription() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Construct a *pubsub.Topic. + topic := mempubsub.NewTopic() + defer topic.Shutdown(ctx) + + // Construct a *pubsub.Subscription for the topic. + subscription := mempubsub.NewSubscription(topic, 1*time.Minute /* ack deadline */) + defer subscription.Shutdown(ctx) +} + +func ExampleNewTopic() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + topic := mempubsub.NewTopic() + defer topic.Shutdown(ctx) +} + +func Example_openSubscriptionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/mempubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Create a topic. + topic, err := pubsub.OpenTopic(ctx, "mem://topicA") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) + + // Create a subscription connected to that topic. + subscription, err := pubsub.OpenSubscription(ctx, "mem://topicA") + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} + +func Example_openTopicFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/mempubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + topic, err := pubsub.OpenTopic(ctx, "mem://topicA") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} diff --git a/go-cloud/pubsub/mempubsub/mem.go b/go-cloud/pubsub/mempubsub/mem.go new file mode 100644 index 000000000..dfd0432b0 --- /dev/null +++ b/go-cloud/pubsub/mempubsub/mem.go @@ -0,0 +1,409 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 mempubsub provides an in-memory pubsub implementation. +// Use NewTopic to construct a *pubsub.Topic, and/or NewSubscription +// to construct a *pubsub.Subscription. +// +// mempubsub should not be used for production: it is intended for local +// development and testing. +// +// # URLs +// +// For pubsub.OpenTopic and pubsub.OpenSubscription, mempubsub registers +// for the scheme "mem". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # Message Delivery Semantics +// +// mempubsub supports at-least-once semantics; applications must +// call Message.Ack after processing a message, or it will be redelivered. +// See https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery +// for more background. +// +// # As +// +// mempubsub does not support any types for As. +package mempubsub // import "gocloud.dev/pubsub/mempubsub" + +import ( + "context" + "errors" + "fmt" + "log" + "net/url" + "path" + "sync" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/batcher" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" +) + +func init() { + o := new(URLOpener) + pubsub.DefaultURLMux().RegisterTopic(Scheme, o) + pubsub.DefaultURLMux().RegisterSubscription(Scheme, o) +} + +// Scheme is the URL scheme mempubsub registers its URLOpeners under on pubsub.DefaultMux. +const Scheme = "mem" + +// URLOpener opens mempubsub URLs like "mem://topic". +// +// The URL's host+path is used as the topic to create or subscribe to. +// +// Query parameters: +// - ackdeadline: The ack deadline for OpenSubscription, in time.ParseDuration formats. +// Defaults to 1m. +type URLOpener struct { + mu sync.Mutex + topics map[string]*pubsub.Topic +} + +// OpenTopicURL opens a pubsub.Topic based on u. +func (o *URLOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + for param := range u.Query() { + return nil, fmt.Errorf("open topic %v: invalid query parameter %q", u, param) + } + topicName := path.Join(u.Host, u.Path) + o.mu.Lock() + defer o.mu.Unlock() + if o.topics == nil { + o.topics = map[string]*pubsub.Topic{} + } + t := o.topics[topicName] + if t == nil { + t = NewTopic() + o.topics[topicName] = t + } + return t, nil +} + +// OpenSubscriptionURL opens a pubsub.Subscription based on u. +func (o *URLOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + q := u.Query() + + ackDeadline := 1 * time.Minute + if s := q.Get("ackdeadline"); s != "" { + var err error + ackDeadline, err = time.ParseDuration(s) + if err != nil { + return nil, fmt.Errorf("open subscription %v: invalid ackdeadline %q: %v", u, s, err) + } + q.Del("ackdeadline") + } + for param := range q { + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q", u, param) + } + topicName := path.Join(u.Host, u.Path) + o.mu.Lock() + defer o.mu.Unlock() + if o.topics == nil { + o.topics = map[string]*pubsub.Topic{} + } + t := o.topics[topicName] + if t == nil { + return nil, fmt.Errorf("open subscription %v: no topic %q has been created", u, topicName) + } + return NewSubscription(t, ackDeadline), nil +} + +var errNotExist = errors.New("mempubsub: topic does not exist") + +type topic struct { + mu sync.Mutex + subs []*subscription + nextAckID int +} + +// TopicOptions contains configuration options for topics. +type TopicOptions struct { + // BatcherOptions adds constraints to the default batching done for sends. + BatcherOptions batcher.Options +} + +// NewTopic creates a new in-memory topic. +func NewTopic() *pubsub.Topic { + return NewTopicWithOptions(nil) +} + +// NewTopicWithOptions is similar to NewTopic, but supports TopicOptions. +func NewTopicWithOptions(opts *TopicOptions) *pubsub.Topic { + if opts == nil { + opts = &TopicOptions{} + } + return pubsub.NewTopic(&topic{}, &opts.BatcherOptions) +} + +// SendBatch implements driver.Topic.SendBatch. +// It is error if the topic is closed or has no subscriptions. +func (t *topic) SendBatch(ctx context.Context, ms []*driver.Message) error { + if err := ctx.Err(); err != nil { + return err + } + if t == nil { + return errNotExist + } + t.mu.Lock() + defer t.mu.Unlock() + + // Log a warning if there are no subscribers. + if len(t.subs) == 0 { + log.Print("warning: message sent to topic with no subscribers") + } + + // Associate ack IDs with messages here. It would be a bit better if each subscription's + // messages had their own ack IDs, so we could catch one subscription using ack IDs from another, + // but that would require copying all the messages. + for i, m := range ms { + m.AckID = t.nextAckID + i + m.LoggableID = fmt.Sprintf("msg #%d", m.AckID) + m.AsFunc = func(any) bool { return false } + + if m.BeforeSend != nil { + if err := m.BeforeSend(func(any) bool { return false }); err != nil { + return err + } + } + if m.AfterSend != nil { + if err := m.AfterSend(func(any) bool { return false }); err != nil { + return err + } + } + } + t.nextAckID += len(ms) + for _, s := range t.subs { + s.add(ms) + } + return nil +} + +// IsRetryable implements driver.Topic.IsRetryable. +func (*topic) IsRetryable(error) bool { return false } + +// As implements driver.Topic.As. +// It supports *topic so that NewSubscription can recover a *topic +// from the portable type (see below). External users won't be able +// to use As because topic isn't exported. +func (t *topic) As(i any) bool { + x, ok := i.(**topic) + if !ok { + return false + } + *x = t + return true +} + +// ErrorAs implements driver.Topic.ErrorAs +func (*topic) ErrorAs(error, any) bool { + return false +} + +// ErrorCode implements driver.Topic.ErrorCode +func (*topic) ErrorCode(err error) gcerrors.ErrorCode { + if err == errNotExist { + return gcerrors.NotFound + } + return gcerrors.Unknown +} + +// Close implements driver.Topic.Close. +func (*topic) Close() error { return nil } + +// SubscriptionOptions will contain configuration for subscriptions. +type SubscriptionOptions struct { + // ReceiveBatcherOptions adds constraints to the default batching done for receives. + ReceiveBatcherOptions batcher.Options + + // AckBatcherOptions adds constraints to the default batching done for acks. + AckBatcherOptions batcher.Options +} + +type subscription struct { + mu sync.Mutex + topic *topic + ackDeadline time.Duration + msgs map[driver.AckID]*message // all unacknowledged messages +} + +// NewSubscription creates a new subscription for the given topic. +// It panics if the given topic did not come from mempubsub. +// If a message is not acked within in the given ack deadline from when +// it is received, then it will be redelivered. +func NewSubscription(pstopic *pubsub.Topic, ackDeadline time.Duration) *pubsub.Subscription { + return NewSubscriptionWithOptions(pstopic, ackDeadline, nil) +} + +// NewSubscriptionWithOptions is similar to NewSubscription, but supports SubscriptionOptions. +func NewSubscriptionWithOptions(pstopic *pubsub.Topic, ackDeadline time.Duration, opts *SubscriptionOptions) *pubsub.Subscription { + if opts == nil { + opts = &SubscriptionOptions{} + } + var t *topic + if !pstopic.As(&t) { + panic("mempubsub: NewSubscription passed a Topic not from mempubsub") + } + return pubsub.NewSubscription(newSubscription(t, ackDeadline), &opts.ReceiveBatcherOptions, &opts.AckBatcherOptions) +} + +func newSubscription(topic *topic, ackDeadline time.Duration) *subscription { + s := &subscription{ + topic: topic, + ackDeadline: ackDeadline, + msgs: map[driver.AckID]*message{}, + } + if topic != nil { + topic.mu.Lock() + defer topic.mu.Unlock() + topic.subs = append(topic.subs, s) + } + return s +} + +type message struct { + msg *driver.Message + expiration time.Time +} + +func (s *subscription) add(ms []*driver.Message) { + s.mu.Lock() + defer s.mu.Unlock() + for _, m := range ms { + // The new message will expire at the zero time, which means it will be + // immediately eligible for delivery. + s.msgs[m.AckID] = &message{msg: m} + } +} + +// Collect some messages available for delivery. Since we're iterating over a map, +// the order of the messages won't match the publish order, which mimics the actual +// behavior of most pub/sub services. +func (s *subscription) receiveNoWait(now time.Time, max int) []*driver.Message { + var msgs []*driver.Message + s.mu.Lock() + defer s.mu.Unlock() + for _, m := range s.msgs { + if now.After(m.expiration) { + msgs = append(msgs, m.msg) + m.expiration = now.Add(s.ackDeadline) + if len(msgs) == max { + return msgs + } + } + } + return msgs +} + +// How long ReceiveBatch should wait if no messages are available, to avoid +// spinning. +const pollDuration = 250 * time.Millisecond + +// ReceiveBatch implements driver.ReceiveBatch. +func (s *subscription) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + // Check for closed or cancelled before doing any work. + if err := s.wait(ctx, 0); err != nil { + return nil, err + } + msgs := s.receiveNoWait(time.Now(), maxMessages) + if len(msgs) == 0 { + // When we return no messages and no error, the portable type will call + // ReceiveBatch again immediately. Sleep for a bit to avoid spinning. + time.Sleep(pollDuration) + } + return msgs, nil +} + +func (s *subscription) wait(ctx context.Context, dur time.Duration) error { + if s.topic == nil { + return errNotExist + } + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(dur): + return nil + } +} + +// SendAcks implements driver.SendAcks. +func (s *subscription) SendAcks(ctx context.Context, ackIDs []driver.AckID) error { + if s.topic == nil { + return errNotExist + } + // Check for context done before doing any work. + if err := ctx.Err(); err != nil { + return err + } + // Acknowledge messages by removing them from the map. + // Since there is a single map, this correctly handles the case where a message + // is redelivered, but the first receiver acknowledges it. + s.mu.Lock() + defer s.mu.Unlock() + for _, id := range ackIDs { + // It is OK if the message is not in the map; that just means it has been + // previously acked. + delete(s.msgs, id) + } + return nil +} + +// CanNack implements driver.CanNack. +func (s *subscription) CanNack() bool { return true } + +// SendNacks implements driver.SendNacks. +func (s *subscription) SendNacks(ctx context.Context, ackIDs []driver.AckID) error { + if s.topic == nil { + return errNotExist + } + // Check for context done before doing any work. + if err := ctx.Err(); err != nil { + return err + } + // Nack messages by setting their expiration to the zero time. + s.mu.Lock() + defer s.mu.Unlock() + for _, id := range ackIDs { + if m := s.msgs[id]; m != nil { + m.expiration = time.Time{} + } + } + return nil +} + +// IsRetryable implements driver.Subscription.IsRetryable. +func (*subscription) IsRetryable(error) bool { return false } + +// As implements driver.Subscription.As. +func (s *subscription) As(i any) bool { return false } + +// ErrorAs implements driver.Subscription.ErrorAs +func (*subscription) ErrorAs(error, any) bool { + return false +} + +// ErrorCode implements driver.Subscription.ErrorCode +func (*subscription) ErrorCode(err error) gcerrors.ErrorCode { + if err == errNotExist { + return gcerrors.NotFound + } + return gcerrors.Unknown +} + +// Close implements driver.Subscription.Close. +func (*subscription) Close() error { return nil } diff --git a/go-cloud/pubsub/mempubsub/mem_test.go b/go-cloud/pubsub/mempubsub/mem_test.go new file mode 100644 index 000000000..0a2d90525 --- /dev/null +++ b/go-cloud/pubsub/mempubsub/mem_test.go @@ -0,0 +1,172 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 mempubsub + +import ( + "context" + "testing" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" +) + +func TestReceive(t *testing.T) { + ctx := context.Background() + topic := &topic{} + sub := newSubscription(topic, 3*time.Second) + if err := topic.SendBatch(ctx, []*driver.Message{ + {Body: []byte("a")}, + {Body: []byte("b")}, + {Body: []byte("c")}, + }); err != nil { + t.Fatal(err) + } + now := time.Now() + // We should get only two of the published messages. + msgs := sub.receiveNoWait(now, 2) + if got, want := len(msgs), 2; got != want { + t.Fatalf("got %d, want %d", got, want) + } + // We should get the remaining message. + msgs = sub.receiveNoWait(now, 2) + if got, want := len(msgs), 1; got != want { + t.Fatalf("got %d, want %d", got, want) + } + // Since all the messages are outstanding, we shouldn't get any. + msgs2 := sub.receiveNoWait(now, 10) + if got, want := len(msgs2), 0; got != want { + t.Fatalf("got %d, want %d", got, want) + } + // Advance time past expiration, and we should get all the messages again, + // since we didn't ack any. + now = now.Add(time.Hour) + msgs = sub.receiveNoWait(now, 10) + if got, want := len(msgs), 3; got != want { + t.Fatalf("got %d, want %d", got, want) + } + // Again, since all the messages are outstanding, we shouldn't get any. + msgs2 = sub.receiveNoWait(now, 10) + if got, want := len(msgs2), 0; got != want { + t.Fatalf("got %d, want %d", got, want) + } + // Now ack the messages. + var ackIDs []driver.AckID + for _, m := range msgs { + ackIDs = append(ackIDs, m.AckID) + } + sub.SendAcks(ctx, ackIDs) + // They will never be delivered again, even if we wait past the ack deadline. + now = now.Add(time.Hour) + msgs = sub.receiveNoWait(now, 10) + if got, want := len(msgs), 0; got != want { + t.Fatalf("got %d, want %d", got, want) + } +} + +func TestOpenTopicFromURL(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"mem://mytopic", false}, + // Invalid parameter. + {"mem://mytopic?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + topic, err := pubsub.OpenTopic(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if topic != nil { + topic.Shutdown(ctx) + } + } +} + +func TestOpenSubscriptionFromURL(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"mem://mytopic", false}, + // OK with ackdeadline + {"mem://mytopic?ackdeadline=30s", false}, + // Invalid ackdeadline + {"mem://mytopic?ackdeadline=notaduration", true}, + // Nonexistent topic. + {"mem://nonexistenttopic", true}, + // Invalid parameter. + {"mem://myproject/mysub?param=value", true}, + } + + ctx := context.Background() + pubsub.OpenTopic(ctx, "mem://mytopic") + for _, test := range tests { + sub, err := pubsub.OpenSubscription(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if sub != nil { + sub.Shutdown(ctx) + } + } +} + +func TestSendNoSubs(t *testing.T) { + // It's OK to send a message to a topic with no subscribers. + // (But it will log a warning: that is untested.) + ctx := context.Background() + topic := NewTopic() + defer topic.Shutdown(ctx) + if err := topic.Send(ctx, &pubsub.Message{Body: []byte("OK")}); err != nil { + t.Fatal(err) + } +} + +/* +// This test runs forever, so it's commented out. It's useful for playing +// around with batching. Add a Printf in ../pubsub.go that prints the batch size. +func TestReceiveBatching(t *testing.T) { + ctx := context.Background() + topic := NewTopic() + defer topic.Shutdown(ctx) + sub := NewSubscriptionWithOptions(topic, 10*time.Second, &SubscriptionOptions{ReceiveBatcherOptions: batcher.Options{MaxBatchSize: 10, MaxHandlers: 100}}) + defer sub.Shutdown(ctx) + + // Receive messages as quickly as possible. + go func() { + for { + msg, _ := sub.Receive(ctx) + if msg != nil { + msg.Ack() + } + } + }() + + // Send slightly slower than the 250ms Sleep. + for { + if err := topic.Send(ctx, &pubsub.Message{Body: []byte("a")}); err != nil { + t.Fatal(err) + } + time.Sleep(333 * time.Millisecond) + } + // With the above parameters, ideally the batch size would settle down to around 2. +} +*/ diff --git a/go-cloud/pubsub/natspubsub/example_test.go b/go-cloud/pubsub/natspubsub/example_test.go new file mode 100644 index 000000000..4d3fd96fb --- /dev/null +++ b/go-cloud/pubsub/natspubsub/example_test.go @@ -0,0 +1,210 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 natspubsub_test + +import ( + "context" + "log" + + "github.com/nats-io/nats.go" + + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/natspubsub" +) + +func ExampleOpenTopic() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + natsConn, err := nats.Connect("nats://nats.example.com") + if err != nil { + log.Fatal(err) + } + defer natsConn.Close() + + topic, err := natspubsub.OpenTopic(natsConn, "example.mysubject", nil) + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func ExampleOpenSubscription() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + natsConn, err := nats.Connect("nats://nats.example.com") + if err != nil { + log.Fatal(err) + } + defer natsConn.Close() + + subscription, err := natspubsub.OpenSubscription( + natsConn, + "example.mysubject", + nil) + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} + +func ExampleOpenSubscription_queue() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + natsConn, err := nats.Connect("nats://nats.example.com") + if err != nil { + log.Fatal(err) + } + defer natsConn.Close() + + subscription, err := natspubsub.OpenSubscription( + natsConn, + "example.mysubject", + &natspubsub.SubscriptionOptions{Queue: "queue1"}) + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} + +func Example_openTopicFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/natspubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenTopic creates a *pubsub.Topic from a URL. + // This URL will Dial the NATS server at the URL in the environment variable + // NATS_SERVER_URL and send messages with subject "example.mysubject". + topic, err := pubsub.OpenTopic(ctx, "nats://example.mysubject") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func Example_openSubscriptionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/natspubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenSubscription creates a *pubsub.Subscription from a URL. + // This URL will Dial the NATS server at the URL in the environment variable + // NATS_SERVER_URL and receive messages with subject "example.mysubject". + subscription, err := pubsub.OpenSubscription(ctx, "nats://example.mysubject") + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} + +func Example_openQueueSubscriptionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/natspubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenSubscription creates a *pubsub.Subscription from a URL. + // This URL will Dial the NATS server at the URL in the environment variable + // NATS_SERVER_URL and receive messages with subject "example.mysubject" + // This URL will be parsed and the queue attribute will be used as the Queue parameter when creating the NATS Subscription. + subscription, err := pubsub.OpenSubscription(ctx, "nats://example.mysubject?queue=myqueue") + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} + +func ExampleOpenSubscriptionV2() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/natspubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + natsConn, err := nats.Connect("nats://nats.example.com") + if err != nil { + log.Fatal(err) + } + defer natsConn.Close() + + subscription, err := natspubsub.OpenSubscriptionV2( + natsConn, + "example.mysubject", + nil) + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} + +func ExampleOpenTopicV2() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/natspubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + natsConn, err := nats.Connect("nats://nats.example.com") + if err != nil { + log.Fatal(err) + } + defer natsConn.Close() + + topic, err := natspubsub.OpenTopicV2(natsConn, "example.mysubject", nil) + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func Example_openTopicV2FromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/natspubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenTopic creates a *pubsub.Topic from a URL. + // This URL will Dial the NATS server at the URL in the environment variable + // NATS_SERVER_URL and send messages with subject "example.mysubject". + // This URL will be parsed and the natsv2 attribute will be used to + // use NATS v2.2.0+ native message headers as the message metadata. + topic, err := pubsub.OpenTopic(ctx, "nats://example.mysubject?natsv2") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func Example_openSubscriptionV2FromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/natspubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenSubscription creates a *pubsub.Subscription from a URL. + // This URL will Dial the NATS server at the URL in the environment variable + // NATS_SERVER_URL and receive messages with subject "example.mysubject". + // This URL will be parsed and the natsv2 attribute will be used to + // use NATS v2.2.0+ native message headers as the message metadata. + subscription, err := pubsub.OpenSubscription(ctx, "nats://example.mysubject?natsv2") + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} diff --git a/go-cloud/pubsub/natspubsub/go.mod b/go-cloud/pubsub/natspubsub/go.mod new file mode 100644 index 000000000..e84142901 --- /dev/null +++ b/go-cloud/pubsub/natspubsub/go.mod @@ -0,0 +1,53 @@ +// Copyright 2018-2019 The Go Cloud Development Kit 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 +// +// https://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. + +module gocloud.dev/pubsub/natspubsub + +go 1.24 + +require ( + github.com/google/go-cmp v0.7.0 + github.com/nats-io/nats-server/v2 v2.9.23 + github.com/nats-io/nats.go v1.43.0 + gocloud.dev v0.43.0 +) + +require ( + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/minio/highwayhash v1.0.2 // indirect + github.com/nats-io/jwt/v2 v2.5.0 // indirect + github.com/nats-io/nkeys v0.4.11 // indirect + github.com/nats-io/nuid v1.0.1 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/sdk v1.37.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect + go.opentelemetry.io/otel/trace v1.37.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/time v0.12.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + google.golang.org/api v0.242.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 // indirect + google.golang.org/grpc v1.73.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect +) diff --git a/go-cloud/pubsub/natspubsub/go.sum b/go-cloud/pubsub/natspubsub/go.sum new file mode 100644 index 000000000..77cfcce8a --- /dev/null +++ b/go-cloud/pubsub/natspubsub/go.sum @@ -0,0 +1,97 @@ +cloud.google.com/go v0.121.4 h1:cVvUiY0sX0xwyxPwdSU2KsF9knOVmtRyAMt8xou0iTs= +cloud.google.com/go/auth v0.16.3 h1:kabzoQ9/bobUmnseYnBO6qQG7q4a/CffFRlJSxv2wCc= +cloud.google.com/go/auth v0.16.3/go.mod h1:NucRGjaXfzP1ltpcQ7On/VTZ0H4kWB5Jy+Y9Dnm76fA= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= +cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= +cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/pubsub v1.49.0 h1:5054IkbslnrMCgA2MAEPcsN3Ky+AyMpEZcii/DoySPo= +cloud.google.com/go/pubsub v1.49.0/go.mod h1:K1FswTWP+C1tI/nfi3HQecoVeFvL4HUOB1tdaNXKhUY= +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/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/nats-io/jwt/v2 v2.5.0 h1:WQQ40AAlqqfx+f6ku+i0pOVm+ASirD4fUh+oQsiE9Ak= +github.com/nats-io/jwt/v2 v2.5.0/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI= +github.com/nats-io/nats-server/v2 v2.9.23 h1:6Wj6H6QpP9FMlpCyWUaNu2yeZ/qGj+mdRkZ1wbikExU= +github.com/nats-io/nats-server/v2 v2.9.23/go.mod h1:wEjrEy9vnqIGE4Pqz4/c75v9Pmaq7My2IgFmnykc4C0= +github.com/nats-io/nats.go v1.43.0 h1:uRFZ2FEoRvP64+UUhaTokyS18XBCR/xM2vQZKO4i8ug= +github.com/nats-io/nats.go v1.43.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= +github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0= +github.com/nats-io/nkeys v0.4.11/go.mod h1:szDimtgmfOi9n25JpfIdGw12tZFYXqhGxjhVxsatHVE= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +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/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 h1:rbRJ8BBoVMsQShESYZ0FkvcITu8X8QNwJogcLUmDNNw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0/go.mod h1:ru6KHrNtNHxM4nD/vd6QrLVWgKhxPYgblq4VAtNawTQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/api v0.242.0 h1:7Lnb1nfnpvbkCiZek6IXKdJ0MFuAZNAJKQfA1ws62xg= +google.golang.org/api v0.242.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 h1:Nt6z9UHqSlIdIGJdz6KhTIs2VRx/iOsA5iE8bmQNcxs= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79/go.mod h1:kTmlBHMPqR5uCZPBvwa2B18mvubkjyY3CRLI0c6fj0s= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79 h1:iOye66xuaAK0WnkPuhQPUFy8eJcmwUXqGGP3om6IxX8= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79/go.mod h1:HKJDgKsFUnv5VAGeQjz8kxcgDP0HoE0iZNp0OdZNlhE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 h1:1ZwqphdOdWYXsUHgMpU/101nCtf/kSp9hOrcvFsnl10= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go-cloud/pubsub/natspubsub/nats.go b/go-cloud/pubsub/natspubsub/nats.go new file mode 100644 index 000000000..c821ff3f4 --- /dev/null +++ b/go-cloud/pubsub/natspubsub/nats.go @@ -0,0 +1,704 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 natspubsub provides a pubsub implementation for NATS.io. Use OpenTopic to +// construct a *pubsub.Topic, and/or OpenSubscription to construct a +// *pubsub.Subscription. This package uses gob to encode and decode driver.Message to +// []byte. +// +// # URLs +// +// For pubsub.OpenTopic and pubsub.OpenSubscription, natspubsub registers +// for the scheme "nats". +// The default URL opener will connect to a default server based on the +// environment variable "NATS_SERVER_URL". +// +// For servers that support it (NATS Server 2.2.0 or later), messages can +// be encoded using native NATS message headers, and native message content. +// This provides full support for non-Go clients. Versions prior to 2.2.0 +// uses gob.Encoder to encode the message headers and content, which limits +// the subscribers only to Go clients. +// To use this feature, set the query parameter "natsv2" in the URL. +// If no value is provided, it assumes the value is true. Otherwise, the value +// needs to be parsable as a boolean. For example: +// - nats://mysubject?natsv2 +// - nats://mysubject?natsv2=true +// +// This feature can also be enabled by setting the UseV2 field in the +// URLOpener. +// If the server does not support this feature, any attempt to use it will +// result in an error. +// Using native NATS message headers and content is more efficient than using +// gob.Encoder, and allows non-Go clients to subscribe to the topic and +// receive messages. It is recommended to use this feature if the server +// supports it. +// +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # Message Delivery Semantics +// +// NATS supports at-most-semantics; applications need not call Message.Ack, +// and must not call Message.Nack. +// See https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery +// for more background. +// +// # As +// +// natspubsub exposes the following types for As: +// - Topic: *nats.Conn +// - Subscription: *nats.Subscription +// - Message.BeforeSend: None for v1, *nats.Msg for v2. +// - Message.AfterSend: None. +// - Message: *nats.Msg +package natspubsub // import "gocloud.dev/pubsub/natspubsub" + +import ( + "bytes" + "context" + "encoding/gob" + "errors" + "fmt" + "net/url" + "os" + "path" + "regexp" + "strconv" + "strings" + "sync" + "time" + + "github.com/nats-io/nats.go" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/batcher" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" +) + +var errNotInitialized = errors.New("natspubsub: topic not initialized") + +var recvBatcherOpts = &batcher.Options{ + // NATS has at-most-once semantics, meaning once it delivers a message, the + // message won't be delivered again. + // Therefore, we can't allow the portable type to read-ahead and queue any + // messages; they might end up undelivered if the user never calls Receive + // to get them. Setting both the MaxBatchSize and MaxHandlers to one means + // that we'll only return a message at a time, which should be immediately + // returned to the user. + // + // Note: there is a race condition where the original Receive that + // triggered a call to ReceiveBatch ends up failing (e.g., due to a + // Done context), and ReceiveBatch returns a message that ends up being + // queued for the next Receive. That message is at risk of being dropped. + // This seems OK. + MaxBatchSize: 1, + MaxHandlers: 1, // max concurrency for receives +} + +func init() { + o := new(defaultDialer) + pubsub.DefaultURLMux().RegisterTopic(Scheme, o) + pubsub.DefaultURLMux().RegisterSubscription(Scheme, o) +} + +// defaultDialer dials a default NATS server based on the environment +// variable "NATS_SERVER_URL". +type defaultDialer struct { + init sync.Once + err error + + opener URLOpener + openerV2 URLOpener +} + +func (o *defaultDialer) defaultConn(ctx context.Context) error { + o.init.Do(func() { + serverURL := os.Getenv("NATS_SERVER_URL") + if serverURL == "" { + o.err = errors.New("NATS_SERVER_URL environment variable not set") + return + } + conn, err := nats.Connect(serverURL) + if err != nil { + o.err = fmt.Errorf("failed to dial NATS_SERVER_URL %q: %v", serverURL, err) + return + } + o.opener = URLOpener{Connection: conn} + o.openerV2 = URLOpener{Connection: conn, UseV2: true} + }) + return o.err +} + +type serverVersion struct { + major, minor, patch int +} + +func (o *defaultDialer) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + err := o.defaultConn(ctx) + if err != nil { + return nil, fmt.Errorf("open topic %v: failed to open default connection: %v", u, err) + } + useV2, err := queryUseV2(u.Query()) + if err != nil { + return nil, fmt.Errorf("open topic %v: %v", u, err) + } + if useV2 { + return o.openerV2.OpenTopicURL(ctx, u) + } + return o.opener.OpenTopicURL(ctx, u) +} + +func (o *defaultDialer) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + err := o.defaultConn(ctx) + if err != nil { + return nil, fmt.Errorf("open subscription %v: failed to open default connection: %v", u, err) + } + useV2, err := queryUseV2(u.Query()) + if err != nil { + return nil, fmt.Errorf("open subscription %v: %v", u, err) + } + if useV2 { + return o.openerV2.OpenSubscriptionURL(ctx, u) + } + return o.opener.OpenSubscriptionURL(ctx, u) +} + +var semVerRegexp = regexp.MustCompile(`\Av?([0-9]+)\.?([0-9]+)?\.?([0-9]+)?`) + +func parseServerVersion(version string) (serverVersion, error) { + m := semVerRegexp.FindStringSubmatch(version) + if m == nil { + return serverVersion{}, errors.New("failed to parse server version") + } + var ( + major, minor, patch int + err error + ) + major, err = strconv.Atoi(m[1]) + if err != nil { + return serverVersion{}, fmt.Errorf("failed to parse server version major number %q: %v", m[1], err) + } + minor, err = strconv.Atoi(m[2]) + if err != nil { + return serverVersion{}, fmt.Errorf("failed to parse server version minor number %q: %v", m[2], err) + } + patch, err = strconv.Atoi(m[3]) + if err != nil { + return serverVersion{}, fmt.Errorf("failed to parse server version patch number %q: %v", m[3], err) + } + return serverVersion{major: major, minor: minor, patch: patch}, nil +} + +// Scheme is the URL scheme natspubsub registers its URLOpeners under on pubsub.DefaultMux. +const Scheme = "nats" + +// URLOpener opens NATS URLs like "nats://mysubject?natsv2=true". +// +// The URL host+path is used as the subject. +// +// No query parameters are supported. +type URLOpener struct { + // Connection to use for communication with the server. + Connection *nats.Conn + // TopicOptions specifies the options to pass to OpenTopic. + TopicOptions TopicOptions + // SubscriptionOptions specifies the options to pass to OpenSubscription. + SubscriptionOptions SubscriptionOptions + // UseV2 indicates whether the NATS Server is at least version 2.2.0. + UseV2 bool +} + +const natsV2QueryParameter = "natsv2" + +// OpenTopicURL opens a pubsub.Topic based on u. +func (o *URLOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + for param := range u.Query() { + if strings.ToLower(param) == natsV2QueryParameter { + continue + } + return nil, fmt.Errorf("open topic %v: invalid query parameter %s", u, param) + } + subject := path.Join(u.Host, u.Path) + if o.UseV2 { + return OpenTopicV2(o.Connection, subject, &o.TopicOptions) + } + return OpenTopic(o.Connection, subject, &o.TopicOptions) +} + +// OpenSubscriptionURL opens a pubsub.Subscription based on u. +func (o *URLOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + opts := o.SubscriptionOptions + for param, values := range u.Query() { + switch strings.ToLower(param) { + case natsV2QueryParameter: + continue + case "queue": + if len(values) != 1 { + return nil, fmt.Errorf("open subscription %v: invalid query parameter %s", u, param) + } + opts.Queue = values[0] + default: + return nil, fmt.Errorf("open subscription %v: invalid query parameter %s", u, param) + } + } + subject := path.Join(u.Host, u.Path) + if o.UseV2 { + return OpenSubscriptionV2(o.Connection, subject, &opts) + } + return OpenSubscription(o.Connection, subject, &opts) +} + +// TopicOptions sets options for constructing a *pubsub.Topic backed by NATS. +type TopicOptions struct{} + +// SubscriptionOptions sets options for constructing a *pubsub.Subscription +// backed by NATS. +type SubscriptionOptions struct { + // Queue sets the subscription as a QueueSubcription. + // For more info, see https://docs.nats.io/nats-concepts/queue. + Queue string +} + +type topic struct { + useV2 bool + nc *nats.Conn + subj string +} + +// OpenTopic returns a *pubsub.Topic for use with NATS. +// The subject is the NATS Subject; for more info, see +// https://nats.io/documentation/writing_applications/subjects. +func OpenTopic(nc *nats.Conn, subject string, _ *TopicOptions) (*pubsub.Topic, error) { + dt, err := openTopic(nc, subject, false) + if err != nil { + return nil, err + } + return pubsub.NewTopic(dt, nil), nil +} + +// OpenTopicV2 returns a *pubsub.Topic for use with NATS at least version 2.2.0. +// This changes the encoding of the message as, starting with version 2.2.0, NATS supports message headers. +// In previous versions the message headers were encoded along with the message content using gob.Encoder, +// which limits the subscribers only to Go clients. +// This implementation uses native NATS message headers, and native message content, which provides full support +// for non-Go clients. +func OpenTopicV2(nc *nats.Conn, subject string, _ *TopicOptions) (*pubsub.Topic, error) { + dt, err := openTopic(nc, subject, true) + if err != nil { + return nil, err + } + return pubsub.NewTopic(dt, nil), nil +} + +// openTopic returns the driver for OpenTopic. This function exists so the test +// harness can get the driver interface implementation if it needs to. +func openTopic(nc *nats.Conn, subject string, useV2 bool) (driver.Topic, error) { + if nc == nil { + return nil, errors.New("natspubsub: nats.Conn is required") + } + if useV2 { + sv, err := parseServerVersion(nc.ConnectedServerVersion()) + if err != nil { + return nil, fmt.Errorf("failed to parse NATS server version %q: %v", nc.ConnectedServerVersion(), err) + } + // Check if the server version is at least 2.2.0. + if sv.major < 2 && sv.minor < 2 { + return nil, fmt.Errorf("natspubsub: NATS server version %q is not supported", nc.ConnectedServerVersion()) + } + } + return &topic{nc: nc, subj: subject, useV2: useV2}, nil +} + +// SendBatch implements driver.Topic.SendBatch. +func (t *topic) SendBatch(ctx context.Context, msgs []*driver.Message) error { + if t == nil || t.nc == nil { + return errNotInitialized + } + + for _, m := range msgs { + err := ctx.Err() + if err != nil { + return err + } + + if t.useV2 { + err = t.sendMessageV2(m) + } else { + err = t.sendMessage(m) + } + if err != nil { + return err + } + } + // Per specification this is supposed to only return after + // a message has been sent. Normally NATS is very efficient + // at sending messages in batches on its own and also handles + // disconnected buffering during a reconnect event. We will + // let NATS handle this for now. If needed we could add a + // FlushWithContext() call which ensures the connected server + // has processed all the messages. + return nil +} + +func (t *topic) sendMessage(m *driver.Message) error { + // TODO(jba): benchmark message encoding to see if it's + // worth reusing a buffer. + payload, err := encodeMessage(m) + if err != nil { + return err + } + if m.BeforeSend != nil { + asFunc := func(i any) bool { return false } + if err := m.BeforeSend(asFunc); err != nil { + return err + } + } + if err = t.nc.Publish(t.subj, payload); err != nil { + return err + } + if m.AfterSend != nil { + asFunc := func(i any) bool { return false } + if err := m.AfterSend(asFunc); err != nil { + return err + } + } + return nil +} + +func (t *topic) sendMessageV2(m *driver.Message) error { + msg := encodeMessageV2(m, t.subj) + if m.BeforeSend != nil { + asFunc := func(i any) bool { + if nm, ok := i.(**nats.Msg); ok { + *nm = msg + return true + } + return false + } + if err := m.BeforeSend(asFunc); err != nil { + return err + } + } + + if err := t.nc.PublishMsg(msg); err != nil { + return err + } + + if m.AfterSend != nil { + asFunc := func(i any) bool { return false } + if err := m.AfterSend(asFunc); err != nil { + return err + } + } + return nil +} + +// IsRetryable implements driver.Topic.IsRetryable. +func (*topic) IsRetryable(error) bool { return false } + +// As implements driver.Topic.As. +func (t *topic) As(i any) bool { + c, ok := i.(**nats.Conn) + if !ok { + return false + } + *c = t.nc + return true +} + +// ErrorAs implements driver.Topic.ErrorAs +func (*topic) ErrorAs(error, any) bool { + return false +} + +// ErrorCode implements driver.Topic.ErrorCode +func (*topic) ErrorCode(err error) gcerrors.ErrorCode { + switch err { + case nil: + return gcerrors.OK + case context.Canceled: + return gcerrors.Canceled + case errNotInitialized: + return gcerrors.NotFound + case nats.ErrBadSubject: + return gcerrors.FailedPrecondition + case nats.ErrAuthorization: + return gcerrors.PermissionDenied + case nats.ErrMaxPayload, nats.ErrReconnectBufExceeded: + return gcerrors.ResourceExhausted + } + return gcerrors.Unknown +} + +// Close implements driver.Topic.Close. +func (*topic) Close() error { return nil } + +type subscription struct { + useV2 bool + nc *nats.Conn + nsub *nats.Subscription + nextID int +} + +// OpenSubscription returns a *pubsub.Subscription representing a NATS subscription or NATS queue subscription. +// The subject is the NATS Subject to subscribe to; +// for more info, see https://nats.io/documentation/writing_applications/subjects. +func OpenSubscription(nc *nats.Conn, subject string, opts *SubscriptionOptions) (*pubsub.Subscription, error) { + ds, err := openSubscription(nc, subject, opts, false) + if err != nil { + return nil, err + } + return pubsub.NewSubscription(ds, recvBatcherOpts, nil), nil +} + +// OpenSubscriptionV2 returns a *pubsub.Subscription representing a NATS subscription or NATS queue subscription +// for use with NATS at least version 2.2.0. +// This changes the encoding of the message as, starting with version 2.2.0, NATS supports message headers. +// In previous versions the message headers were encoded along with the message content using gob.Encoder, +// which limits the subscribers only to Go clients. +// This implementation uses native NATS message headers, and native message content, which provides full support +// for non-Go clients. +func OpenSubscriptionV2(nc *nats.Conn, subject string, opts *SubscriptionOptions) (*pubsub.Subscription, error) { + ds, err := openSubscription(nc, subject, opts, true) + if err != nil { + return nil, err + } + return pubsub.NewSubscription(ds, recvBatcherOpts, nil), nil +} + +func openSubscription(nc *nats.Conn, subject string, opts *SubscriptionOptions, useV2 bool) (driver.Subscription, error) { + var sub *nats.Subscription + var err error + if opts != nil && opts.Queue != "" { + sub, err = nc.QueueSubscribeSync(subject, opts.Queue) + } else { + sub, err = nc.SubscribeSync(subject) + } + if err != nil { + return nil, err + } + return &subscription{nc: nc, nsub: sub, nextID: 1, useV2: useV2}, nil +} + +// ReceiveBatch implements driver.ReceiveBatch. +func (s *subscription) ReceiveBatch(ctx context.Context, _ int) ([]*driver.Message, error) { + if s == nil || s.nsub == nil { + return nil, nats.ErrBadSubscription + } + + msg, err := s.nsub.NextMsg(100 * time.Millisecond) + if err != nil { + if err == nats.ErrTimeout { + return nil, nil + } + return nil, err + } + + var dm *driver.Message + if s.useV2 { + dm, err = decodeMessageV2(msg) + } else { + dm, err = decode(msg) + } + if err != nil { + return nil, err + } + dm.LoggableID = fmt.Sprintf("msg #%d", s.nextID) + s.nextID++ + return []*driver.Message{dm}, nil +} + +// Convert NATS msgs to *driver.Message. +func decode(msg *nats.Msg) (*driver.Message, error) { + if msg == nil { + return nil, nats.ErrInvalidMsg + } + var dm driver.Message + if err := decodeMessage(msg.Data, &dm); err != nil { + return nil, err + } + dm.AckID = -1 // Not applicable to NATS + dm.AsFunc = messageAsFunc(msg) + return &dm, nil +} + +func messageAsFunc(msg *nats.Msg) func(any) bool { + return func(i any) bool { + p, ok := i.(**nats.Msg) + if !ok { + return false + } + *p = msg + return true + } +} + +// SendAcks implements driver.Subscription.SendAcks. +func (s *subscription) SendAcks(ctx context.Context, ids []driver.AckID) error { + // Ack is a no-op. + return nil +} + +// CanNack implements driver.CanNack. +func (s *subscription) CanNack() bool { return false } + +// SendNacks implements driver.Subscription.SendNacks. It should never be called +// because we return false for CanNack. +func (s *subscription) SendNacks(ctx context.Context, ids []driver.AckID) error { + panic("unreachable") +} + +// IsRetryable implements driver.Subscription.IsRetryable. +func (s *subscription) IsRetryable(error) bool { return false } + +// As implements driver.Subscription.As. +func (s *subscription) As(i any) bool { + c, ok := i.(**nats.Subscription) + if !ok { + return false + } + *c = s.nsub + return true +} + +// ErrorAs implements driver.Subscription.ErrorAs +func (*subscription) ErrorAs(error, any) bool { + return false +} + +// ErrorCode implements driver.Subscription.ErrorCode +func (*subscription) ErrorCode(err error) gcerrors.ErrorCode { + switch err { + case nil: + return gcerrors.OK + case context.Canceled: + return gcerrors.Canceled + case errNotInitialized, nats.ErrBadSubscription: + return gcerrors.NotFound + case nats.ErrBadSubject, nats.ErrTypeSubscription: + return gcerrors.FailedPrecondition + case nats.ErrAuthorization: + return gcerrors.PermissionDenied + case nats.ErrMaxMessages, nats.ErrSlowConsumer: + return gcerrors.ResourceExhausted + case nats.ErrTimeout: + return gcerrors.DeadlineExceeded + } + return gcerrors.Unknown +} + +// Close implements driver.Subscription.Close. +func (*subscription) Close() error { return nil } + +func encodeMessage(dm *driver.Message) ([]byte, error) { + var buf bytes.Buffer + enc := gob.NewEncoder(&buf) + if len(dm.Metadata) == 0 { + return dm.Body, nil + } + if err := enc.Encode(dm.Metadata); err != nil { + return nil, err + } + if err := enc.Encode(dm.Body); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func decodeMessage(data []byte, dm *driver.Message) error { + buf := bytes.NewBuffer(data) + dec := gob.NewDecoder(buf) + if err := dec.Decode(&dm.Metadata); err != nil { + // This may indicate a normal NATS message, so just treat as the body. + dm.Metadata = nil + dm.Body = data + return nil + } + return dec.Decode(&dm.Body) +} + +func queryUseV2(q url.Values) (bool, error) { + if len(q) == 0 { + return false, nil + } + v, ok := q[natsV2QueryParameter] + if !ok { + return false, nil + } + + if len(v) == 0 { + // If the query parameter was provided without any value i.e. nats://mysubject?natsv2 + // it assumes the value is true. + return true, nil + } + if len(v) > 1 { + return false, fmt.Errorf("invalid query parameter %s - multiple values provided", natsV2QueryParameter) + } + if v[0] == "" { + return true, nil + } + useV2, err := strconv.ParseBool(v[0]) + if err != nil { + return false, fmt.Errorf("invalid query parameter %s - value either needs to be parsable as a boolean or empty", natsV2QueryParameter) + } + return useV2, nil +} + +func encodeMessageV2(dm *driver.Message, sub string) *nats.Msg { + var header nats.Header + if dm.Metadata != nil { + header = nats.Header{} + for k, v := range dm.Metadata { + header[url.QueryEscape(k)] = []string{url.QueryEscape(v)} + } + } + return &nats.Msg{ + Subject: sub, + Data: dm.Body, + Header: header, + } +} + +func decodeMessageV2(msg *nats.Msg) (*driver.Message, error) { + if msg == nil { + return nil, nats.ErrInvalidMsg + } + + dm := driver.Message{ + AsFunc: messageAsFunc(msg), + Body: msg.Data, + } + + if msg.Header != nil { + dm.Metadata = map[string]string{} + for k, v := range msg.Header { + var sv string + if len(v) > 0 { + sv = v[0] + } + kb, err := url.QueryUnescape(k) + if err != nil { + return nil, err + } + vb, err := url.QueryUnescape(sv) + if err != nil { + return nil, err + } + dm.Metadata[kb] = vb + } + } + return &dm, nil +} diff --git a/go-cloud/pubsub/natspubsub/nats_test.go b/go-cloud/pubsub/natspubsub/nats_test.go new file mode 100644 index 000000000..438a455f0 --- /dev/null +++ b/go-cloud/pubsub/natspubsub/nats_test.go @@ -0,0 +1,641 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 natspubsub + +import ( + "bytes" + "context" + "fmt" + "os" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/drivertest" + + "github.com/google/go-cmp/cmp" + "github.com/nats-io/nats-server/v2/server" + gnatsd "github.com/nats-io/nats-server/v2/test" + "github.com/nats-io/nats.go" +) + +const ( + testPort = 11222 + benchPort = 9222 +) + +type harness struct { + s *server.Server + nc *nats.Conn + useV2 bool +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + opts := gnatsd.DefaultTestOptions + opts.Port = testPort + s := gnatsd.RunServer(&opts) + nc, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", testPort)) + if err != nil { + return nil, err + } + return &harness{s: s, nc: nc, useV2: false}, nil +} + +func newHarnessV2(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + opts := gnatsd.DefaultTestOptions + opts.Port = testPort + s := gnatsd.RunServer(&opts) + nc, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", testPort)) + if err != nil { + return nil, err + } + return &harness{s: s, nc: nc, useV2: true}, nil +} + +func (h *harness) CreateTopic(ctx context.Context, testName string) (driver.Topic, func(), error) { + cleanup := func() {} + dt, err := openTopic(h.nc, testName, h.useV2) + if err != nil { + return nil, nil, err + } + return dt, cleanup, nil +} + +func (h *harness) MakeNonexistentTopic(ctx context.Context) (driver.Topic, error) { + // A nil *topic behaves like a nonexistent topic. + return (*topic)(nil), nil +} + +func (h *harness) CreateSubscription(ctx context.Context, dt driver.Topic, testName string) (driver.Subscription, func(), error) { + ds, err := openSubscription(h.nc, testName, nil, h.useV2) + if err != nil { + return nil, nil, err + } + cleanup := func() { + var sub *nats.Subscription + if ds.As(&sub) { + sub.Unsubscribe() + } + } + return ds, cleanup, nil +} + +func (h *harness) CreateQueueSubscription(ctx context.Context, dt driver.Topic, testName string) (driver.Subscription, func(), error) { + ds, err := openSubscription(h.nc, testName, &SubscriptionOptions{Queue: testName}, h.useV2) + if err != nil { + return nil, nil, err + } + cleanup := func() { + var sub *nats.Subscription + if ds.As(&sub) { + sub.Unsubscribe() + } + } + return ds, cleanup, nil +} + +func (h *harness) MakeNonexistentSubscription(ctx context.Context) (driver.Subscription, func(), error) { + return (*subscription)(nil), func() {}, nil +} + +func (h *harness) Close() { + h.nc.Close() + h.s.Shutdown() +} + +func (h *harness) MaxBatchSizes() (int, int) { return 0, 0 } + +func (*harness) SupportsMultipleSubscriptions() bool { return true } + +type natsAsTest struct { + useV2 bool +} + +func (natsAsTest) Name() string { + return "nats test" +} + +func (natsAsTest) TopicCheck(topic *pubsub.Topic) error { + var c2 nats.Conn + if topic.As(&c2) { + return fmt.Errorf("cast succeeded for %T, want failure", &c2) + } + var c3 *nats.Conn + if !topic.As(&c3) { + return fmt.Errorf("cast failed for %T", &c3) + } + return nil +} + +func (natsAsTest) SubscriptionCheck(sub *pubsub.Subscription) error { + var c2 nats.Subscription + if sub.As(&c2) { + return fmt.Errorf("cast succeeded for %T, want failure", &c2) + } + var c3 *nats.Subscription + if !sub.As(&c3) { + return fmt.Errorf("cast failed for %T", &c3) + } + return nil +} + +func (natsAsTest) TopicErrorCheck(t *pubsub.Topic, err error) error { + var dummy string + if t.ErrorAs(err, &dummy) { + return fmt.Errorf("cast succeeded for %T, want failure", &dummy) + } + return nil +} + +func (natsAsTest) SubscriptionErrorCheck(s *pubsub.Subscription, err error) error { + var dummy string + if s.ErrorAs(err, &dummy) { + return fmt.Errorf("cast succeeded for %T, want failure", &dummy) + } + return nil +} + +func (natsAsTest) MessageCheck(m *pubsub.Message) error { + var pm nats.Msg + if m.As(&pm) { + return fmt.Errorf("cast succeeded for %T, want failure", &pm) + } + var ppm *nats.Msg + if !m.As(&ppm) { + return fmt.Errorf("cast failed for %T", &ppm) + } + return nil +} + +func (n natsAsTest) BeforeSend(as func(any) bool) error { + if !n.useV2 { + return nil + } + var pm nats.Msg + if as(&pm) { + return fmt.Errorf("cast succeeded for %T, want failure", &pm) + } + + var ppm *nats.Msg + if !as(&ppm) { + return fmt.Errorf("cast failed for %T", &ppm) + } + return nil +} + +func (natsAsTest) AfterSend(as func(any) bool) error { + return nil +} + +func TestConformance(t *testing.T) { + asTests := []drivertest.AsTest{natsAsTest{}} + drivertest.RunConformanceTests(t, newHarness, asTests) +} + +func TestConformanceV2(t *testing.T) { + asTests := []drivertest.AsTest{natsAsTest{useV2: true}} + drivertest.RunConformanceTests(t, newHarnessV2, asTests) +} + +// These are natspubsub specific to increase coverage. + +// If we only send a body we should be able to get that from a direct NATS subscriber. +func TestInteropWithDirectNATS(t *testing.T) { + ctx := context.Background() + dh, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer dh.Close() + conn := dh.(*harness).nc + + const topic = "foo" + body := []byte("hello") + + // Send a message using Go CDK and receive it using NATS directly. + pt, err := OpenTopic(conn, topic, nil) + if err != nil { + t.Fatal(err) + } + defer pt.Shutdown(ctx) + nsub, _ := conn.SubscribeSync(topic) + if err = pt.Send(ctx, &pubsub.Message{Body: body}); err != nil { + t.Fatal(err) + } + m, err := nsub.NextMsgWithContext(ctx) + if err != nil { + t.Fatal(err.Error()) + } + if !bytes.Equal(m.Data, body) { + t.Fatalf("Data did not match. %q vs %q\n", m.Data, body) + } + + // Send a message using NATS directly and receive it using Go CDK. + ps, err := OpenSubscription(conn, topic, nil) + if err != nil { + t.Fatal(err) + } + defer ps.Shutdown(ctx) + if err := conn.Publish(topic, body); err != nil { + t.Fatal(err) + } + msg, err := ps.Receive(ctx) + if err != nil { + t.Fatal(err) + } + defer msg.Ack() + if !bytes.Equal(msg.Body, body) { + t.Fatalf("Data did not match. %q vs %q\n", m.Data, body) + } +} + +// These are natspubsub specific to increase coverage. + +// If we only send a body we should be able to get that from a direct NATS subscriber. +func TestInteropWithDirectNATSV2(t *testing.T) { + ctx := context.Background() + dh, err := newHarnessV2(ctx, t) + if err != nil { + t.Fatal(err) + } + defer dh.Close() + conn := dh.(*harness).nc + + const topic = "foo" + // In version V2 we can use metadata which will be natively used in the nats message. + md := map[string]string{"a": "1", "b": "2", "c": "3"} + body := []byte("hello") + + // Send a message using Go CDK and receive it using NATS directly. + pt, err := OpenTopicV2(conn, topic, nil) + if err != nil { + t.Fatal(err) + } + defer pt.Shutdown(ctx) + nsub, _ := conn.SubscribeSync(topic) + if err = pt.Send(ctx, &pubsub.Message{Body: body, Metadata: md}); err != nil { + t.Fatal(err) + } + m, err := nsub.NextMsgWithContext(ctx) + if err != nil { + t.Fatal(err.Error()) + } + if !bytes.Equal(m.Data, body) { + t.Fatalf("Data did not match. %q vs %q\n", m.Data, body) + } + for k, v := range md { + if m.Header.Get(k) != v { + t.Fatalf("Metadata %q did not match. %q vs %q\n", k, m.Header.Get(k), v) + } + } + + // Send a message using NATS directly and receive it using Go CDK. + ps, err := OpenSubscriptionV2(conn, topic, nil) + if err != nil { + t.Fatal(err) + } + defer ps.Shutdown(ctx) + if err := conn.Publish(topic, body); err != nil { + t.Fatal(err) + } + msg, err := ps.Receive(ctx) + if err != nil { + t.Fatal(err) + } + defer msg.Ack() + if !bytes.Equal(msg.Body, body) { + t.Fatalf("Data did not match. %q vs %q\n", m.Data, body) + } +} + +func TestErrorCode(t *testing.T) { + ctx := context.Background() + dh, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer dh.Close() + h := dh.(*harness) + + // Topics + dt, err := openTopic(h.nc, "bar", false) + if err != nil { + t.Fatal(err) + } + + if gce := dt.ErrorCode(nil); gce != gcerrors.OK { + t.Fatalf("Expected %v, got %v", gcerrors.OK, gce) + } + if gce := dt.ErrorCode(context.Canceled); gce != gcerrors.Canceled { + t.Fatalf("Expected %v, got %v", gcerrors.Canceled, gce) + } + if gce := dt.ErrorCode(nats.ErrBadSubject); gce != gcerrors.FailedPrecondition { + t.Fatalf("Expected %v, got %v", gcerrors.FailedPrecondition, gce) + } + if gce := dt.ErrorCode(nats.ErrAuthorization); gce != gcerrors.PermissionDenied { + t.Fatalf("Expected %v, got %v", gcerrors.PermissionDenied, gce) + } + if gce := dt.ErrorCode(nats.ErrMaxPayload); gce != gcerrors.ResourceExhausted { + t.Fatalf("Expected %v, got %v", gcerrors.ResourceExhausted, gce) + } + if gce := dt.ErrorCode(nats.ErrReconnectBufExceeded); gce != gcerrors.ResourceExhausted { + t.Fatalf("Expected %v, got %v", gcerrors.ResourceExhausted, gce) + } + + // Subscriptions + ds, err := openSubscription(h.nc, "bar", nil, false) + if err != nil { + t.Fatal(err) + } + if gce := ds.ErrorCode(nil); gce != gcerrors.OK { + t.Fatalf("Expected %v, got %v", gcerrors.OK, gce) + } + if gce := ds.ErrorCode(context.Canceled); gce != gcerrors.Canceled { + t.Fatalf("Expected %v, got %v", gcerrors.Canceled, gce) + } + if gce := ds.ErrorCode(nats.ErrBadSubject); gce != gcerrors.FailedPrecondition { + t.Fatalf("Expected %v, got %v", gcerrors.FailedPrecondition, gce) + } + if gce := ds.ErrorCode(nats.ErrBadSubscription); gce != gcerrors.NotFound { + t.Fatalf("Expected %v, got %v", gcerrors.NotFound, gce) + } + if gce := ds.ErrorCode(nats.ErrTypeSubscription); gce != gcerrors.FailedPrecondition { + t.Fatalf("Expected %v, got %v", gcerrors.FailedPrecondition, gce) + } + if gce := ds.ErrorCode(nats.ErrAuthorization); gce != gcerrors.PermissionDenied { + t.Fatalf("Expected %v, got %v", gcerrors.PermissionDenied, gce) + } + if gce := ds.ErrorCode(nats.ErrMaxMessages); gce != gcerrors.ResourceExhausted { + t.Fatalf("Expected %v, got %v", gcerrors.ResourceExhausted, gce) + } + if gce := ds.ErrorCode(nats.ErrSlowConsumer); gce != gcerrors.ResourceExhausted { + t.Fatalf("Expected %v, got %v", gcerrors.ResourceExhausted, gce) + } + if gce := ds.ErrorCode(nats.ErrTimeout); gce != gcerrors.DeadlineExceeded { + t.Fatalf("Expected %v, got %v", gcerrors.DeadlineExceeded, gce) + } + + // Queue Subscription + qs, err := openSubscription(h.nc, "bar", &SubscriptionOptions{Queue: t.Name()}, false) + if err != nil { + t.Fatal(err) + } + if gce := qs.ErrorCode(nil); gce != gcerrors.OK { + t.Fatalf("Expected %v, got %v", gcerrors.OK, gce) + } + if gce := qs.ErrorCode(context.Canceled); gce != gcerrors.Canceled { + t.Fatalf("Expected %v, got %v", gcerrors.Canceled, gce) + } + if gce := qs.ErrorCode(nats.ErrBadSubject); gce != gcerrors.FailedPrecondition { + t.Fatalf("Expected %v, got %v", gcerrors.FailedPrecondition, gce) + } + if gce := qs.ErrorCode(nats.ErrBadSubscription); gce != gcerrors.NotFound { + t.Fatalf("Expected %v, got %v", gcerrors.NotFound, gce) + } + if gce := qs.ErrorCode(nats.ErrTypeSubscription); gce != gcerrors.FailedPrecondition { + t.Fatalf("Expected %v, got %v", gcerrors.FailedPrecondition, gce) + } + if gce := qs.ErrorCode(nats.ErrAuthorization); gce != gcerrors.PermissionDenied { + t.Fatalf("Expected %v, got %v", gcerrors.PermissionDenied, gce) + } + if gce := qs.ErrorCode(nats.ErrMaxMessages); gce != gcerrors.ResourceExhausted { + t.Fatalf("Expected %v, got %v", gcerrors.ResourceExhausted, gce) + } + if gce := qs.ErrorCode(nats.ErrSlowConsumer); gce != gcerrors.ResourceExhausted { + t.Fatalf("Expected %v, got %v", gcerrors.ResourceExhausted, gce) + } + if gce := qs.ErrorCode(nats.ErrTimeout); gce != gcerrors.DeadlineExceeded { + t.Fatalf("Expected %v, got %v", gcerrors.DeadlineExceeded, gce) + } +} + +func BenchmarkNatsQueuePubSub(b *testing.B) { + ctx := context.Background() + + opts := gnatsd.DefaultTestOptions + opts.Port = benchPort + s := gnatsd.RunServer(&opts) + defer s.Shutdown() + + nc, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", benchPort)) + if err != nil { + b.Fatal(err) + } + defer nc.Close() + + for _, tc := range []struct { + name string + h *harness + }{ + {name: "V1", h: &harness{s: s, nc: nc, useV2: false}}, + {name: "V2", h: &harness{s: s, nc: nc, useV2: true}}, + } { + b.Run(tc.name, func(b *testing.B) { + dt, cleanup, err := tc.h.CreateTopic(ctx, b.Name()) + if err != nil { + b.Fatal(err) + } + defer cleanup() + + qs, cleanup, err := tc.h.CreateQueueSubscription(ctx, dt, b.Name()) + if err != nil { + b.Fatal(err) + } + defer cleanup() + + topic := pubsub.NewTopic(dt, nil) + defer topic.Shutdown(ctx) + queueSub := pubsub.NewSubscription(qs, recvBatcherOpts, nil) + defer queueSub.Shutdown(ctx) + + drivertest.RunBenchmarks(b, topic, queueSub) + }) + } +} + +func BenchmarkNatsPubSub(b *testing.B) { + ctx := context.Background() + + opts := gnatsd.DefaultTestOptions + opts.Port = benchPort + s := gnatsd.RunServer(&opts) + defer s.Shutdown() + + nc, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", benchPort)) + if err != nil { + b.Fatal(err) + } + defer nc.Close() + + for _, tc := range []struct { + name string + h *harness + }{ + {name: "V1", h: &harness{s: s, nc: nc, useV2: false}}, + {name: "V2", h: &harness{s: s, nc: nc, useV2: true}}, + } { + b.Run(tc.name, func(b *testing.B) { + dt, cleanup, err := tc.h.CreateTopic(ctx, b.Name()) + if err != nil { + b.Fatal(err) + } + defer cleanup() + ds, cleanup, err := tc.h.CreateSubscription(ctx, dt, b.Name()) + if err != nil { + b.Fatal(err) + } + defer cleanup() + + topic := pubsub.NewTopic(dt, nil) + defer topic.Shutdown(ctx) + sub := pubsub.NewSubscription(ds, recvBatcherOpts, nil) + defer sub.Shutdown(ctx) + + drivertest.RunBenchmarks(b, topic, sub) + }) + } +} + +func fakeConnectionStringInEnv() func() { + oldEnvVal := os.Getenv("NATS_SERVER_URL") + os.Setenv("NATS_SERVER_URL", fmt.Sprintf("nats://localhost:%d", testPort)) + return func() { + os.Setenv("NATS_SERVER_URL", oldEnvVal) + } +} + +func TestOpenTopicFromURL(t *testing.T) { + ctx := context.Background() + dh, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer dh.Close() + + cleanup := fakeConnectionStringInEnv() + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"nats://mytopic", false}, + // Invalid parameter. + {"nats://mytopic?param=value", true}, + } + + for _, test := range tests { + topic, err := pubsub.OpenTopic(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if topic != nil { + topic.Shutdown(ctx) + } + } +} + +func TestOpenSubscriptionFromURL(t *testing.T) { + ctx := context.Background() + dh, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer dh.Close() + + cleanup := fakeConnectionStringInEnv() + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"nats://mytopic", false}, + // Invalid parameter. + {"nats://mytopic?param=value", true}, + // Queue URL Parameter for QueueSubscription. + {"nats://mytopic?queue=queue1", false}, + // Multiple values for Queue URL Parameter for QueueSubscription. + {"nats://mytopic?queue=queue1&queue=queue2", true}, + // NATSV2 URL should be acceptable without values. + {"nats://mytopic?natsv2", false}, + // NATSV2 URL should be acceptable with boolean parsable values. + {"nats://mytopic?natsv2=true", false}, + {"nats://mytopic?natsv2=false", false}, + // NATSV2 URL should throw error with non-boolean parsable values. + {"nats://mytopic?natsv2=foo", true}, + } + + for _, test := range tests { + sub, err := pubsub.OpenSubscription(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if sub != nil { + sub.Shutdown(ctx) + } + } +} + +func TestCodec(t *testing.T) { + const sub = "foo" + for _, dm := range []*driver.Message{ + {Metadata: nil, Body: nil}, + {Metadata: map[string]string{"a": "1"}, Body: nil}, + {Metadata: nil, Body: []byte("hello")}, + {Metadata: map[string]string{"a": "1"}, Body: []byte("hello")}, + { + Metadata: map[string]string{"a": "1"}, Body: []byte("hello"), + AckID: "foo", AsFunc: func(any) bool { return true }, + }, + } { + t.Run("V1", func(t *testing.T) { + bytes, err := encodeMessage(dm) + if err != nil { + t.Fatal(err) + } + var got driver.Message + if err := decodeMessage(bytes, &got); err != nil { + t.Fatal(err) + } + want := *dm + want.AckID = nil + want.AsFunc = nil + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("%+v:\n%s", want, diff) + } + }) + t.Run("V2", func(t *testing.T) { + nm := encodeMessageV2(dm, sub) + got, err := decodeMessageV2(nm) + if err != nil { + t.Fatal(err) + } + + want := *dm + want.AckID = nil + want.AsFunc = nil + // AsFunc needs to be cleared as it cannot be comparable using Diff. + got.AsFunc = nil + if diff := cmp.Diff(*got, want); diff != "" { + t.Errorf("%+v:\n%s", want, diff) + } + }) + + } +} diff --git a/go-cloud/pubsub/pub_test.go b/go-cloud/pubsub/pub_test.go new file mode 100644 index 000000000..caa042ff1 --- /dev/null +++ b/go-cloud/pubsub/pub_test.go @@ -0,0 +1,91 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 pubsub_test + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" +) + +type funcTopic struct { + driver.Topic + sendBatch func(ctx context.Context, ms []*driver.Message) error + closed bool +} + +func (t *funcTopic) SendBatch(ctx context.Context, ms []*driver.Message) error { + return t.sendBatch(ctx, ms) +} + +func (t *funcTopic) IsRetryable(error) bool { return false } +func (t *funcTopic) Close() error { + t.closed = true + return nil +} + +func TestTopicShutdownCanBeCanceledEvenWithHangingSend(t *testing.T) { + dt := &funcTopic{ + sendBatch: func(ctx context.Context, ms []*driver.Message) error { + <-ctx.Done() + return ctx.Err() + }, + } + topic := pubsub.NewTopic(dt, nil) + + errs := make(chan error, 1) + + go func() { + m := &pubsub.Message{} + if err := topic.Send(context.Background(), m); err == nil { + errs <- errors.New("nil err from Send, expected context cancellation error") + } + }() + + done := make(chan struct{}) + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) + defer cancel() + go func() { + topic.Shutdown(ctx) + close(done) + }() + + // Now cancel the context being used by topic.Shutdown. + cancel() + + // It shouldn't take too long before topic.Shutdown stops. + tooLong := 5 * time.Second + select { + case <-done: + case <-time.After(tooLong): + t.Fatalf("waited too long(%v) for Shutdown(ctx) to run", tooLong) + case err := <-errs: + t.Fatalf("got error from goroutine: %v", err) + } +} + +func TestTopicCloseIsCalled(t *testing.T) { + ctx := context.Background() + dt := &funcTopic{} + topic := pubsub.NewTopic(dt, nil) + topic.Shutdown(ctx) + if !dt.closed { + t.Error("want Topic.Close to have been called") + } +} diff --git a/go-cloud/pubsub/pubsub.go b/go-cloud/pubsub/pubsub.go new file mode 100644 index 000000000..12528ab92 --- /dev/null +++ b/go-cloud/pubsub/pubsub.go @@ -0,0 +1,939 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 pubsub provides an easy and portable way to interact with +// publish/subscribe systems. Subpackages contain driver implementations of +// pubsub for supported services +// +// See https://gocloud.dev/howto/pubsub/ for a detailed how-to guide. +// +// # At-most-once and At-least-once Delivery +// +// The semantics of message delivery vary across PubSub services. +// Some services guarantee that messages received by subscribers but not +// acknowledged are delivered again (at-least-once semantics). In others, +// a message will be delivered only once, if it is delivered at all +// (at-most-once semantics). Some services support both modes via options. +// +// This package accommodates both kinds of systems, but application developers +// should think carefully about which kind of semantics the application needs. +// Even though the application code may look similar, system-level +// characteristics are quite different. See the driver package +// documentation for more information about message delivery semantics. +// +// After receiving a Message via Subscription.Receive: +// - Always call Message.Ack or Message.Nack after processing the message. +// - For some drivers, Ack will be a no-op. +// - For some drivers, Nack is not supported and will panic; you can call +// Message.Nackable to see. +// +// # OpenTelemetry Integration. +// +// OpenTelemetry supports tracing and metric collection for multiple languages and +// backend providers. See https://opentelemetry.io. +// +// This API collects OpenTelemetry traces and metrics for the following methods: +// - Topic.Send +// - Topic.Shutdown +// - Subscription.Receive +// - Subscription.Shutdown +// - The internal driver methods SendBatch, SendAcks and ReceiveBatch. +// +// All trace and metric names begin with the package import path. +// The traces add the method name. +// For example, "gocloud.dev/pubsub/Topic.Send". +// The metrics are "completed_calls", a count of completed method calls by driver, +// method and status (error code); and "latency", a distribution of method latency +// by driver and method. +// For example, "gocloud.dev/pubsub/latency". +// +// To enable trace collection in your application, see "Configure an Exporter" at +// https://opentelemetry.io/docs/languages/go/getting-started/. +// To enable metric collection in your application, see "Metrics" at +// https://opentelemetry.io/docs/languages/go/metrics/. +package pubsub // import "gocloud.dev/pubsub" + +import ( + "context" + "errors" + "fmt" + "log" + "math" + "net/url" + "reflect" + "runtime" + "sync" + "time" + "unicode/utf8" + + "github.com/googleapis/gax-go/v2" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/openurl" + gcdkotel "github.com/DataDog/iceberg-go/go-cloud/internal/otel" + "github.com/DataDog/iceberg-go/go-cloud/internal/retry" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/batcher" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" + "golang.org/x/sync/errgroup" +) + +// Message contains data to be published. +type Message struct { + // LoggableID will be set to an opaque message identifer for + // received messages, useful for debug logging. No assumptions should + // be made about the content. + LoggableID string + + // Body contains the content of the message. + Body []byte + + // Metadata has key/value metadata for the message. + // + // When sending a message, set any key/value pairs you want associated with + // the message. It is acceptable for Metadata to be nil. + // Note that some services limit the number of key/value pairs per message. + // + // When receiving a message, Metadata will be nil if the message has no + // associated metadata. + Metadata map[string]string + + // BeforeSend is a callback used when sending a message. It will always be + // set to nil for received messages. + // + // The callback will be called exactly once, before the message is sent. + // + // asFunc converts its argument to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + BeforeSend func(asFunc func(any) bool) error + + // AfterSend is a callback used when sending a message. It will always be + // set to nil for received messages. + // + // The callback will be called at most once, after the message is sent. + // If Send returns an error, AfterSend will not be called. + // + // asFunc converts its argument to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + AfterSend func(asFunc func(any) bool) error + + // asFunc invokes driver.Message.AsFunc. + asFunc func(any) bool + + // ack is a closure that queues this message for the action (ack or nack). + ack func(isAck bool) + + // nackable is true iff Nack can be called without panicking. + nackable bool + + // mu guards isAcked in case Ack/Nack is called concurrently. + mu sync.Mutex + + // isAcked tells whether this message has already had its Ack or Nack + // method called. + isAcked bool +} + +// Ack acknowledges the message, telling the server that it does not need to be +// sent again to the associated Subscription. It will be a no-op for some +// drivers; see +// https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery +// for more info. +// +// Ack returns immediately, but the actual ack is sent in the background, and +// is not guaranteed to succeed. If background acks persistently fail, the error +// will be returned from a subsequent Receive. +func (m *Message) Ack() { + m.mu.Lock() + defer m.mu.Unlock() + if m.isAcked { + panic(fmt.Sprintf("Ack/Nack called twice on message: %+v", m)) + } + m.ack(true) + m.isAcked = true +} + +// Nackable returns true iff Nack can be called without panicking. +// +// Some services do not support Nack; for example, at-most-once services +// can't redeliver a message. See +// https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery +// for more info. +func (m *Message) Nackable() bool { + return m.nackable +} + +// Nack (short for negative acknowledgment) tells the server that this Message +// was not processed and should be redelivered. +// +// Nack panics for some drivers, as Nack is meaningless when messages can't be +// redelivered. You can call Nackable to determine if Nack is available. See +// https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery +// fore more info. +// +// Nack returns immediately, but the actual nack is sent in the background, +// and is not guaranteed to succeed. +// +// Nack is a performance optimization for retrying transient failures. It +// must not be used for message parse errors or other messages that the +// application will never be able to process: calling Nack will cause them to +// be redelivered and overload the server. Instead, an application should call +// Ack and log the failure in some monitored way. +func (m *Message) Nack() { + m.mu.Lock() + defer m.mu.Unlock() + if m.isAcked { + panic(fmt.Sprintf("Ack/Nack called twice on message: %+v", m)) + } + if !m.nackable { + panic("Message.Nack is not supported by this driver") + } + m.ack(false) + m.isAcked = true +} + +// As converts i to driver-specific types. +// See https://gocloud.dev/concepts/as/ for background information, the "As" +// examples in this package for examples, and the driver package +// documentation for the specific types supported for that driver. +// As panics unless it is called on a message obtained from Subscription.Receive. +func (m *Message) As(i any) bool { + if m.asFunc == nil { + panic("As called on a Message that was not obtained from Receive") + } + return m.asFunc(i) +} + +// Topic publishes messages to all its subscribers. +type Topic struct { + driver driver.Topic + batcher *batcher.Batcher + tracer *gcdkotel.Tracer + mu sync.Mutex + err error + + // cancel cancels all SendBatch calls. + cancel func() +} + +// Send publishes a message. It only returns after the message has been +// sent, or failed to be sent. Send can be called from multiple goroutines +// at once. +func (t *Topic) Send(ctx context.Context, m *Message) (err error) { + ctx, span := t.tracer.Start(ctx, "Topic.Send") + defer func() { t.tracer.End(ctx, span, err) }() + + // Check for doneness before we do any work. + if err := ctx.Err(); err != nil { + return err // Return context errors unwrapped. + } + t.mu.Lock() + err = t.err + t.mu.Unlock() + if err != nil { + return err // t.err wrapped when set + } + if m.LoggableID != "" { + return gcerr.Newf(gcerr.InvalidArgument, nil, "pubsub: Message.LoggableID should not be set when sending a message") + } + for k, v := range m.Metadata { + if !utf8.ValidString(k) { + return gcerr.Newf(gcerr.InvalidArgument, nil, "pubsub: Message.Metadata keys must be valid UTF-8 strings: %q", k) + } + if !utf8.ValidString(v) { + return gcerr.Newf(gcerr.InvalidArgument, nil, "pubsub: Message.Metadata values must be valid UTF-8 strings: %q", v) + } + } + dm := &driver.Message{ + Body: m.Body, + Metadata: m.Metadata, + BeforeSend: m.BeforeSend, + AfterSend: m.AfterSend, + } + return t.batcher.Add(ctx, dm) +} + +var errTopicShutdown = gcerr.Newf(gcerr.FailedPrecondition, nil, "pubsub: Topic has been Shutdown") + +// Shutdown flushes pending message sends and disconnects the Topic. +// It only returns after all pending messages have been sent. +func (t *Topic) Shutdown(ctx context.Context) (err error) { + ctx, span := t.tracer.Start(ctx, "Topic.Shutdown") + defer func() { t.tracer.End(ctx, span, err) }() + + t.mu.Lock() + if errors.Is(t.err, errTopicShutdown) { + defer t.mu.Unlock() + return t.err + } + t.err = errTopicShutdown + t.mu.Unlock() + c := make(chan struct{}) + go func() { + defer close(c) + t.batcher.Shutdown() + }() + select { + case <-ctx.Done(): + case <-c: + } + t.cancel() + if err := t.driver.Close(); err != nil { + return wrapError(t.driver, err) + } + return ctx.Err() +} + +// As converts i to driver-specific types. +// See https://gocloud.dev/concepts/as/ for background information, the "As" +// examples in this package for examples, and the driver package +// documentation for the specific types supported for that driver. +func (t *Topic) As(i any) bool { + return t.driver.As(i) +} + +// ErrorAs converts err to driver-specific types. +// ErrorAs panics if i is nil or not a pointer. +// ErrorAs returns false if err == nil. +// See https://gocloud.dev/concepts/as/ for background information. +func (t *Topic) ErrorAs(err error, i any) bool { + return gcerr.ErrorAs(err, i, t.driver.ErrorAs) +} + +// NewTopic is for use by drivers only. Do not use in application code. +var NewTopic = newTopic + +// newSendBatcher creates a batcher for topics, for use with NewTopic. +func newSendBatcher(ctx context.Context, t *Topic, dt driver.Topic, opts *batcher.Options) *batcher.Batcher { + handler := func(items any) error { + dms := items.([]*driver.Message) + err := retry.Call(ctx, gax.Backoff{}, dt.IsRetryable, func() (err error) { + spanCtx, span := t.tracer.Start(ctx, "driver.Topic.SendBatch") + defer func() { t.tracer.End(spanCtx, span, err) }() + return dt.SendBatch(spanCtx, dms) + }) + if err != nil { + return wrapError(dt, err) + } + return nil + } + return batcher.New(reflect.TypeOf(&driver.Message{}), opts, handler) +} + +// newTopic makes a pubsub.Topic from a driver.Topic. +// +// opts may be nil to accept defaults. +func newTopic(d driver.Topic, opts *batcher.Options) *Topic { + ctx, cancel := context.WithCancel(context.Background()) + t := &Topic{ + driver: d, + tracer: gcdkotel.NewTracer(pkgName, gcdkotel.ProviderName(d)), + cancel: cancel, + } + t.batcher = newSendBatcher(ctx, t, d, opts) + return t +} + +const pkgName = "gocloud.dev/pubsub" + +var ( + + // OpenTelemetryViews are predefined views for OpenTelemetry metrics. + // The views include counts and latency distributions for API method calls. + // See the explanations at https://opentelemetry.io/docs/specs/otel/metrics/data-model/ for usage. + OpenTelemetryViews = gcdkotel.Views(pkgName) +) + +// Subscription receives published messages. +type Subscription struct { + driver driver.Subscription + tracer *gcdkotel.Tracer + // ackBatcher makes batches of acks and nacks and sends them to the server. + ackBatcher *batcher.Batcher + canNack bool // true iff the driver supports Nack + backgroundCtx context.Context // for background SendAcks and ReceiveBatch calls + cancel func() // for canceling backgroundCtx + + recvBatchOpts *batcher.Options + + mu sync.Mutex // protects everything below + q []*driver.Message // local queue of messages downloaded from server + err error // permanent error + unreportedAckErr error // permanent error from background SendAcks that hasn't been returned to the user yet + waitc chan struct{} // for goroutines waiting on ReceiveBatch + runningBatchSize float64 // running number of messages to request via ReceiveBatch + throughputStart time.Time // start time for throughput measurement + throughputCount int // number of msgs given out via Receive since throughputStart + + // Used in tests. + preReceiveBatchHook func(maxMessages int) +} + +const ( + // The desired duration of a subscription's queue of messages (the messages pulled + // and waiting in memory to be doled out to Receive callers). This is how long + // it would take to drain the queue at the current processing rate. + // The relationship to queue length (number of messages) is + // + // lengthInMessages = desiredQueueDuration / averageProcessTimePerMessage + // + // In other words, if it takes 100ms to process a message on average, and we want + // 2s worth of queued messages, then we need 2/.1 = 20 messages in the queue. + // + // If desiredQueueDuration is too small, then there won't be a large enough buffer + // of messages to handle fluctuations in processing time, and the queue is likely + // to become empty, reducing throughput. If desiredQueueDuration is too large, then + // messages will wait in memory for a long time, possibly timing out (that is, + // their ack deadline will be exceeded). Those messages could have been handled + // by another process receiving from the same subscription. + desiredQueueDuration = 2 * time.Second + + // Expected duration of calls to driver.ReceiveBatch, at some high percentile. + // We'll try to fetch more messages when the current queue is predicted + // to be used up in expectedReceiveBatchDuration. + expectedReceiveBatchDuration = 1 * time.Second + + // s.runningBatchSize holds our current best guess for how many messages to + // fetch in order to have a buffer of desiredQueueDuration. When we have + // fewer than prefetchRatio * s.runningBatchSize messages left, that means + // we expect to run out of messages in expectedReceiveBatchDuration, so we + // should initiate another ReceiveBatch call. + prefetchRatio = float64(expectedReceiveBatchDuration) / float64(desiredQueueDuration) + + // The initial # of messages to request via ReceiveBatch. + initialBatchSize = 1 + + // The factor by which old batch sizes decay when a new value is added to the + // running value. The larger this number, the more weight will be given to the + // newest value in preference to older ones. + // + // The delta based on a single value is capped by the constants below. + decay = 0.5 + + // The maximum growth factor in a single jump. Higher values mean that the + // batch size can increase more aggressively. For example, 2.0 means that the + // batch size will at most double from one ReceiveBatch call to the next. + maxGrowthFactor = 2.0 + + // Similarly, the maximum shrink factor. Lower values mean that the batch size + // can shrink more aggressively. For example; 0.75 means that the batch size + // will at most shrink to 75% of what it was before. Note that values less + // than (1-decay) will have no effect because the running value can't change + // by more than that. + maxShrinkFactor = 0.75 + + // The maximum batch size to request. Setting this too low doesn't allow + // drivers to get lots of messages at once; setting it too small risks having + // drivers spend a long time in ReceiveBatch trying to achieve it. + maxBatchSize = 3000 +) + +// updateBatchSize updates the number of messages to request in ReceiveBatch +// based on the previous batch size and the rate of messages being pulled from +// the queue, measured using s.throughput*. +// +// It returns the number of messages to request in this ReceiveBatch call. +// +// s.mu must be held. +func (s *Subscription) updateBatchSize() int { + // If we're always only doing one at a time, there's no point in this. + if s.recvBatchOpts != nil && s.recvBatchOpts.MaxBatchSize == 1 && s.recvBatchOpts.MaxHandlers == 1 { + return 1 + } + now := time.Now() + if s.throughputStart.IsZero() { + // No throughput measurement; don't update s.runningBatchSize. + } else { + // Update s.runningBatchSize based on throughput since our last time here, + // as measured by the ratio of the number of messages returned to elapsed + // time. + elapsed := now.Sub(s.throughputStart) + if elapsed < 100*time.Millisecond { + // Avoid divide-by-zero and huge numbers. + elapsed = 100 * time.Millisecond + } + msgsPerSec := float64(s.throughputCount) / elapsed.Seconds() + + // The "ideal" batch size is how many messages we'd need in the queue to + // support desiredQueueDuration at the msgsPerSec rate. + idealBatchSize := desiredQueueDuration.Seconds() * msgsPerSec + + // Move s.runningBatchSize towards the ideal. + // We first combine the previous value and the new value, with weighting + // based on decay, and then cap the growth/shrinkage. + newBatchSize := s.runningBatchSize*(1-decay) + idealBatchSize*decay + if maxSize := s.runningBatchSize * maxGrowthFactor; newBatchSize > maxSize { + s.runningBatchSize = maxSize + } else if minSize := s.runningBatchSize * maxShrinkFactor; newBatchSize < minSize { + s.runningBatchSize = minSize + } else { + s.runningBatchSize = newBatchSize + } + } + + // Reset throughput measurement markers. + s.throughputStart = now + s.throughputCount = 0 + + // Using Ceil guarantees at least one message. + return int(math.Ceil(math.Min(s.runningBatchSize, maxBatchSize))) +} + +// Receive receives and returns the next message from the Subscription's queue, +// blocking and polling if none are available. It can be called +// concurrently from multiple goroutines. +// +// Receive retries retryable errors from the underlying driver forever. +// Therefore, if Receive returns an error, either: +// 1. It is a non-retryable error from the underlying driver, either from +// +// an attempt to fetch more messages or from an attempt to ack messages. +// Operator intervention may be required (e.g., invalid resource, quota +// error, etc.). Receive will return the same error from then on, so the +// application should log the error and either recreate the Subscription, +// or exit. +// +// 2. The provided ctx is Done. Error() on the returned error will include both +// +// the ctx error and the underlying driver error, and ErrorAs on it +// can access the underlying driver error type if needed. Receive may +// be called again with a fresh ctx. +// +// Callers can distinguish between the two by checking if the ctx they passed +// is Done, or via xerrors.Is(err, context.DeadlineExceeded or context.Canceled) +// on the returned error. +// +// The Ack method of the returned Message must be called once the message has +// been processed, to prevent it from being received again. +func (s *Subscription) Receive(ctx context.Context) (_ *Message, err error) { + ctx, span := s.tracer.Start(ctx, "Subscription.Receive") + defer func() { s.tracer.End(ctx, span, err) }() + + s.mu.Lock() + defer s.mu.Unlock() + for { + // The lock is always held here, at the top of the loop. + if s.err != nil { + // The Subscription is in a permanent error state. Return the error. + s.unreportedAckErr = nil + return nil, s.err // s.err wrapped when set + } + + // Short circuit if ctx is Done. + // Otherwise, we'll continue to return messages from the queue, and even + // get new messages if driver.ReceiveBatch doesn't return an error when + // ctx is done. + if err := ctx.Err(); err != nil { + return nil, err + } + + if s.waitc == nil && float64(len(s.q)) <= s.runningBatchSize*prefetchRatio { + // We think we're going to run out of messages in expectedReceiveBatchDuration, + // and there's no outstanding ReceiveBatch call, so initiate one in the + // background. + // Completion will be signalled to this goroutine, and to any other + // waiting goroutines, by closing s.waitc. + s.waitc = make(chan struct{}) + batchSize := s.updateBatchSize() + // log.Printf("BATCH SIZE %d", batchSize) + + go func() { + if s.preReceiveBatchHook != nil { + s.preReceiveBatchHook(batchSize) + } + resultChannel := s.getNextBatch(batchSize) + for msgsOrError := range resultChannel { + if len(msgsOrError.msgs) > 0 { + // messages received from channel + s.mu.Lock() + s.q = append(s.q, msgsOrError.msgs...) + s.mu.Unlock() + // notify that queue should now have messages + s.waitc <- struct{}{} + } else if msgsOrError.err != nil { + // err can receive message only after batch group completes + // Non-retryable error from ReceiveBatch -> permanent error + s.mu.Lock() + s.err = msgsOrError.err + s.mu.Unlock() + } + } + // batch reception finished + s.mu.Lock() + close(s.waitc) + s.waitc = nil + s.mu.Unlock() + }() + } + if len(s.q) > 0 { + // At least one message is available. Return it. + m := s.q[0] + s.q = s.q[1:] + s.throughputCount++ + + // Convert driver.Message to Message. + id := m.AckID + md := m.Metadata + if len(md) == 0 { + md = nil + } + loggableID := m.LoggableID + if loggableID == "" { + // This shouldn't happen, but just in case it's better to be explicit. + loggableID = "unknown" + } + m2 := &Message{ + LoggableID: loggableID, + Body: m.Body, + Metadata: md, + asFunc: m.AsFunc, + nackable: s.canNack, + } + m2.ack = func(isAck bool) { + // Ignore the error channel. Errors are dealt with + // in the ackBatcher handler. + _ = s.ackBatcher.AddNoWait(&driver.AckInfo{AckID: id, IsAck: isAck}) + } + // Add a finalizer that complains if the Message we return isn't + // acked or nacked. + _, file, lineno, ok := runtime.Caller(1) // the caller of Receive + runtime.SetFinalizer(m2, func(m *Message) { + m.mu.Lock() + defer m.mu.Unlock() + if !m.isAcked { + var caller string + if ok { + caller = fmt.Sprintf(" (%s:%d)", file, lineno) + } + log.Printf("A pubsub.Message was never Acked or Nacked%s", caller) + } + }) + return m2, nil + } + // A call to ReceiveBatch must be in flight. Wait for it. + waitc := s.waitc + s.mu.Unlock() // unlock to allow message or error processing from background goroutine + select { + case <-waitc: + // Continue to top of loop. + s.mu.Lock() + case <-ctx.Done(): + s.mu.Lock() + return nil, ctx.Err() + } + } +} + +type msgsOrError struct { + msgs []*driver.Message + err error +} + +// getNextBatch gets the next batch of messages from the server. It will return a channel that will itself return the +// messages as they come from each independent batch, or an operation error +func (s *Subscription) getNextBatch(nMessages int) chan msgsOrError { + // Split nMessages into batches based on recvBatchOpts; we'll make a + // separate ReceiveBatch call for each batch, and aggregate the results in + // msgs. + batches := batcher.Split(nMessages, s.recvBatchOpts) + result := make(chan msgsOrError, len(batches)) + g, ctx := errgroup.WithContext(s.backgroundCtx) + for _, maxMessagesInBatch := range batches { + // Make a copy of the loop variable since it will be used by a goroutine. + curMaxMessagesInBatch := maxMessagesInBatch + g.Go(func() error { + var msgs []*driver.Message + err := retry.Call(ctx, gax.Backoff{}, s.driver.IsRetryable, func() error { + var err error + spanCtx, span := s.tracer.Start(ctx, "driver.Subscription.ReceiveBatch") + defer func() { s.tracer.End(spanCtx, span, err) }() + msgs, err = s.driver.ReceiveBatch(spanCtx, curMaxMessagesInBatch) + return err + }) + if err != nil { + return wrapError(s.driver, err) + } + result <- msgsOrError{msgs: msgs} + return nil + }) + } + go func() { + // wait on group completion on the background and proper channel closing + if err := g.Wait(); err != nil { + result <- msgsOrError{err: err} + } + close(result) + }() + return result +} + +var errSubscriptionShutdown = gcerr.Newf(gcerr.FailedPrecondition, nil, "pubsub: Subscription has been Shutdown") + +// Shutdown flushes pending ack sends and disconnects the Subscription. +func (s *Subscription) Shutdown(ctx context.Context) (err error) { + ctx, span := s.tracer.Start(ctx, "Subscription.Shutdown") + defer func() { s.tracer.End(ctx, span, err) }() + + s.mu.Lock() + if errors.Is(s.err, errSubscriptionShutdown) { + // Already Shutdown. + defer s.mu.Unlock() + return s.err + } + s.err = errSubscriptionShutdown + s.mu.Unlock() + c := make(chan struct{}) + go func() { + defer close(c) + if s.ackBatcher != nil { + s.ackBatcher.Shutdown() + } + }() + select { + case <-ctx.Done(): + case <-c: + } + s.cancel() + if err := s.driver.Close(); err != nil { + return wrapError(s.driver, err) + } + s.mu.Lock() + defer s.mu.Unlock() + if err := s.unreportedAckErr; err != nil { + s.unreportedAckErr = nil + return err + } + return ctx.Err() +} + +// As converts i to driver-specific types. +// See https://gocloud.dev/concepts/as/ for background information, the "As" +// examples in this package for examples, and the driver package +// documentation for the specific types supported for that driver. +func (s *Subscription) As(i any) bool { + return s.driver.As(i) +} + +// ErrorAs converts err to driver-specific types. +// ErrorAs panics if i is nil or not a pointer. +// ErrorAs returns false if err == nil. +// See Topic.As for more details. +func (s *Subscription) ErrorAs(err error, i any) bool { + return gcerr.ErrorAs(err, i, s.driver.ErrorAs) +} + +// NewSubscription is for use by drivers only. Do not use in application code. +var NewSubscription = newSubscription + +// newSubscription creates a Subscription from a driver.Subscription. +// +// recvBatchOpts sets options for Receive batching. May be nil to accept +// defaults. The ideal number of messages to receive at a time is determined +// dynamically, then split into multiple possibly concurrent calls to +// driver.ReceiveBatch based on recvBatchOptions. +// +// ackBatcherOpts sets options for ack+nack batching. May be nil to accept +// defaults. +func newSubscription(ds driver.Subscription, recvBatchOpts, ackBatcherOpts *batcher.Options) *Subscription { + ctx, cancel := context.WithCancel(context.Background()) + s := &Subscription{ + driver: ds, + tracer: gcdkotel.NewTracer(pkgName, gcdkotel.ProviderName(ds)), + cancel: cancel, + backgroundCtx: ctx, + recvBatchOpts: recvBatchOpts, + runningBatchSize: initialBatchSize, + canNack: ds.CanNack(), + } + s.ackBatcher = newAckBatcher(ctx, s, ds, ackBatcherOpts) + return s +} + +func newAckBatcher(ctx context.Context, s *Subscription, ds driver.Subscription, opts *batcher.Options) *batcher.Batcher { + handler := func(items any) error { + var acks, nacks []driver.AckID + for _, a := range items.([]*driver.AckInfo) { + if a.IsAck { + acks = append(acks, a.AckID) + } else { + nacks = append(nacks, a.AckID) + } + } + g, ctx := errgroup.WithContext(ctx) + if len(acks) > 0 { + g.Go(func() error { + return retry.Call(ctx, gax.Backoff{}, ds.IsRetryable, func() (err error) { + spanCtx, span := s.tracer.Start(ctx, "driver.Subscription.SendAcks") + defer func() { s.tracer.End(spanCtx, span, err) }() + return ds.SendAcks(spanCtx, acks) + }) + }) + } + if len(nacks) > 0 { + g.Go(func() error { + return retry.Call(ctx, gax.Backoff{}, ds.IsRetryable, func() (err error) { + spanCtx, span := s.tracer.Start(ctx, "driver.Subscription.SendNacks") + defer func() { s.tracer.End(spanCtx, span, err) }() + return ds.SendNacks(spanCtx, nacks) + }) + }) + } + err := g.Wait() + // Remember a non-retryable error from SendAcks/Nacks. It will be returned on the + // next call to Receive. + if err != nil { + err = wrapError(s.driver, err) + s.mu.Lock() + s.err = err + s.unreportedAckErr = err + s.mu.Unlock() + } + return err + } + return batcher.New(reflect.TypeOf([]*driver.AckInfo{}).Elem(), opts, handler) +} + +type errorCoder interface { + ErrorCode(error) gcerrors.ErrorCode +} + +func wrapError(ec errorCoder, err error) error { + if err == nil { + return nil + } + if gcerr.DoNotWrap(err) { + return err + } + return gcerr.New(ec.ErrorCode(err), err, 2, "pubsub") +} + +// TopicURLOpener represents types than can open Topics based on a URL. +// The opener must not modify the URL argument. OpenTopicURL must be safe to +// call from multiple goroutines. +// +// This interface is generally implemented by types in driver packages. +type TopicURLOpener interface { + OpenTopicURL(ctx context.Context, u *url.URL) (*Topic, error) +} + +// SubscriptionURLOpener represents types than can open Subscriptions based on a URL. +// The opener must not modify the URL argument. OpenSubscriptionURL must be safe to +// call from multiple goroutines. +// +// This interface is generally implemented by types in driver packages. +type SubscriptionURLOpener interface { + OpenSubscriptionURL(ctx context.Context, u *url.URL) (*Subscription, error) +} + +// URLMux is a URL opener multiplexer. It matches the scheme of the URLs +// against a set of registered schemes and calls the opener that matches the +// URL's scheme. +// See https://gocloud.dev/concepts/urls/ for more information. +// +// The zero value is a multiplexer with no registered schemes. +type URLMux struct { + subscriptionSchemes openurl.SchemeMap + topicSchemes openurl.SchemeMap +} + +// TopicSchemes returns a sorted slice of the registered Topic schemes. +func (mux *URLMux) TopicSchemes() []string { return mux.topicSchemes.Schemes() } + +// ValidTopicScheme returns true iff scheme has been registered for Topics. +func (mux *URLMux) ValidTopicScheme(scheme string) bool { return mux.topicSchemes.ValidScheme(scheme) } + +// SubscriptionSchemes returns a sorted slice of the registered Subscription schemes. +func (mux *URLMux) SubscriptionSchemes() []string { return mux.subscriptionSchemes.Schemes() } + +// ValidSubscriptionScheme returns true iff scheme has been registered for Subscriptions. +func (mux *URLMux) ValidSubscriptionScheme(scheme string) bool { + return mux.subscriptionSchemes.ValidScheme(scheme) +} + +// RegisterTopic registers the opener with the given scheme. If an opener +// already exists for the scheme, RegisterTopic panics. +func (mux *URLMux) RegisterTopic(scheme string, opener TopicURLOpener) { + mux.topicSchemes.Register("pubsub", "Topic", scheme, opener) +} + +// RegisterSubscription registers the opener with the given scheme. If an opener +// already exists for the scheme, RegisterSubscription panics. +func (mux *URLMux) RegisterSubscription(scheme string, opener SubscriptionURLOpener) { + mux.subscriptionSchemes.Register("pubsub", "Subscription", scheme, opener) +} + +// OpenTopic calls OpenTopicURL with the URL parsed from urlstr. +// OpenTopic is safe to call from multiple goroutines. +func (mux *URLMux) OpenTopic(ctx context.Context, urlstr string) (*Topic, error) { + opener, u, err := mux.topicSchemes.FromString("Topic", urlstr) + if err != nil { + return nil, err + } + return opener.(TopicURLOpener).OpenTopicURL(ctx, u) +} + +// OpenSubscription calls OpenSubscriptionURL with the URL parsed from urlstr. +// OpenSubscription is safe to call from multiple goroutines. +func (mux *URLMux) OpenSubscription(ctx context.Context, urlstr string) (*Subscription, error) { + opener, u, err := mux.subscriptionSchemes.FromString("Subscription", urlstr) + if err != nil { + return nil, err + } + return opener.(SubscriptionURLOpener).OpenSubscriptionURL(ctx, u) +} + +// OpenTopicURL dispatches the URL to the opener that is registered with the +// URL's scheme. OpenTopicURL is safe to call from multiple goroutines. +func (mux *URLMux) OpenTopicURL(ctx context.Context, u *url.URL) (*Topic, error) { + opener, err := mux.topicSchemes.FromURL("Topic", u) + if err != nil { + return nil, err + } + return opener.(TopicURLOpener).OpenTopicURL(ctx, u) +} + +// OpenSubscriptionURL dispatches the URL to the opener that is registered with the +// URL's scheme. OpenSubscriptionURL is safe to call from multiple goroutines. +func (mux *URLMux) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*Subscription, error) { + opener, err := mux.subscriptionSchemes.FromURL("Subscription", u) + if err != nil { + return nil, err + } + return opener.(SubscriptionURLOpener).OpenSubscriptionURL(ctx, u) +} + +var defaultURLMux = &URLMux{} + +// DefaultURLMux returns the URLMux used by OpenTopic and OpenSubscription. +// +// Driver packages can use this to register their TopicURLOpener and/or +// SubscriptionURLOpener on the mux. +func DefaultURLMux() *URLMux { + return defaultURLMux +} + +// OpenTopic opens the Topic identified by the URL given. +// See the URLOpener documentation in driver subpackages for +// details on supported URL formats, and https://gocloud.dev/concepts/urls +// for more information. +func OpenTopic(ctx context.Context, urlstr string) (*Topic, error) { + return defaultURLMux.OpenTopic(ctx, urlstr) +} + +// OpenSubscription opens the Subscription identified by the URL given. +// See the URLOpener documentation in driver subpackages for +// details on supported URL formats, and https://gocloud.dev/concepts/urls +// for more information. +func OpenSubscription(ctx context.Context, urlstr string) (*Subscription, error) { + return defaultURLMux.OpenSubscription(ctx, urlstr) +} diff --git a/go-cloud/pubsub/pubsub_test.go b/go-cloud/pubsub/pubsub_test.go new file mode 100644 index 000000000..1bf783d16 --- /dev/null +++ b/go-cloud/pubsub/pubsub_test.go @@ -0,0 +1,782 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 pubsub + +import ( + "context" + "errors" + "fmt" + "net/url" + "strings" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/oteltest" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/batcher" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" +) + +type driverTopic struct { + driver.Topic + subs []*driverSub +} + +func (t *driverTopic) SendBatch(ctx context.Context, ms []*driver.Message) error { + for _, s := range t.subs { + select { + case <-s.sem: + s.q = append(s.q, ms...) + s.sem <- struct{}{} + case <-ctx.Done(): + return ctx.Err() + } + } + return nil +} + +func (*driverTopic) IsRetryable(error) bool { return false } +func (*driverTopic) ErrorCode(error) gcerrors.ErrorCode { return gcerrors.Unknown } +func (*driverTopic) Close() error { return nil } + +type driverSub struct { + driver.Subscription + sem chan struct{} + // Normally this queue would live on a separate server in the cloud. + q []*driver.Message +} + +func NewDriverSub() *driverSub { + ds := &driverSub{ + sem: make(chan struct{}, 1), + } + ds.sem <- struct{}{} + return ds +} + +func (s *driverSub) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + for { + select { + case <-s.sem: + ms := s.grabQueue(maxMessages) + if len(ms) != 0 { + return ms, nil + } + case <-ctx.Done(): + return nil, ctx.Err() + } + } +} + +func (s *driverSub) grabQueue(maxMessages int) []*driver.Message { + defer func() { s.sem <- struct{}{} }() + if len(s.q) > 0 { + if len(s.q) <= maxMessages { + ms := s.q + s.q = nil + return ms + } + ms := s.q[:maxMessages] + s.q = s.q[maxMessages:] + return ms + } + return nil +} + +func (s *driverSub) SendAcks(ctx context.Context, ackIDs []driver.AckID) error { + return nil +} + +func (*driverSub) IsRetryable(error) bool { return false } +func (*driverSub) ErrorCode(error) gcerrors.ErrorCode { return gcerrors.Internal } +func (*driverSub) CanNack() bool { return false } +func (*driverSub) Close() error { return nil } + +func TestSendReceive(t *testing.T) { + ctx := context.Background() + ds := NewDriverSub() + dt := &driverTopic{ + subs: []*driverSub{ds}, + } + topic := NewTopic(dt, nil) + defer topic.Shutdown(ctx) + m := &Message{LoggableID: "foo", Body: []byte("user signed up")} + if err := topic.Send(ctx, m); err == nil { + t.Fatalf("expected a Send with a non-empty LoggableID to fail") + } + m.LoggableID = "" + if err := topic.Send(ctx, m); err != nil { + t.Fatal(err) + } + + sub := NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + m2, err := sub.Receive(ctx) + if err != nil { + t.Fatal(err) + } + if string(m2.Body) != string(m.Body) { + t.Fatalf("received message has body %q, want %q", m2.Body, m.Body) + } + m2.Ack() +} + +func TestConcurrentReceivesGetAllTheMessages(t *testing.T) { + howManyToSend := int(1e3) + ctx, cancel := context.WithCancel(context.Background()) + dt := &driverTopic{} + + // wg is used to wait until all messages are received. + var wg sync.WaitGroup + wg.Add(howManyToSend) + + // Make a subscription. + ds := NewDriverSub() + dt.subs = append(dt.subs, ds) + s := NewSubscription(ds, nil, nil) + defer s.Shutdown(ctx) + + // Start 10 goroutines to receive from it. + var mu sync.Mutex + receivedMsgs := make(map[string]bool) + for i := 0; i < 10; i++ { + go func() { + for { + m, err := s.Receive(ctx) + if err != nil { + // Permanent error; ctx cancelled or subscription closed is + // expected once we've received all the messages. + mu.Lock() + n := len(receivedMsgs) + mu.Unlock() + if n != howManyToSend { + t.Errorf("Worker's Receive failed before all messages were received (%d)", n) + } + return + } + m.Ack() + mu.Lock() + receivedMsgs[string(m.Body)] = true + mu.Unlock() + wg.Done() + } + }() + } + + // Send messages. Each message has a unique body used as a key to receivedMsgs. + topic := NewTopic(dt, nil) + defer topic.Shutdown(ctx) + for i := 0; i < howManyToSend; i++ { + key := fmt.Sprintf("message #%d", i) + m := &Message{Body: []byte(key)} + if err := topic.Send(ctx, m); err != nil { + t.Fatal(err) + } + } + + // Wait for the goroutines to receive all of the messages, then cancel the + // ctx so they all exit. + wg.Wait() + defer cancel() + + // Check that all the messages were received. + for i := 0; i < howManyToSend; i++ { + key := fmt.Sprintf("message #%d", i) + if !receivedMsgs[key] { + t.Errorf("message %q was not received", key) + } + } +} + +func TestCancelSend(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + ds := NewDriverSub() + dt := &driverTopic{ + subs: []*driverSub{ds}, + } + topic := NewTopic(dt, nil) + defer topic.Shutdown(ctx) + m := &Message{} + + // Intentionally break the driver subscription by acquiring its semaphore. + // Now topic.Send will have to wait for cancellation. + <-ds.sem + + cancel() + if err := topic.Send(ctx, m); err == nil { + t.Error("got nil, want cancellation error") + } +} + +func TestCancelReceive(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + ds := NewDriverSub() + s := NewSubscription(ds, nil, nil) + defer s.Shutdown(ctx) + cancel() + // Without cancellation, this Receive would hang. + if _, err := s.Receive(ctx); err == nil { + t.Error("got nil, want cancellation error") + } +} + +type blockingDriverSub struct { + driver.Subscription + inReceiveBatch chan struct{} +} + +func (b blockingDriverSub) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + b.inReceiveBatch <- struct{}{} + <-ctx.Done() + return nil, ctx.Err() +} +func (blockingDriverSub) CanNack() bool { return false } +func (blockingDriverSub) IsRetryable(error) bool { return false } +func (blockingDriverSub) Close() error { return nil } + +func TestCancelTwoReceives(t *testing.T) { + // We want to create the following situation: + // 1. Goroutine 1 calls Receive, obtains the lock (Subscription.mu), + // then releases the lock and calls driver.ReceiveBatch, which hangs. + // 2. Goroutine 2 calls Receive. + // 3. The context passed to the Goroutine 2 call is canceled. + // We expect Goroutine 2's Receive to exit immediately. That won't + // happen if Receive holds the lock during the call to ReceiveBatch. + inReceiveBatch := make(chan struct{}) + s := NewSubscription(blockingDriverSub{inReceiveBatch: inReceiveBatch}, nil, nil) + defer s.Shutdown(context.Background()) + go func() { + _, err := s.Receive(context.Background()) + // This should happen at the very end of the test, during Shutdown. + if err != context.Canceled { + t.Errorf("got %v, want context.Canceled", err) + } + }() + <-inReceiveBatch + // Give the Receive call time to block on the mutex before timing out. + ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) + defer cancel() + errc := make(chan error) + go func() { + _, err := s.Receive(ctx) + errc <- err + }() + err := <-errc + if err != context.DeadlineExceeded { + t.Errorf("got %v, want context.DeadlineExceeded", err) + } +} + +type secondReceiveBlockedDriverSub struct { + driver.Subscription + receiveCounter atomic.Uint64 +} + +func (s *secondReceiveBlockedDriverSub) ReceiveBatch(ctx context.Context, _ int) ([]*driver.Message, error) { + // The first request will return a message right away. + // The second one will block ~forever. + if n := s.receiveCounter.Add(1); n > 1 { + <-ctx.Done() + } + msg := &driver.Message{Body: []byte(fmt.Sprintf("message #%d", s.receiveCounter.Load()))} + return []*driver.Message{msg}, nil +} +func (*secondReceiveBlockedDriverSub) CanNack() bool { return false } +func (*secondReceiveBlockedDriverSub) SendAcks(_ context.Context, _ []driver.AckID) error { return nil } +func (*secondReceiveBlockedDriverSub) IsRetryable(error) bool { return false } +func (*secondReceiveBlockedDriverSub) Close() error { return nil } + +// TestIndependentBatchReturn verifies that when multiple batch requests are sent, +// as long as one of them succeeds it should not block Subscription.Receive. +func TestIndependentBatchReturn(t *testing.T) { + s := NewSubscription( + &secondReceiveBlockedDriverSub{}, + &batcher.Options{MaxBatchSize: 1, MaxHandlers: 2}, // force 2 batches by allowing 2 handlers and 1 msg per batch + nil, + ) + ctx := context.Background() + defer s.Shutdown(ctx) + + // Set the batch size to force 2 batches to be called. + s.runningBatchSize = 2 + ctxTimeout, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + m, err := s.Receive(ctxTimeout) + if err != nil { + t.Fatal("Receive should not fail", err) + return + } + m.Ack() +} + +func TestRetryTopic(t *testing.T) { + // Test that Send is retried if the driver returns a retryable error. + ctx := context.Background() + ft := &failTopic{} + topic := NewTopic(ft, nil) + defer topic.Shutdown(ctx) + err := topic.Send(ctx, &Message{}) + if err != nil { + t.Errorf("Send: got %v, want nil", err) + } + if got, want := ft.calls, nRetryCalls+1; got != want { + t.Errorf("calls: got %d, want %d", got, want) + } +} + +var errRetry = errors.New("retry") + +func isRetryable(err error) bool { + return err == errRetry +} + +const nRetryCalls = 2 + +// failTopic helps test retries for SendBatch. +// +// SendBatch will fail nRetryCall times before succeeding. +type failTopic struct { + driver.Topic + calls int +} + +func (t *failTopic) SendBatch(ctx context.Context, ms []*driver.Message) error { + t.calls++ + if t.calls <= nRetryCalls { + return errRetry + } + return nil +} + +func (*failTopic) IsRetryable(err error) bool { return isRetryable(err) } +func (*failTopic) ErrorCode(error) gcerrors.ErrorCode { return gcerrors.Unknown } +func (*failTopic) Close() error { return nil } + +func TestRetryReceive(t *testing.T) { + ctx := context.Background() + fs := &failSub{fail: true} + sub := NewSubscription(fs, nil, nil) + defer sub.Shutdown(ctx) + m, err := sub.Receive(ctx) + if err != nil { + t.Fatalf("Receive: got %v, want nil", err) + } + m.Ack() + if got, want := fs.calls, nRetryCalls+1; got != want { + t.Errorf("calls: got %d, want %d", got, want) + } +} + +// TestBatchSizeDecay verifies that the batch size decays when no messages are available. +// (see https://github.com/google/go-cloud/issues/2849). +func TestBatchSizeDecays(t *testing.T) { + ctx := context.Background() + fs := &failSub{} + // Allow multiple handlers and cap max batch size to ensure we get concurrency. + sub := NewSubscription(fs, &batcher.Options{MaxHandlers: 10, MaxBatchSize: 2}, nil) + defer sub.Shutdown(ctx) + + // Records the last batch size. + var mu sync.Mutex + lastMaxMessages := 0 + sub.preReceiveBatchHook = func(maxMessages int) { + mu.Lock() + defer mu.Unlock() + lastMaxMessages = maxMessages + } + + // Do some receives to allow the number of batches to increase past 1. + for n := 0; n < 100; n++ { + m, err := sub.Receive(ctx) + if err != nil { + t.Fatalf("Receive: got %v, want nil", err) + } + m.Ack() + } + + // Tell the failSub to start returning no messages. + fs.mu.Lock() + fs.empty = true + fs.mu.Unlock() + + mu.Lock() + highWaterMarkBatchSize := lastMaxMessages + if lastMaxMessages <= 1 { + t.Fatal("max messages wasn't greater than 1") + } + mu.Unlock() + + // Make a bunch of calls to Receive to drain any outstanding + // messages, and wait some extra time during which we should + // continue polling, and the batch size should decay. + for { + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + m, err := sub.Receive(ctx) + if err != nil { + // Expected: no more messages, and timed out. + break + } + // Drained a message. + m.Ack() + } + + // Verify that the batch size decayed. + mu.Lock() + if lastMaxMessages >= highWaterMarkBatchSize { + t.Fatalf("wanted batch size to decay; high water mark was %d, now %d", highWaterMarkBatchSize, lastMaxMessages) + } + mu.Unlock() +} + +// TestRetryReceiveBatches verifies that batching and retries work without races +// (see https://github.com/google/go-cloud/issues/2676). +func TestRetryReceiveInBatchesDoesntRace(t *testing.T) { + ctx := context.Background() + fs := &failSub{} + // Allow multiple handlers and cap max batch size to ensure we get concurrency. + sub := NewSubscription(fs, &batcher.Options{MaxHandlers: 10, MaxBatchSize: 2}, nil) + defer sub.Shutdown(ctx) + + // Do some receives to allow the number of batches to increase past 1. + for n := 0; n < 100; n++ { + m, err := sub.Receive(ctx) + if err != nil { + t.Fatalf("Receive: got %v, want nil", err) + } + m.Ack() + } + // Tell the failSub to start failing. + fs.mu.Lock() + fs.fail = true + fs.mu.Unlock() + + // This call to Receive should result in nRetryCalls+1 calls to ReceiveBatch for + // each batch. In the issue noted above, this would cause a race. + for n := 0; n < 100; n++ { + m, err := sub.Receive(ctx) + if err != nil { + t.Fatalf("Receive: got %v, want nil", err) + } + m.Ack() + } + // Don't try to verify the exact number of calls, as it is unpredictable + // based on the timing of the batching. +} + +// failSub helps test retries for ReceiveBatch. +// +// Once start=true, ReceiveBatch will fail nRetryCalls times before succeeding. +type failSub struct { + driver.Subscription + fail bool + empty bool + calls int + mu sync.Mutex +} + +func (t *failSub) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + t.mu.Lock() + defer t.mu.Unlock() + if t.fail { + t.calls++ + if t.calls <= nRetryCalls { + return nil, errRetry + } + } + if t.empty { + t.calls++ + return nil, nil + } + return []*driver.Message{{Body: []byte("")}}, nil +} + +func (*failSub) SendAcks(ctx context.Context, ackIDs []driver.AckID) error { return nil } +func (*failSub) IsRetryable(err error) bool { return isRetryable(err) } +func (*failSub) CanNack() bool { return false } +func (*failSub) Close() error { return nil } + +// TODO(jba): add a test for retry of SendAcks. + +var errDriver = errors.New("driver error") + +type erroringTopic struct { + driver.Topic +} + +func (erroringTopic) SendBatch(context.Context, []*driver.Message) error { return errDriver } +func (erroringTopic) IsRetryable(err error) bool { return isRetryable(err) } +func (erroringTopic) ErrorCode(error) gcerrors.ErrorCode { return gcerrors.AlreadyExists } +func (erroringTopic) Close() error { return errDriver } + +type erroringSubscription struct { + driver.Subscription +} + +func (erroringSubscription) ReceiveBatch(context.Context, int) ([]*driver.Message, error) { + return nil, errDriver +} + +func (erroringSubscription) SendAcks(context.Context, []driver.AckID) error { return errDriver } +func (erroringSubscription) IsRetryable(err error) bool { return isRetryable(err) } +func (erroringSubscription) ErrorCode(error) gcerrors.ErrorCode { return gcerrors.AlreadyExists } +func (erroringSubscription) CanNack() bool { return false } +func (erroringSubscription) Close() error { return errDriver } + +// TestErrorsAreWrapped tests that all errors returned from the driver are +// wrapped exactly once by the portable type. +func TestErrorsAreWrapped(t *testing.T) { + ctx := context.Background() + + verify := func(err error) { + t.Helper() + if err == nil { + t.Errorf("got nil error, wanted non-nil") + return + } + if e, ok := err.(*gcerr.Error); !ok { + t.Errorf("not wrapped: %v", err) + } else if got := e.Unwrap(); got != errDriver { + t.Errorf("got %v for wrapped error, not errDriver", got) + } + if s := err.Error(); !strings.HasPrefix(s, "pubsub ") { + t.Errorf("Error() for wrapped error doesn't start with 'pubsub': prefix: %s", s) + } + } + + topic := NewTopic(erroringTopic{}, nil) + verify(topic.Send(ctx, &Message{})) + err := topic.Shutdown(ctx) + verify(err) + + sub := NewSubscription(erroringSubscription{}, nil, nil) + _, err = sub.Receive(ctx) + verify(err) + err = sub.Shutdown(ctx) + verify(err) +} + +// TestOpenTelemetry tests that OpenTelemetry tracing is working correctly. +func TestOpenTelemetry(t *testing.T) { + ctx := context.Background() + + te := oteltest.NewTestExporter(t, OpenTelemetryViews) + defer func() { + err := te.Shutdown(ctx) + if err != nil { + t.Logf("Error shutting down test exporter: %v", err) + } + }() + + ds := NewDriverSub() + dt := &driverTopic{ + subs: []*driverSub{ds}, + } + topic := NewTopic(dt, nil) + defer topic.Shutdown(ctx) + sub := NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + if err := topic.Send(ctx, &Message{Body: []byte("x")}); err != nil { + t.Fatal(err) + } + if err := topic.Shutdown(ctx); err != nil { + t.Fatal(err) + } + msg, err := sub.Receive(ctx) + if err != nil { + t.Fatal(err) + } + msg.Ack() + err = sub.Shutdown(ctx) + if err != nil { + t.Fatal(err) + } + _, _ = sub.Receive(ctx) + + spans := te.GetSpans() + metrics := te.GetMetrics(ctx) + + diff := oteltest.Diff(spans.Snapshots(), metrics, pkgName, "gocloud.dev/pubsub", []oteltest.Call{ + {Method: "driver.Topic.SendBatch", Code: gcerrors.OK}, + {Method: "Topic.Send", Code: gcerrors.OK}, + {Method: "Topic.Shutdown", Code: gcerrors.OK}, + {Method: "driver.Subscription.ReceiveBatch", Code: gcerrors.OK}, + {Method: "Subscription.Receive", Code: gcerrors.OK}, + {Method: "driver.Subscription.SendAcks", Code: gcerrors.OK}, + {Method: "Subscription.Shutdown", Code: gcerrors.OK}, + {Method: "Subscription.Receive", Code: gcerrors.FailedPrecondition}, + }) + if diff != "" { + t.Error(diff) + } +} + +func TestURLMux(t *testing.T) { + ctx := context.Background() + + mux := new(URLMux) + fake := &fakeOpener{} + mux.RegisterTopic("foo", fake) + mux.RegisterTopic("err", fake) + mux.RegisterSubscription("foo", fake) + mux.RegisterSubscription("err", fake) + + if diff := cmp.Diff(mux.TopicSchemes(), []string{"err", "foo"}); diff != "" { + t.Errorf("Schemes: %s", diff) + } + if !mux.ValidTopicScheme("foo") || !mux.ValidTopicScheme("err") { + t.Errorf("ValidTopicScheme didn't return true for valid scheme") + } + if mux.ValidTopicScheme("foo2") || mux.ValidTopicScheme("http") { + t.Errorf("ValidTopicScheme didn't return false for invalid scheme") + } + + if diff := cmp.Diff(mux.SubscriptionSchemes(), []string{"err", "foo"}); diff != "" { + t.Errorf("Schemes: %s", diff) + } + if !mux.ValidSubscriptionScheme("foo") || !mux.ValidSubscriptionScheme("err") { + t.Errorf("ValidSubscriptionScheme didn't return true for valid scheme") + } + if mux.ValidSubscriptionScheme("foo2") || mux.ValidSubscriptionScheme("http") { + t.Errorf("ValidSubscriptionScheme didn't return false for invalid scheme") + } + + for _, tc := range []struct { + name string + url string + wantErr bool + }{ + { + name: "empty URL", + wantErr: true, + }, + { + name: "invalid URL", + url: ":foo", + wantErr: true, + }, + { + name: "invalid URL no scheme", + url: "foo", + wantErr: true, + }, + { + name: "unregistered scheme", + url: "bar://myps", + wantErr: true, + }, + { + name: "func returns error", + url: "err://myps", + wantErr: true, + }, + { + name: "no query options", + url: "foo://myps", + }, + { + name: "empty query options", + url: "foo://myps?", + }, + { + name: "query options", + url: "foo://myps?aAa=bBb&cCc=dDd", + }, + { + name: "multiple query options", + url: "foo://myps?x=a&x=b&x=c", + }, + { + name: "fancy ps name", + url: "foo:///foo/bar/baz", + }, + { + name: "using api schema prefix", + url: "pubsub+foo://foo", + }, + } { + t.Run("topic: "+tc.name, func(t *testing.T) { + _, gotErr := mux.OpenTopic(ctx, tc.url) + if (gotErr != nil) != tc.wantErr { + t.Fatalf("got err %v, want error %v", gotErr, tc.wantErr) + } + if gotErr != nil { + return + } + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + // Repeat with OpenTopicURL. + parsed, err := url.Parse(tc.url) + if err != nil { + t.Fatal(err) + } + _, gotErr = mux.OpenTopicURL(ctx, parsed) + if gotErr != nil { + t.Fatalf("got err %v, want nil", gotErr) + } + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + }) + t.Run("subscription: "+tc.name, func(t *testing.T) { + _, gotErr := mux.OpenSubscription(ctx, tc.url) + if (gotErr != nil) != tc.wantErr { + t.Fatalf("got err %v, want error %v", gotErr, tc.wantErr) + } + if gotErr != nil { + return + } + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + // Repeat with OpenSubscriptionURL. + parsed, err := url.Parse(tc.url) + if err != nil { + t.Fatal(err) + } + _, gotErr = mux.OpenSubscriptionURL(ctx, parsed) + if gotErr != nil { + t.Fatalf("got err %v, want nil", gotErr) + } + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + }) + } +} + +type fakeOpener struct { + u *url.URL // last url passed to OpenTopicURL/OpenSubscriptionURL +} + +func (o *fakeOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*Topic, error) { + if u.Scheme == "err" { + return nil, errors.New("fail") + } + o.u = u + return nil, nil +} + +func (o *fakeOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*Subscription, error) { + if u.Scheme == "err" { + return nil, errors.New("fail") + } + o.u = u + return nil, nil +} diff --git a/go-cloud/pubsub/rabbitpubsub/amqp.go b/go-cloud/pubsub/rabbitpubsub/amqp.go new file mode 100644 index 000000000..f85d3c2e4 --- /dev/null +++ b/go-cloud/pubsub/rabbitpubsub/amqp.go @@ -0,0 +1,179 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 rabbitpubsub + +// Interfaces for the AMQP protocol, and adapters for the real amqp client. +// Fake implementations of the interfaces are in fake_test.go + +import ( + "context" + + amqp "github.com/rabbitmq/amqp091-go" +) + +// Values we use for the amqp client. +// See https://www.rabbitmq.com/amqp-0-9-1-reference.html. +const ( + // Many methods of the amqp client take a "no-wait" parameter, which + // if true causes the client to return without waiting for a server + // response. We always want to wait. + wait = false + + // If the message can't be enqueued, return it to the sender rather than silently + // dropping it. + mandatory = true + + // If there are no waiting consumers, enqueue the message instead of dropping it. + immediate = false +) + +// See https://pkg.go.dev/github.com/rabbitmq/amqp091-go#Connection for the documentation of these methods. +type amqpConnection interface { + Channel() (amqpChannel, error) + Close() error +} + +// See https://pkg.go.dev/github.com/rabbitmq/amqp091-go#Channel for the documentation of these methods. +type amqpChannel interface { + Publish(exchange, routingKey string, msg amqp.Publishing) error + PublishWithContext(ctx context.Context, exchange, routingKey string, msg amqp.Publishing) error + Consume(queue, consumer string) (<-chan amqp.Delivery, error) + Ack(tag uint64) error + Nack(tag uint64) error + Cancel(consumer string) error + Close() error + NotifyPublish(chan amqp.Confirmation) chan amqp.Confirmation + NotifyReturn(chan amqp.Return) chan amqp.Return + NotifyClose(chan *amqp.Error) chan *amqp.Error + ExchangeDeclare(string) error + QueueDeclareAndBind(qname, ename string) error + ExchangeDelete(string) error + QueueDelete(qname string) error + Qos(prefetchCount, prefetchSize int, global bool) error +} + +// connection adapts an *amqp.Connection to the amqpConnection interface. +type connection struct { + conn *amqp.Connection +} + +// Channel creates a new channel. We always want the channel in confirm mode (where +// confirmations are delivered for each publish), so we do that here as well. +func (c *connection) Channel() (amqpChannel, error) { + ch, err := c.conn.Channel() + if err != nil { + return nil, err + } + if err := ch.Confirm(wait); err != nil { + return nil, err + } + + return &channel{ch}, nil +} + +func (c *connection) Close() error { + return c.conn.Close() +} + +// channel adapts an *amqp.Channel to the amqpChannel interface. +type channel struct { + ch *amqp.Channel +} + +func (ch *channel) Publish(exchange, routingKey string, msg amqp.Publishing) error { + return ch.PublishWithContext(context.Background(), exchange, routingKey, msg) +} + +func (ch *channel) PublishWithContext(ctx context.Context, exchange, routingKey string, msg amqp.Publishing) error { + return ch.ch.PublishWithContext(ctx, exchange, routingKey, mandatory, immediate, msg) +} + +func (ch *channel) Consume(queue, consumer string) (<-chan amqp.Delivery, error) { + return ch.ch.Consume(queue, consumer, + false, // autoAck + false, // exclusive + false, // noLocal + wait, + nil) // args +} + +func (ch *channel) Ack(tag uint64) error { + return ch.ch.Ack(tag, false) // multiple=false: acking only this ID +} + +func (ch *channel) Nack(tag uint64) error { + return ch.ch.Nack(tag, false, true) // multiple=false: acking only this ID, requeue: true to redeliver +} + +func (ch *channel) Confirm() error { + return ch.ch.Confirm(wait) +} + +func (ch *channel) Cancel(consumer string) error { + return ch.ch.Cancel(consumer, wait) +} + +func (ch *channel) Close() error { + return ch.ch.Close() +} + +func (ch *channel) NotifyPublish(c chan amqp.Confirmation) chan amqp.Confirmation { + return ch.ch.NotifyPublish(c) +} + +func (ch *channel) NotifyReturn(c chan amqp.Return) chan amqp.Return { + return ch.ch.NotifyReturn(c) +} + +func (ch *channel) NotifyClose(c chan *amqp.Error) chan *amqp.Error { + return ch.ch.NotifyClose(c) +} + +func (ch *channel) ExchangeDeclare(name string) error { + return ch.ch.ExchangeDeclare(name, + amqp.ExchangeFanout, // kind + false, // durable + false, // delete when unused + false, // internal + wait, + nil) // args +} + +// QueueDeclareAndBind declares a queue and binds it to an exchange. +func (ch *channel) QueueDeclareAndBind(queueName, exchangeName string) error { + q, err := ch.ch.QueueDeclare(queueName, + false, // durable + false, // delete when unused + false, // exclusive + wait, + nil) // args + if err != nil { + return err + } + return ch.ch.QueueBind(q.Name, q.Name, exchangeName, wait, nil) +} + +func (ch *channel) ExchangeDelete(name string) error { + return ch.ch.ExchangeDelete(name, false, false) +} + +func (ch *channel) QueueDelete(qname string) error { + _, err := ch.ch.QueueDelete(qname, false, false, false) + return err +} + +func (ch *channel) Qos(prefetchCount, prefetchSize int, global bool) error { + return ch.ch.Qos(prefetchCount, prefetchSize, global) +} diff --git a/go-cloud/pubsub/rabbitpubsub/doc.go b/go-cloud/pubsub/rabbitpubsub/doc.go new file mode 100644 index 000000000..86fcd3342 --- /dev/null +++ b/go-cloud/pubsub/rabbitpubsub/doc.go @@ -0,0 +1,54 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 rabbitpubsub provides an pubsub implementation for RabbitMQ. +// Use OpenTopic to construct a *pubsub.Topic, and/or OpenSubscription +// to construct a *pubsub.Subscription. +// +// RabbitMQ follows the AMQP specification, which uses different terminology +// than the Go CDK Pub/Sub. +// +// A Pub/Sub topic is an AMQP exchange. The exchange kind should be "fanout" to match +// the Pub/Sub model, although publishing will work with any kind of exchange. +// +// A Pub/Sub subscription is an AMQP queue. The queue should be bound to the exchange +// that is the topic of the subscription. See the package example for details. +// +// # URLs +// +// For pubsub.OpenTopic and pubsub.OpenSubscription, rabbitpubsub registers +// for the scheme "rabbit". +// The default URL opener will connect to a default server based on the +// environment variable "RABBIT_SERVER_URL". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # Message Delivery Semantics +// +// RabbitMQ supports at-least-once semantics; applications must +// call Message.Ack after processing a message, or it will be redelivered. +// See https://godoc.org/gocloud.dev/pubsub#hdr-At_most_once_and_At_least_once_Delivery +// for more background. +// +// # As +// +// rabbitpubsub exposes the following types for As: +// - Topic: *amqp.Connection +// - Subscription: *amqp.Connection +// - Message.BeforeSend: *amqp.Publishing +// - Message.AfterSend: None +// - Message: amqp.Delivery +// - Error: *amqp.Error and MultiError +package rabbitpubsub // import "gocloud.dev/pubsub/rabbitpubsub" diff --git a/go-cloud/pubsub/rabbitpubsub/example_test.go b/go-cloud/pubsub/rabbitpubsub/example_test.go new file mode 100644 index 000000000..6c9a0c461 --- /dev/null +++ b/go-cloud/pubsub/rabbitpubsub/example_test.go @@ -0,0 +1,84 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 rabbitpubsub_test + +import ( + "context" + "log" + + amqp "github.com/rabbitmq/amqp091-go" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/rabbitpubsub" +) + +func ExampleOpenTopic() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + rabbitConn, err := amqp.Dial("amqp://guest:guest@localhost:5672/") + if err != nil { + log.Fatal(err) + } + defer rabbitConn.Close() + topic := rabbitpubsub.OpenTopic(rabbitConn, "myexchange", nil) + defer topic.Shutdown(ctx) +} + +func ExampleOpenSubscription() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + rabbitConn, err := amqp.Dial("amqp://guest:guest@localhost:5672/") + if err != nil { + log.Fatal(err) + } + defer rabbitConn.Close() + subscription := rabbitpubsub.OpenSubscription(rabbitConn, "myqueue", nil) + defer subscription.Shutdown(ctx) +} + +func Example_openTopicFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/rabbitpubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenTopic creates a *pubsub.Topic from a URL. + // This URL will Dial the RabbitMQ server at the URL in the environment + // variable RABBIT_SERVER_URL and open the exchange "myexchange". + topic, err := pubsub.OpenTopic(ctx, "rabbit://myexchange") + if err != nil { + log.Fatal(err) + } + defer topic.Shutdown(ctx) +} + +func Example_openSubscriptionFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/pubsub/rabbitpubsub" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // pubsub.OpenSubscription creates a *pubsub.Subscription from a URL. + // This URL will Dial the RabbitMQ server at the URL in the environment + // variable RABBIT_SERVER_URL and open the queue "myqueue". + subscription, err := pubsub.OpenSubscription(ctx, "rabbit://myqueue") + if err != nil { + log.Fatal(err) + } + defer subscription.Shutdown(ctx) +} diff --git a/go-cloud/pubsub/rabbitpubsub/fake_test.go b/go-cloud/pubsub/rabbitpubsub/fake_test.go new file mode 100644 index 000000000..52efa95a0 --- /dev/null +++ b/go-cloud/pubsub/rabbitpubsub/fake_test.go @@ -0,0 +1,426 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 rabbitpubsub + +// This file implements a fake for the parts of the AMQP protocol used by our RabbitMQ +// implementation. + +import ( + "context" + "fmt" + "sync" + "time" + + amqp "github.com/rabbitmq/amqp091-go" +) + +// fakeConnection implements the amqpConnection interface. +// It also doubles as the state of the fake server. +type fakeConnection struct { + mu sync.Mutex + closed chan struct{} + exchanges map[string]*exchange // exchange names are server-scoped + queues map[string]*queue // queue names are server-scoped +} + +// fakeChannel implements the amqpChannel interface. +type fakeChannel struct { + conn *fakeConnection + // The following fields are protected by conn.mu. + deliveryTag uint64 // counter; used to distinguish published messages + pubChans []chan<- amqp.Confirmation + returnChans []chan<- amqp.Return + closeChans []chan<- *amqp.Error + consumerCancels map[string]func() // from consumer name to cancel func for the context + + closeMu sync.Mutex + closed chan struct{} +} + +// An exchange is a collection of queues. +// Every queue is also in the fakeConnection.queues map, so they can be looked up +// by name. An exchange needs a list of its own queues (the ones bound to it) so +// it can deliver incoming messages to them. +type exchange struct { + queues []*queue +} + +// A queue holds a set of messages to be delivered. +type queue struct { + messages []amqp.Delivery + pendingAck map[uint64]amqp.Delivery +} + +func newFakeConnection() *fakeConnection { + return &fakeConnection{ + exchanges: map[string]*exchange{}, + queues: map[string]*queue{}, + closed: make(chan struct{}), + } +} + +// Channel creates a new AMQP fake channel. +func (c *fakeConnection) Channel() (amqpChannel, error) { + if chanIsClosed(c.closed) { + return nil, amqp.ErrClosed + } + return &fakeChannel{ + conn: c, + consumerCancels: map[string]func(){}, + closed: make(chan struct{}), + }, nil +} + +func (c *fakeConnection) Close() error { + c.mu.Lock() + defer c.mu.Unlock() + closeChan(c.closed) + return nil +} + +// getExchange returns the named exchange, or error if it doesn't exist. +// It closes the channel on error. +// It must be called with the lock held. +func (ch *fakeChannel) getExchange(name string) (*exchange, error) { + if ex := ch.conn.exchanges[name]; ex != nil { + return ex, nil + } + return nil, ch.errorf(amqp.NotFound, "exchange %q not found", name) +} + +// errorf returns an amqp.Error and closes the channel. (In the AMQP protocol, any channel error +// closes the channel and makes it unusable.) +// It must be called with ch.conn.mu held. +func (ch *fakeChannel) errorf(code int, reasonFormat string, args ...any) error { + _ = ch.Close() + return &amqp.Error{Code: code, Reason: fmt.Sprintf(reasonFormat, args...)} +} + +// Report whether the channel or its connection is closed. Does not require the lock. +func (ch *fakeChannel) isClosed() bool { + return chanIsClosed(ch.closed) || chanIsClosed(ch.conn.closed) +} + +// ExchangeDeclare creates a new exchange with the given name if one doesn't already +// exist. +func (ch *fakeChannel) ExchangeDeclare(name string) error { + if ch.isClosed() { + return amqp.ErrClosed + } + + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + + if _, ok := ch.conn.exchanges[name]; !ok { + ch.conn.exchanges[name] = &exchange{} + } + return nil +} + +// QueueDeclareAndBind binds a queue to the given exchange. +// The exchange must exist. +// If the queue doesn't exist, it's created. +func (ch *fakeChannel) QueueDeclareAndBind(queueName, exchangeName string) error { + if ch.isClosed() { + return amqp.ErrClosed + } + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + + ex, err := ch.getExchange(exchangeName) + if err != nil { + return err + } + if _, ok := ch.conn.queues[queueName]; ok { + return nil + } + q := &queue{pendingAck: map[uint64]amqp.Delivery{}} + ch.conn.queues[queueName] = q + ex.queues = append(ex.queues, q) + return nil +} + +func (ch *fakeChannel) Publish(exchangeName, routingKey string, pub amqp.Publishing) error { + return ch.PublishWithContext(context.Background(), exchangeName, routingKey, pub) +} + +func (ch *fakeChannel) PublishWithContext(ctx context.Context, + exchangeName, routingKey string, + pub amqp.Publishing, +) error { + if ch.isClosed() { + return amqp.ErrClosed + } + + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + + ex, err := ch.getExchange(exchangeName) + if err != nil { + return err + } + if len(ex.queues) == 0 { + // The message is unroutable. Send a Return to all channels registered with + // NotifyReturn. + ret := amqp.Return{ + Exchange: exchangeName, + ReplyCode: amqp.NoRoute, + ReplyText: "NO_ROUTE: no queues bound to exchange", + RoutingKey: routingKey, + } + for _, c := range ch.returnChans { + select { + case c <- ret: + case <-ch.closed: + return amqp.ErrClosed + case <-ch.conn.closed: + return amqp.ErrClosed + } + } + } else { + // Each published message in the channel gets a new delivery tag, starting at 1. + ch.deliveryTag++ + // Convert the Publishing into a Delivery. + del := amqp.Delivery{ + Headers: pub.Headers, + Body: pub.Body, + DeliveryTag: ch.deliveryTag, + // We don't care about the other fields. + } + // All exchanges are "fanout" exchanges, so the message is sent to all queues. + for _, q := range ex.queues { + q.messages = append(q.messages, del) + } + } + // Every Go channel registered with NotifyPublish gets a confirmation message. + // Ack is true even if the message was unroutable. + for _, c := range ch.pubChans { + select { + case c <- amqp.Confirmation{DeliveryTag: ch.deliveryTag, Ack: true}: + case <-ch.closed: + return amqp.ErrClosed + case <-ch.conn.closed: + return amqp.ErrClosed + } + } + return nil +} + +// Consume starts a consumer that reads from the given queue. +// The consumerName can be used in a Cancel call to stop the consumer. +func (ch *fakeChannel) Consume(queueName, consumerName string) (<-chan amqp.Delivery, error) { + if ch.isClosed() { + return nil, amqp.ErrClosed + } + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + + q, ok := ch.conn.queues[queueName] + if !ok { + return nil, ch.errorf(amqp.NotFound, "queue %q not found", queueName) + } + if _, ok := ch.consumerCancels[consumerName]; ok { + return nil, ch.errorf(amqp.PreconditionFailed, "consumer %q already exists", consumerName) + } + ctx, cancel := context.WithCancel(context.Background()) + ch.consumerCancels[consumerName] = cancel // used by fakeChannel.Cancel + delc := make(chan amqp.Delivery) + go func() { + // For this simple fake, just deliver one message every once in a while if + // any are available, until the consumer is canceled. + for { + m, ok := ch.takeOneMessage(q) + if ok { + select { + case delc <- m: + case <-ctx.Done(): + // ignore errors here and below + return + case <-ch.closed: + return + case <-ch.conn.closed: + return + } + } + select { + case <-time.After(10 * time.Millisecond): + case <-ctx.Done(): + // ignore error + return + } + } + }() + return delc, nil +} + +// Take a message from q, if one is available. We just remove +// the message from the queue permanently. In a more sophisticated implementation +// we'd mark it as outstanding and keep it around until it got acked, but we don't +// need acks for this fake. +func (ch *fakeChannel) takeOneMessage(q *queue) (amqp.Delivery, bool) { + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + if len(q.messages) == 0 { + return amqp.Delivery{}, false + } + m := q.messages[0] + q.messages = q.messages[1:] + q.pendingAck[m.DeliveryTag] = m + return m, true +} + +// Ack removes the message from q.pendingAck. +func (ch *fakeChannel) Ack(tag uint64) error { + if ch.isClosed() { + return amqp.ErrClosed + } + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + for _, q := range ch.conn.queues { + if _, ok := q.pendingAck[tag]; ok { + delete(q.pendingAck, tag) + return nil + } + } + // No error if we couldn't find it to ack it. + return nil +} + +// Nack moves the message from q.pendingAck back to q.messages +// to be redelivered. +func (ch *fakeChannel) Nack(tag uint64) error { + if ch.isClosed() { + return amqp.ErrClosed + } + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + for _, q := range ch.conn.queues { + if m, ok := q.pendingAck[tag]; ok { + delete(q.pendingAck, tag) + q.messages = append(q.messages, m) + return nil + } + } + // No error if we couldn't find it to nack it. + return nil +} + +// Cancel stops the consumer's goroutine. +func (ch *fakeChannel) Cancel(consumerName string) error { + if ch.isClosed() { + return amqp.ErrClosed + } + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + + cancel, ok := ch.consumerCancels[consumerName] + if !ok { + return ch.errorf(amqp.NotFound, "consumer %q not found", consumerName) + } + cancel() + delete(ch.consumerCancels, consumerName) + return nil +} + +// NotifyPublish remembers its argument channel so it can be notified for every +// published message. It returns its argument. +func (ch *fakeChannel) NotifyPublish(c chan amqp.Confirmation) chan amqp.Confirmation { + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + ch.pubChans = append(ch.pubChans, c) + return c +} + +// NotifyReturn remembers its argument channel so it can be notified for every +// published message that's returned due to being unroutable. +func (ch *fakeChannel) NotifyReturn(c chan amqp.Return) chan amqp.Return { + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + ch.returnChans = append(ch.returnChans, c) + return c +} + +// NotifyClose remembers its argument channel so it can be notified when +// the channel is closed. +func (ch *fakeChannel) NotifyClose(c chan *amqp.Error) chan *amqp.Error { + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + ch.closeChans = append(ch.closeChans, c) + return c +} + +// Close marks the fakeChannel as closed and sends an error to all channels +// registered with NotifyClose. +func (ch *fakeChannel) Close() error { + if chanIsClosed(ch.conn.closed) { + return amqp.ErrClosed + } + ch.closeMu.Lock() + closeChans := ch.closeChans + closeChan(ch.closed) + ch.closeMu.Unlock() + for _, c := range closeChans { + // Don't block on notifying. + select { + case c <- amqp.ErrClosed: + default: + } + } + return nil +} + +func (ch *fakeChannel) ExchangeDelete(name string) error { + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + + delete(ch.conn.exchanges, name) + return nil +} + +func (ch *fakeChannel) QueueDelete(name string) error { + ch.conn.mu.Lock() + defer ch.conn.mu.Unlock() + + delete(ch.conn.queues, name) + return nil +} + +func (ch *fakeChannel) Qos(_, _ int, _ bool) error { + if ch.isClosed() { + return amqp.ErrClosed + } + + return nil +} + +// Assumes nothing is ever written to the channel. +func chanIsClosed(ch chan struct{}) bool { + select { + case <-ch: + return true + default: + return false + } +} + +// Avoid panic when closing a closed channel. +// Must be called with the lock held. +func closeChan(ch chan struct{}) { + select { + case <-ch: + default: + close(ch) + } +} diff --git a/go-cloud/pubsub/rabbitpubsub/go.mod b/go-cloud/pubsub/rabbitpubsub/go.mod new file mode 100644 index 000000000..e5a494068 --- /dev/null +++ b/go-cloud/pubsub/rabbitpubsub/go.mod @@ -0,0 +1,74 @@ +// Copyright 2018-2019 The Go Cloud Development Kit 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 +// +// https://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. + +module gocloud.dev/pubsub/rabbitpubsub + +go 1.24 + +require ( + github.com/rabbitmq/amqp091-go v1.10.0 + gocloud.dev v0.43.0 +) + +require ( + cloud.google.com/go/auth v0.16.3 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + cloud.google.com/go/compute/metadata v0.7.0 // indirect + github.com/aws/aws-sdk-go v1.55.7 // indirect + github.com/aws/aws-sdk-go-v2 v1.36.5 // indirect + github.com/aws/aws-sdk-go-v2/config v1.29.17 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.70 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 // indirect + github.com/aws/smithy-go v1.22.4 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/go-replayers/grpcreplay v1.3.0 // indirect + github.com/google/go-replayers/httpreplay v1.2.0 // indirect + github.com/google/martian/v3 v3.3.3 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/google/wire v0.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect + go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/sdk v1.37.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect + go.opentelemetry.io/otel/trace v1.37.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + google.golang.org/api v0.242.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 // indirect + google.golang.org/grpc v1.73.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect +) diff --git a/go-cloud/pubsub/rabbitpubsub/go.sum b/go-cloud/pubsub/rabbitpubsub/go.sum new file mode 100644 index 000000000..5df7c7dd4 --- /dev/null +++ b/go-cloud/pubsub/rabbitpubsub/go.sum @@ -0,0 +1,676 @@ +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +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.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= +cloud.google.com/go v0.121.4 h1:cVvUiY0sX0xwyxPwdSU2KsF9knOVmtRyAMt8xou0iTs= +cloud.google.com/go v0.121.4/go.mod h1:XEBchUiHFJbz4lKBZwYBDHV/rSyfFktk737TLDU089s= +cloud.google.com/go/auth v0.16.3 h1:kabzoQ9/bobUmnseYnBO6qQG7q4a/CffFRlJSxv2wCc= +cloud.google.com/go/auth v0.16.3/go.mod h1:NucRGjaXfzP1ltpcQ7On/VTZ0H4kWB5Jy+Y9Dnm76fA= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/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/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= +cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +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/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= +cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM= +cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U= +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= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.49.0 h1:5054IkbslnrMCgA2MAEPcsN3Ky+AyMpEZcii/DoySPo= +cloud.google.com/go/pubsub v1.49.0/go.mod h1:K1FswTWP+C1tI/nfi3HQecoVeFvL4HUOB1tdaNXKhUY= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.55.0 h1:NESjdAToN9u1tmhVqhXCaCwYBuvEhZLLv0gBr+2znf0= +cloud.google.com/go/storage v1.55.0/go.mod h1:ztSmTTwzsdXe5syLVS0YsbFxXuvEmEyZj7v7zChEmuY= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0= +github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2/config v1.29.17 h1:jSuiQ5jEe4SAMH6lLRMY9OVC+TqJLP5655pBGjmnjr0= +github.com/aws/aws-sdk-go-v2/config v1.29.17/go.mod h1:9P4wwACpbeXs9Pm9w1QTh6BwWwJjwYvJ1iCt5QbCXh8= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70 h1:ONnH5CM16RTXRkS8Z1qg7/s2eDOhHhaXVd72mmyv4/0= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70/go.mod h1:M+lWhhmomVGgtuPOhO85u4pEa3SmssPTdcYpP/5J/xc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 h1:KAXP9JSHO1vKGCr5f4O6WmlVKLFFXgWYAGoJosorxzU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32/go.mod h1:h4Sg6FQdexC1yYG9RDnOvLbW1a/P986++/Y/a+GyEM8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 h1:t0E6FzREdtCsiLIoLCWsYliNsRBgyGD/MCK571qk4MI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17/go.mod h1:ygpklyoaypuyDvOM5ujWGrYWpAK3h7ugnmKCU/76Ys4= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 h1:AIRJ3lfb2w/1/8wOOSqYb9fUKGwQbtysJ2H1MofRUPg= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5/go.mod h1:b7SiVprpU+iGazDUqvRSLf5XmCdn+JtT1on7uNL6Ipc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 h1:BpOxT3yhLwSJ77qIY3DoHAQjZsc4HEGfMCE4NGy3uFg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3/go.mod h1:vq/GQR1gOFLquZMSrxUK/cpvKCNVYibNyJ1m7JrU88E= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 h1:NFOJ/NXEGV4Rq//71Hs1jC/NvPs1ezajK+yQmkwnPV0= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0/go.mod h1:7ph2tGpfQvwzgistp2+zga9f+bCjlQJPkPUmMgDSD7w= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +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= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +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/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= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +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= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-replayers/grpcreplay v1.3.0 h1:1Keyy0m1sIpqstQmgz307zhiJ1pV4uIlFds5weTmxbo= +github.com/google/go-replayers/grpcreplay v1.3.0/go.mod h1:v6NgKtkijC0d3e3RW8il6Sy5sqRVUwoQa4mHOGEy8DI= +github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk= +github.com/google/go-replayers/httpreplay v1.2.0/go.mod h1:WahEFFZZ7a1P4VM1qEeHy+tME4bwyqPcwWbNlUI1Mcg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= +github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +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.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= +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/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= +github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0 h1:B+WbN9RPsvobe6q4vP6KgM8/9plR/HNjgGBrfcOlweA= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0/go.mod h1:K5zQ3TT7p2ru9Qkzk0bKtCql0RGkPj9pRjpXgZJZ+rU= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 h1:rbRJ8BBoVMsQShESYZ0FkvcITu8X8QNwJogcLUmDNNw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0/go.mod h1:ru6KHrNtNHxM4nD/vd6QrLVWgKhxPYgblq4VAtNawTQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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/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= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +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-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= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/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.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-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/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.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.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +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-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +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.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.242.0 h1:7Lnb1nfnpvbkCiZek6IXKdJ0MFuAZNAJKQfA1ws62xg= +google.golang.org/api v0.242.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= +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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +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= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 h1:Nt6z9UHqSlIdIGJdz6KhTIs2VRx/iOsA5iE8bmQNcxs= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79/go.mod h1:kTmlBHMPqR5uCZPBvwa2B18mvubkjyY3CRLI0c6fj0s= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79 h1:iOye66xuaAK0WnkPuhQPUFy8eJcmwUXqGGP3om6IxX8= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79/go.mod h1:HKJDgKsFUnv5VAGeQjz8kxcgDP0HoE0iZNp0OdZNlhE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 h1:1ZwqphdOdWYXsUHgMpU/101nCtf/kSp9hOrcvFsnl10= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +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.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/go-cloud/pubsub/rabbitpubsub/localrabbit.sh b/go-cloud/pubsub/rabbitpubsub/localrabbit.sh new file mode 100755 index 000000000..81aad979b --- /dev/null +++ b/go-cloud/pubsub/rabbitpubsub/localrabbit.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Starts a local RabbitMQ instance via Docker. + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +set -euo pipefail + +echo "Starting RabbitMQ..." +docker rm -f rabbit &> /dev/null || : +docker run -d --name rabbit -p 5672:5672 rabbitmq:3.10.17 &> /dev/null +echo Sleeping to give RabbitMQ some time to come up.... +sleep 60 +echo "...done. Run \"docker rm -f rabbit\" to clean up the container." +echo diff --git a/go-cloud/pubsub/rabbitpubsub/rabbit.go b/go-cloud/pubsub/rabbitpubsub/rabbit.go new file mode 100644 index 000000000..4b79f348f --- /dev/null +++ b/go-cloud/pubsub/rabbitpubsub/rabbit.go @@ -0,0 +1,830 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 rabbitpubsub + +import ( + "context" + "errors" + "fmt" + "net/url" + "os" + "path" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + + amqp "github.com/rabbitmq/amqp091-go" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" +) + +func init() { + o := new(defaultDialer) + pubsub.DefaultURLMux().RegisterTopic(Scheme, o) + pubsub.DefaultURLMux().RegisterSubscription(Scheme, o) +} + +// defaultDialer dials a default Rabbit server based on the environment +// variable "RABBIT_SERVER_URL". +type defaultDialer struct { + mu sync.Mutex + conn *amqp.Connection + opener *URLOpener +} + +func (o *defaultDialer) defaultConn(ctx context.Context) (*URLOpener, error) { + o.mu.Lock() + defer o.mu.Unlock() + + // Re-use the connection if possible. + if o.opener != nil && o.conn != nil && !o.conn.IsClosed() { + return o.opener, nil + } + + // First time through, or last time resulted in an error, or connection + // was closed. Initialize the connection. + serverURL := os.Getenv("RABBIT_SERVER_URL") + if serverURL == "" { + return nil, errors.New("RABBIT_SERVER_URL environment variable not set") + } + conn, err := amqp.Dial(serverURL) + if err != nil { + return nil, fmt.Errorf("failed to dial RABBIT_SERVER_URL %q: %w", serverURL, err) + } + o.conn = conn + o.opener = &URLOpener{Connection: conn} + return o.opener, nil +} + +func (o *defaultDialer) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + opener, err := o.defaultConn(ctx) + if err != nil { + return nil, fmt.Errorf("open topic %v: failed to open default connection: %w", u, err) + } + return opener.OpenTopicURL(ctx, u) +} + +func (o *defaultDialer) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + opener, err := o.defaultConn(ctx) + if err != nil { + return nil, fmt.Errorf("open subscription %v: failed to open default connection: %w", u, err) + } + return opener.OpenSubscriptionURL(ctx, u) +} + +// Scheme is the URL scheme rabbitpubsub registers its URLOpeners under on pubsub.DefaultMux. +const Scheme = "rabbit" + +// URLOpener opens RabbitMQ URLs like "rabbit://myexchange" for +// topics or "rabbit://myqueue" for subscriptions. +// +// For topics, the URL's host+path is used as the exchange name. +// +// For subscriptions, the URL's host+path is used as the queue name. +// +// An optional query string can be used to set the Qos consumer prefetch on subscriptions +// like "rabbit://myqueue?prefetch_count=1000" to set the consumer prefetch count to 1000 +// see also https://www.rabbitmq.com/docs/consumer-prefetch +type URLOpener struct { + // Connection to use for communication with the server. + Connection *amqp.Connection + + // TopicOptions specifies the options to pass to OpenTopic. + TopicOptions TopicOptions + // SubscriptionOptions specifies the options to pass to OpenSubscription. + SubscriptionOptions SubscriptionOptions +} + +// OpenTopicURL opens a pubsub.Topic based on u. +func (o *URLOpener) OpenTopicURL(ctx context.Context, u *url.URL) (*pubsub.Topic, error) { + opts := o.TopicOptions + for param, value := range u.Query() { + switch param { + case "key_name": + if len(value) != 1 || len(value[0]) == 0 { + return nil, fmt.Errorf("open topic %v: invalid query parameter %q", u, param) + } + + opts.KeyName = value[0] + default: + return nil, fmt.Errorf("open topic %v: invalid query parameter %q", u, param) + } + } + + exchangeName := path.Join(u.Host, u.Path) + return OpenTopic(o.Connection, exchangeName, &opts), nil +} + +// OpenSubscriptionURL opens a pubsub.Subscription based on u. +func (o *URLOpener) OpenSubscriptionURL(ctx context.Context, u *url.URL) (*pubsub.Subscription, error) { + opts := o.SubscriptionOptions + for param, value := range u.Query() { + switch param { + case "prefetch_count": + if len(value) != 1 || len(value[0]) == 0 { + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q", u, param) + } + + prefetchCount, err := strconv.Atoi(value[0]) + if err != nil { + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q: %w", u, param, err) + } + + opts.PrefetchCount = &prefetchCount + default: + return nil, fmt.Errorf("open subscription %v: invalid query parameter %q", u, param) + } + } + + queueName := path.Join(u.Host, u.Path) + return OpenSubscription(o.Connection, queueName, &opts), nil +} + +type topic struct { + exchange string // the AMQP exchange + conn amqpConnection + opts *TopicOptions + + mu sync.Mutex + ch amqpChannel // AMQP channel used for all communication. + pubc <-chan amqp.Confirmation // Go channel for server acks of publishes + retc <-chan amqp.Return // Go channel for "returned" undeliverable messages + closec <-chan *amqp.Error // Go channel for AMQP channel close notifications +} + +// TopicOptions sets options for constructing a *pubsub.Topic backed by +// RabbitMQ. +type TopicOptions struct { + // KeyName optionally sets the Message.Metadata key to use as the optional + // RabbitMQ message key. If set, and if a matching Message.Metadata key is found, + // the value for that key will be used as the routing key when sending to + // RabbitMQ, instead of being added to the message headers. + KeyName string +} + +// SubscriptionOptions sets options for constructing a *pubsub.Subscription +// backed by RabbitMQ. +type SubscriptionOptions struct { + // KeyName optionally sets the Message.Metadata key in which to store the + // RabbitMQ message key. If set, and if the RabbitMQ message key is non-empty, + // the key value will be stored in Message.Metadata under KeyName. + KeyName string + + // Qos property prefetch count. Optional. + PrefetchCount *int +} + +// OpenTopic returns a *pubsub.Topic corresponding to the named exchange. +// See the package documentation for an example. +// +// The exchange should already exist (for instance, by using +// amqp.Channel.ExchangeDeclare), although this won't be checked until the first call +// to SendBatch. For the Go CDK Pub/Sub model to make sense, the exchange should +// be a fanout exchange, although nothing in this package enforces that. +// +// OpenTopic uses the supplied amqp.Connection for all communication. It is the +// caller's responsibility to establish this connection before calling OpenTopic, and +// to close it when Close has been called on all Topics opened with it. +// +// The documentation of the amqp package recommends using separate connections for +// publishing and subscribing. +func OpenTopic(conn *amqp.Connection, name string, opts *TopicOptions) *pubsub.Topic { + return pubsub.NewTopic(newTopic(&connection{conn}, name, opts), nil) +} + +func newTopic(conn amqpConnection, name string, opts *TopicOptions) *topic { + if opts == nil { + opts = &TopicOptions{} + } + + return &topic{ + conn: conn, + exchange: name, + opts: opts, + } +} + +// establishChannel creates an AMQP channel if necessary. According to the amqp +// package docs, once an error is returned from the channel, it must be discarded and +// a new one created. +// +// Must be called with t.mu held. +func (t *topic) establishChannel(ctx context.Context) error { + if t.ch != nil { // We already have a channel. + select { + // If it was closed, open a new one. + // (Ignore the error, if any.) + case <-t.closec: + + // If it isn't closed, nothing to do. + default: + return nil + } + } + var ch amqpChannel + err := runWithContext(ctx, func() error { + // Create a new channel in confirm mode. + var err error + ch, err = t.conn.Channel() + return err + }) + if err != nil { + return err + } + t.ch = ch + // Get Go channels which will hold acks and returns from the server. The server + // will send an ack for each published message to confirm that it was received. + // It will return undeliverable messages. + // All the Notify methods return their arg. + t.pubc = ch.NotifyPublish(make(chan amqp.Confirmation)) + t.retc = ch.NotifyReturn(make(chan amqp.Return)) + t.closec = ch.NotifyClose(make(chan *amqp.Error, 1)) // closec will get at most one element + return nil +} + +// Run f while checking to see if ctx is done. +// Return the error from f if it completes, or ctx.Err() if ctx is done. +func runWithContext(ctx context.Context, f func() error) error { + c := make(chan error, 1) // buffer so the goroutine can finish even if ctx is done + go func() { c <- f() }() + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-c: + return err + } +} + +// SendBatch implements driver.SendBatch. +func (t *topic) SendBatch(ctx context.Context, ms []*driver.Message) error { + // It is simplest to allow only one SendBatch at a time. Allowing concurrent + // calls to SendBatch would complicate the logic of receiving publish + // confirmations and returns. We can go that route if performance warrants it. + t.mu.Lock() + defer t.mu.Unlock() + + if err := t.establishChannel(ctx); err != nil { + return err + } + + // Receive from Go channels concurrently or we will deadlock with the Publish + // RPC. (The amqp package docs recommend setting the capacity of the Go channel + // to the number of messages to be published, but we can't do that because we + // want to reuse the channel for all calls to SendBatch--it takes two RPCs to set + // up.) + errc := make(chan error, 1) + cctx, cancel := context.WithCancel(ctx) + defer cancel() + ch := t.ch // Avoid touching t.ch while goroutine is running. + go func() { + // This goroutine runs with t.mu held because its lifetime is within the + // lifetime of the t.mu.Lock call at the start of SendBatch. + errc <- t.receiveFromPublishChannels(cctx, len(ms)) + }() + + var perr error + for _, m := range ms { + routingKey, pub := toRoutingKeyAndAMQPPublishing(m, t.opts) + if m.BeforeSend != nil { + asFunc := func(i any) bool { + if p, ok := i.(**amqp.Publishing); ok { + *p = &pub + return true + } + return false + } + if err := m.BeforeSend(asFunc); err != nil { + return err + } + } + if perr = ch.Publish(t.exchange, routingKey, pub); perr != nil { + cancel() + break + } + if m.AfterSend != nil { + asFunc := func(i any) bool { return false } + if err := m.AfterSend(asFunc); err != nil { + return err + } + } + } + // Wait for the goroutine to finish. + err := <-errc + // If we got an error from Publish, prefer that. + if perr != nil { + // Set t.ch to nil because an AMQP channel is broken after error. + // Do this here, after the goroutine has finished, rather than in the Publish loop + // above, to avoid a race condition. + t.ch = nil + err = perr + } + // If there is only one error, return it rather than a MultiError. That + // will work better with ErrorCode and ErrorAs. + var merr MultiError + if errors.As(err, &merr) && len(merr) == 1 { + return merr[0] + } + return err +} + +// Read from the channels established with NotifyPublish and NotifyReturn. +// Must be called with t.mu held. +func (t *topic) receiveFromPublishChannels(ctx context.Context, nMessages int) error { + // Consume all the acknowledgments for the messages we are publishing, and also + // get returned messages. The server will send exactly one ack for each published + // message (successful or not), and one return for each undeliverable message. + // Since SendBatch (the only caller of this method) holds the lock, we expect + // exactly as many acks as messages. + var merr MultiError + nAcks := 0 + for nAcks < nMessages { + select { + case <-ctx.Done(): + if t.ch != nil { + // Channel will be in a weird state (not all publish acks consumed, perhaps) + // so re-create it next time. + t.ch.Close() + t.ch = nil + } + return ctx.Err() + + case ret, ok := <-t.retc: + if !ok { + // Channel closed. Handled in the pubc case below. But set + // the channel to nil to prevent it from being selected again. + t.retc = nil + } else { + // The message was returned from the server because it is unroutable. + // Record the error and continue so we drain all + // items from pubc. We don't need to re-establish the channel on this + // error. + merr = append(merr, fmt.Errorf("rabbitpubsub: message returned from %s: %s (code %d)", + ret.Exchange, ret.ReplyText, ret.ReplyCode)) + } + + case conf, ok := <-t.pubc: + if !ok { + // t.pubc was closed unexpectedly. + t.ch = nil // re-create the channel on next use + if merr != nil { + return merr + } + // t.closec must be closed too. See if it has an error. + if err := closeErr(t.closec); err != nil { + merr = append(merr, err) + return merr + } + // We shouldn't be here, but if we are, we still want to return an + // error. + merr = append(merr, errors.New("rabbitpubsub: publish listener closed unexpectedly")) + return merr + } + nAcks++ + if !conf.Ack { + merr = append(merr, errors.New("rabbitpubsub: ack failed on publish")) + } + } + } + if merr != nil { + return merr + } + // Returning a nil merr would mean the returned error interface value is non-nil, so return nil explicitly. + return nil +} + +// A MultiError is an error that contains multiple errors. +type MultiError []error + +func (m MultiError) Error() string { + var s []string + for _, e := range m { + s = append(s, e.Error()) + } + return strings.Join(s, "; ") +} + +// Return the error from a Go channel monitoring the closing of an AMQP channel. +// closec must have been registered via Channel.NotifyClose. +// When closeErr is called, we expect closec to be closed. If it isn't, we also +// consider that an error. +func closeErr(closec <-chan *amqp.Error) error { + select { + case aerr := <-closec: + // This nil check is necessary. aerr is of type *amqp.Error. If we + // returned it directly (effectively assigning it to a variable of + // type error), then the return value would not be a nil interface + // value even if aerr was a nil pointer, and that would break tests + // like "if err == nil ...". + if aerr == nil { + return nil + } + return aerr + default: + return errors.New("rabbitpubsub: NotifyClose Go channel is unexpectedly open") + } +} + +// toRoutingKeyAndAMQPPublishing converts a driver.Message to a pair routingKey + amqp.Publishing. +func toRoutingKeyAndAMQPPublishing(m *driver.Message, opts *TopicOptions) (routingKey string, msg amqp.Publishing) { + h := amqp.Table{} + for k, v := range m.Metadata { + if opts.KeyName == k { + routingKey = v + } else { + h[k] = v + } + } + + msg = amqp.Publishing{ + Headers: h, + Body: m.Body, + } + + return routingKey, msg +} + +// IsRetryable implements driver.Topic.IsRetryable. +func (*topic) IsRetryable(err error) bool { + return isRetryable(err) +} + +func (*topic) ErrorCode(err error) gcerrors.ErrorCode { + return errorCode(err) +} + +var errorCodes = map[int]gcerrors.ErrorCode{ + amqp.NotFound: gcerrors.NotFound, + amqp.PreconditionFailed: gcerrors.FailedPrecondition, + // These next indicate a bug in our driver, not the user's code. + amqp.SyntaxError: gcerrors.Internal, + amqp.CommandInvalid: gcerrors.Internal, + amqp.InternalError: gcerrors.Internal, + amqp.NotImplemented: gcerrors.Unimplemented, + amqp.ChannelError: gcerrors.FailedPrecondition, // typically channel closed +} + +func errorCode(err error) gcerrors.ErrorCode { + var aerr *amqp.Error + if !errors.As(err, &aerr) { + return gcerrors.Unknown + } + if ec, ok := errorCodes[aerr.Code]; ok { + return ec + } + return gcerrors.Unknown +} + +func isRetryable(err error) bool { + var aerr *amqp.Error + if !errors.As(err, &aerr) { + return false + } + // amqp.Error has a Recover field which sounds like it should mean "retryable". + // But it actually means "can be recovered by retrying later or with different + // parameters," which is not what we want. The error codes for which Recover is + // true, defined in the isSoftExceptionCode function of + // https://github.com/rabbitmq/amqp091-go/blob/main/spec091.go, including things + // like NotFound and AccessRefused, which require outside action. + // + // The following are the codes which might be resolved by retry without external + // action, according to the AMQP 0.91 spec + // (https://www.rabbitmq.com/amqp-0-9-1-reference.html#constants). The quotations + // are from that page. + switch aerr.Code { + case amqp.ContentTooLarge: + // "The client attempted to transfer content larger than the server could + // accept at the present time. The client may retry at a later time." + return true + + case amqp.ConnectionForced: + // "An operator intervened to close the connection for some reason. The + // client may retry at some later date." + return true + + default: + return false + } +} + +// As implements driver.Topic.As. +func (t *topic) As(i any) bool { + c, ok := i.(**amqp.Connection) + if !ok { + return false + } + conn, ok := t.conn.(*connection) + if !ok { // running against the fake + return false + } + *c = conn.conn + return true +} + +// ErrorAs implements driver.Topic.ErrorAs +func (*topic) ErrorAs(err error, i any) bool { + return errorAs(err, i) +} + +func errorAs(err error, i any) bool { + var aerr *amqp.Error + if errors.As(err, &aerr) { + if p, ok := i.(**amqp.Error); ok { + *p = aerr + return true + } + } + + var merr MultiError + if errors.As(err, &merr) { + if p, ok := i.(*MultiError); ok { + *p = merr + return true + } + } + + return false +} + +// Close implements driver.Topic.Close. +func (*topic) Close() error { return nil } + +// OpenSubscription returns a *pubsub.Subscription corresponding to the named queue. +// See the package documentation for an example. +// +// The queue must have been previously created (for instance, by using +// amqp.Channel.QueueDeclare) and bound to an exchange. +// +// OpenSubscription uses the supplied amqp.Connection for all communication. It is +// the caller's responsibility to establish this connection before calling +// OpenSubscription and to close it when Close has been called on all Subscriptions +// opened with it. +// +// The documentation of the amqp package recommends using separate connections for +// publishing and subscribing. +func OpenSubscription(conn *amqp.Connection, name string, opts *SubscriptionOptions) *pubsub.Subscription { + return pubsub.NewSubscription(newSubscription(&connection{conn}, name, opts), nil, nil) +} + +type subscription struct { + conn amqpConnection + queue string // the AMQP queue name + consumer string // the client-generated name for this particular subscriber + + opts *SubscriptionOptions + + mu sync.Mutex + ch amqpChannel // AMQP channel used for all communication. + delc <-chan amqp.Delivery + closec <-chan *amqp.Error + + receiveBatchHook func() // for testing +} + +var nextConsumer int64 // atomic + +func newSubscription(conn amqpConnection, name string, opts *SubscriptionOptions) *subscription { + if opts == nil { + opts = &SubscriptionOptions{} + } + + return &subscription{ + conn: conn, + queue: name, + consumer: fmt.Sprintf("c%d", atomic.AddInt64(&nextConsumer, 1)), + opts: opts, + receiveBatchHook: func() {}, + } +} + +// Must be called with s.mu held. +func (s *subscription) establishChannel(ctx context.Context) error { + if s.ch != nil { // We already have a channel. + select { + // If it was closed, open a new one. + // (Ignore the error, if any.) + case <-s.closec: + + // If it isn't closed, nothing to do. + default: + return nil + } + } + var ch amqpChannel + err := runWithContext(ctx, func() error { + // Create a new channel. + var err error + ch, err = s.conn.Channel() + if err != nil { + return err + } + // Apply subscription options to channel. + err = applyOptionsToChannel(s.opts, ch) + if err != nil { + return err + } + // Subscribe to messages from the queue. + s.delc, err = ch.Consume(s.queue, s.consumer) + return err + }) + if err != nil { + return err + } + + s.ch = ch + s.closec = ch.NotifyClose(make(chan *amqp.Error, 1)) // closec will get at most one element + + return nil +} + +func applyOptionsToChannel(opts *SubscriptionOptions, ch amqpChannel) error { + if opts.PrefetchCount == nil { + return nil + } + + if err := ch.Qos(*opts.PrefetchCount, 0, false); err != nil { + return fmt.Errorf("unable to set channel Qos: %w", err) + } + + return nil +} + +// ReceiveBatch implements driver.Subscription.ReceiveBatch. +func (s *subscription) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + s.mu.Lock() + defer s.mu.Unlock() + + if err := s.establishChannel(ctx); err != nil { + return nil, err + } + + s.receiveBatchHook() + + // Get up to maxMessages waiting messages, but don't take too long. + var ms []*driver.Message + maxTime := time.NewTimer(50 * time.Millisecond) + for { + select { + case <-ctx.Done(): + // Cancel the Consume. + _ = s.ch.Cancel(s.consumer) // ignore the error + s.ch = nil + return nil, ctx.Err() + + case d, ok := <-s.delc: + if !ok { // channel closed + s.ch = nil // re-establish the channel next time + if len(ms) > 0 { + return ms, nil + } + // s.closec must be closed too. See if it has an error. + if err := closeErr(s.closec); err != nil { + // PreconditionFailed can happen if we send an Ack or Nack for a + // message that has already been acked/nacked. Ignore those errors. + var aerr *amqp.Error + if errors.As(err, &aerr) && aerr.Code == amqp.PreconditionFailed { + return nil, nil + } + return nil, err + } + // We shouldn't be here, but if we are, we still want to return an + // error. + return nil, errors.New("rabbitpubsub: delivery channel closed unexpectedly") + } + ms = append(ms, toDriverMessage(d, s.opts)) + if len(ms) >= maxMessages { + return ms, nil + } + + case <-maxTime.C: + // Timed out. Return whatever we have. If we have nothing, we'll get + // called again soon, but returning allows us to give up the lock in + // case there are acks/nacks to be sent. + return ms, nil + } + } +} + +// toDriverMessage converts an amqp.Delivery (a received message) to a driver.Message. +func toDriverMessage(d amqp.Delivery, opts *SubscriptionOptions) *driver.Message { + // Delivery.Headers is a map[string]any, so we have to + // convert each value to a string. + md := map[string]string{} + for k, v := range d.Headers { + md[k] = fmt.Sprint(v) + } + // Add a metadata entry for the message routing key if appropriate. + if d.RoutingKey != "" && opts.KeyName != "" { + md[opts.KeyName] = d.RoutingKey + } + loggableID := d.MessageId + if loggableID == "" { + loggableID = d.CorrelationId + } + if loggableID == "" { + loggableID = fmt.Sprintf("DeliveryTag %d", d.DeliveryTag) + } + return &driver.Message{ + LoggableID: loggableID, + Body: d.Body, + AckID: d.DeliveryTag, + Metadata: md, + AsFunc: func(i any) bool { + p, ok := i.(*amqp.Delivery) + if !ok { + return false + } + *p = d + return true + }, + } +} + +// SendAcks implements driver.Subscription.SendAcks. +func (s *subscription) SendAcks(ctx context.Context, ackIDs []driver.AckID) error { + return s.sendAcksOrNacks(ctx, ackIDs, true) +} + +// CanNack implements driver.CanNack. +func (s *subscription) CanNack() bool { return true } + +// SendNacks implements driver.Subscription.SendNacks. +func (s *subscription) SendNacks(ctx context.Context, ackIDs []driver.AckID) error { + return s.sendAcksOrNacks(ctx, ackIDs, false) +} + +func (s *subscription) sendAcksOrNacks(ctx context.Context, ackIDs []driver.AckID, ack bool) error { + s.mu.Lock() + defer s.mu.Unlock() + + if err := s.establishChannel(ctx); err != nil { + return err + } + + // Ack/Nack calls don't wait for a response, so this loop should execute relatively + // quickly. + // It wouldn't help to make it concurrent, because Channel.Ack/Nack grabs a + // channel-wide mutex. (We could consider using multiple channels if performance + // becomes an issue.) + for _, id := range ackIDs { + if ctx.Err() != nil { + return ctx.Err() + } + var err error + if ack { + err = s.ch.Ack(id.(uint64)) + } else { + err = s.ch.Nack(id.(uint64)) + } + if err != nil { + s.ch = nil // re-establish channel after an error + return err + } + } + return nil +} + +// IsRetryable implements driver.Subscription.IsRetryable. +func (*subscription) IsRetryable(err error) bool { + return isRetryable(err) +} + +func (*subscription) ErrorCode(err error) gcerrors.ErrorCode { + return errorCode(err) +} + +// As implements driver.Subscription.As. +func (s *subscription) As(i any) bool { + c, ok := i.(**amqp.Connection) + if !ok { + return false + } + conn, ok := s.conn.(*connection) + if !ok { // running against the fake + return false + } + *c = conn.conn + return true +} + +// ErrorAs implements driver.Subscription.ErrorAs +func (*subscription) ErrorAs(err error, i any) bool { + return errorAs(err, i) +} + +// Close implements driver.Subscription.Close. +func (*subscription) Close() error { return nil } diff --git a/go-cloud/pubsub/rabbitpubsub/rabbit_test.go b/go-cloud/pubsub/rabbitpubsub/rabbit_test.go new file mode 100644 index 000000000..ca465648b --- /dev/null +++ b/go-cloud/pubsub/rabbitpubsub/rabbit_test.go @@ -0,0 +1,488 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 rabbitpubsub + +// To run these tests against a real RabbitMQ server, first run localrabbit.sh. +// Then wait a few seconds for the server to be ready. +// If no server is running, the tests will use a fake (see fake_test.go). + +import ( + "context" + "errors" + "fmt" + "io" + "os" + "strings" + "sync" + "sync/atomic" + "testing" + "time" + + amqp "github.com/rabbitmq/amqp091-go" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/drivertest" +) + +const rabbitURL = "amqp://guest:guest@localhost:5672/" + +var logOnce sync.Once + +func mustDialRabbit(t testing.TB) amqpConnection { + t.Helper() + + if !setup.HasDockerTestEnvironment() { + logOnce.Do(func() { + t.Log("using the fake because the RabbitMQ server is not available") + }) + return newFakeConnection() + } + conn, err := amqp.Dial(rabbitURL) + if err != nil { + t.Fatal(err) + } + logOnce.Do(func() { + t.Logf("using the RabbitMQ server at %s", rabbitURL) + }) + return &connection{conn} +} + +func TestConformance(t *testing.T) { + harnessMaker := func(_ context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return &harness{conn: mustDialRabbit(t)}, nil + } + _, isFake := mustDialRabbit(t).(*fakeConnection) + asTests := []drivertest.AsTest{rabbitAsTest{isFake}} + drivertest.RunConformanceTests(t, harnessMaker, asTests) + + // Run the conformance tests with the fake if we haven't. + if isFake { + return + } + t.Logf("now running tests with the fake") + harnessMaker = func(_ context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return &harness{conn: newFakeConnection()}, nil + } + asTests = []drivertest.AsTest{rabbitAsTest{true}} + drivertest.RunConformanceTests(t, harnessMaker, asTests) +} + +func BenchmarkRabbit(b *testing.B) { + ctx := context.Background() + h := &harness{conn: mustDialRabbit(b)} + dt, cleanup, err := h.CreateTopic(ctx, b.Name()) + if err != nil { + b.Fatal(err) + } + defer cleanup() + ds, cleanup, err := h.CreateSubscription(ctx, dt, b.Name()) + if err != nil { + b.Fatal(err) + } + defer cleanup() + + topic := pubsub.NewTopic(dt, nil) + defer topic.Shutdown(ctx) + sub := pubsub.NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + + drivertest.RunBenchmarks(b, topic, sub) +} + +type harness struct { + conn amqpConnection + numTopics uint32 + numSubs uint32 +} + +func (h *harness) CreateTopic(_ context.Context, testName string) (dt driver.Topic, cleanup func(), err error) { + exchange := fmt.Sprintf("%s-topic-%d", testName, atomic.AddUint32(&h.numTopics, 1)) + if err := declareExchange(h.conn, exchange); err != nil { + return nil, nil, err + } + cleanup = func() { + ch, err := h.conn.Channel() + if err != nil { + panic(err) + } + ch.ExchangeDelete(exchange) + } + return newTopic(h.conn, exchange, nil), cleanup, nil +} + +func (h *harness) MakeNonexistentTopic(context.Context) (driver.Topic, error) { + return newTopic(h.conn, "nonexistent-topic", nil), nil +} + +func (h *harness) CreateSubscription(_ context.Context, dt driver.Topic, testName string) (ds driver.Subscription, cleanup func(), err error) { + queue := fmt.Sprintf("%s-subscription-%d", testName, atomic.AddUint32(&h.numSubs, 1)) + if err := bindQueue(h.conn, queue, dt.(*topic).exchange); err != nil { + return nil, nil, err + } + cleanup = func() { + ch, err := h.conn.Channel() + if err != nil { + panic(err) + } + ch.QueueDelete(queue) + } + ds = newSubscription(h.conn, queue, nil) + return ds, cleanup, nil +} + +func (h *harness) MakeNonexistentSubscription(_ context.Context) (driver.Subscription, func(), error) { + return newSubscription(h.conn, "nonexistent-subscription", nil), func() {}, nil +} + +func (h *harness) Close() { + h.conn.Close() +} + +func (h *harness) MaxBatchSizes() (int, int) { return 0, 0 } + +func (*harness) SupportsMultipleSubscriptions() bool { return true } + +func TestUnroutable(t *testing.T) { + // Expect that we get an error on publish if the exchange has no queue bound to it. + // The error should be a MultiError containing one error per message. + ctx := context.Background() + conn := mustDialRabbit(t) + defer conn.Close() + + if err := declareExchange(conn, "u"); err != nil { + t.Fatal(err) + } + topic := newTopic(conn, "u", nil) + msgs := []*driver.Message{ + {Body: []byte("")}, + {Body: []byte("")}, + } + err := topic.SendBatch(ctx, msgs) + var merr MultiError + if !topic.ErrorAs(err, &merr) { + t.Fatalf("got error of type %T, want MultiError", err) + } + if got, want := len(merr), len(msgs); got != want { + t.Fatalf("got %d errors, want %d", got, want) + } + // Test MultiError.Error. + if got, want := strings.Count(merr.Error(), ";")+1, len(merr); got != want { + t.Errorf("got %d semicolon-separated messages, want %d", got, want) + } + // Test each individual error. + for i, err := range merr { + if !strings.Contains(err.Error(), "NO_ROUTE") { + t.Errorf("%d: got %v, want an error with 'NO_ROUTE'", i, err) + } + } +} + +func TestErrorCode(t *testing.T) { + for _, test := range []struct { + in error + want gcerrors.ErrorCode + }{ + {nil, gcerrors.Unknown}, + {&os.PathError{}, gcerrors.Unknown}, + {&amqp.Error{Code: amqp.SyntaxError}, gcerrors.Internal}, + {&amqp.Error{Code: amqp.NotImplemented}, gcerrors.Unimplemented}, + {&amqp.Error{Code: amqp.ContentTooLarge}, gcerrors.Unknown}, + } { + if got := errorCode(test.in); got != test.want { + t.Errorf("%v: got %s, want %s", test.in, got, test.want) + } + } +} + +func TestOpens(t *testing.T) { + ctx := context.Background() + if got := OpenTopic(nil, "t", nil); got == nil { + t.Error("got nil, want non-nil") + } else { + got.Shutdown(ctx) + } + if got := OpenSubscription(nil, "s", nil); got == nil { + t.Error("got nil, want non-nil") + } else { + got.Shutdown(ctx) + } +} + +func TestIsRetryable(t *testing.T) { + for _, test := range []struct { + err error + want bool + }{ + {errors.New("xyz"), false}, + {io.ErrUnexpectedEOF, false}, + {&amqp.Error{Code: amqp.AccessRefused}, false}, + {&amqp.Error{Code: amqp.ContentTooLarge}, true}, + {&amqp.Error{Code: amqp.ConnectionForced}, true}, + } { + got := isRetryable(test.err) + if got != test.want { + t.Errorf("%+v: got %t, want %t", test.err, got, test.want) + } + } +} + +func TestRunWithContext(t *testing.T) { + // runWithContext will run its argument to completion if the context isn't done. + e := errors.New("") + // f sleeps for a bit just to give the scheduler a chance to run. + f := func() error { time.Sleep(100 * time.Millisecond); return e } + got := runWithContext(context.Background(), f) + if want := e; got != want { + t.Errorf("got %v, want %v", got, want) + } + + // runWithContext will return ctx.Err if context is done. + ctx, cancel := context.WithCancel(context.Background()) + cancel() + got = runWithContext(ctx, f) + if want := context.Canceled; got != want { + t.Errorf("got %v, want %v", got, want) + } +} + +func declareExchange(conn amqpConnection, name string) error { + ch, err := conn.Channel() + if err != nil { + panic(err) + } + defer ch.Close() + return ch.ExchangeDeclare(name) +} + +func bindQueue(conn amqpConnection, queueName, exchangeName string) error { + ch, err := conn.Channel() + if err != nil { + return err + } + defer ch.Close() + return ch.QueueDeclareAndBind(queueName, exchangeName) +} + +type rabbitAsTest struct { + usingFake bool +} + +func (rabbitAsTest) Name() string { + return "rabbit test" +} + +func (r rabbitAsTest) TopicCheck(topic *pubsub.Topic) error { + var conn2 amqp.Connection + if topic.As(&conn2) { + return fmt.Errorf("cast succeeded for %T, want failure", &conn2) + } + if !r.usingFake { + var conn3 *amqp.Connection + if !topic.As(&conn3) { + return fmt.Errorf("cast failed for %T", &conn3) + } + } + return nil +} + +func (r rabbitAsTest) SubscriptionCheck(sub *pubsub.Subscription) error { + var conn2 amqp.Connection + if sub.As(&conn2) { + return fmt.Errorf("cast succeeded for %T, want failure", &conn2) + } + if !r.usingFake { + var conn3 *amqp.Connection + if !sub.As(&conn3) { + return fmt.Errorf("cast failed for %T", &conn3) + } + } + return nil +} + +func (rabbitAsTest) TopicErrorCheck(t *pubsub.Topic, err error) error { + var aerr *amqp.Error + if !t.ErrorAs(err, &aerr) { + return fmt.Errorf("failed to convert %v (%T) to an amqp.Error", err, err) + } + if aerr.Code != amqp.NotFound { + return fmt.Errorf("got code %v, want NotFound", aerr.Code) + } + + err = MultiError{err} + var merr MultiError + if !t.ErrorAs(err, &merr) { + return fmt.Errorf("failed to convert %v (%T) to a MultiError", err, err) + } + var perr *os.PathError + if t.ErrorAs(err, &perr) { + return errors.New("got true for PathError, want false") + } + return nil +} + +func (rabbitAsTest) SubscriptionErrorCheck(s *pubsub.Subscription, err error) error { + var aerr *amqp.Error + if !s.ErrorAs(err, &aerr) { + return fmt.Errorf("failed to convert %v (%T) to an amqp.Error", err, err) + } + if aerr.Code != amqp.NotFound { + return fmt.Errorf("got code %v, want NotFound", aerr.Code) + } + + err = MultiError{err} + var merr MultiError + if !s.ErrorAs(err, &merr) { + return fmt.Errorf("failed to convert %v (%T) to a MultiError", err, err) + } + var perr *os.PathError + if s.ErrorAs(err, &perr) { + return errors.New("got true for PathError, want false") + } + return nil +} + +func (r rabbitAsTest) MessageCheck(m *pubsub.Message) error { + var pd *amqp.Delivery + if m.As(&pd) { + return fmt.Errorf("cast succeeded for %T, want failure", &pd) + } + if !r.usingFake { + var d amqp.Delivery + if !m.As(&d) { + return fmt.Errorf("cast failed for %T", &d) + } + } + return nil +} + +func (rabbitAsTest) BeforeSend(as func(any) bool) error { + var pub *amqp.Publishing + if !as(&pub) { + return fmt.Errorf("cast failed for %T", &pub) + } + return nil +} + +func (rabbitAsTest) AfterSend(as func(any) bool) error { + return nil +} + +func TestOpenTopicFromURL(t *testing.T) { + t.Setenv("RABBIT_SERVER_URL", rabbitURL) + + tests := []struct { + label string + URLTemplate string + WantErr bool + }{ + {"valid url", "rabbit://%s", false}, + {"valid url with key name parameter", "rabbit://%s?key_name=foo", false}, + {"invalid url with parameters", "rabbit://%s?param=value", true}, + {"invalid url with key name parameter", "rabbit://%s?key_name=", true}, + } + + for _, test := range tests { + t.Run(test.label, func(t *testing.T) { + conn := mustDialRabbit(t) + _, isFake := conn.(*fakeConnection) + if isFake { + t.Skip("test requires real rabbitmq") + } + + h := &harness{conn: conn} + + ctx := context.Background() + + dt, cleanupTopic, err := h.CreateTopic(ctx, t.Name()) + if err != nil { + t.Fatalf("unable to create topic: %v", err) + } + + t.Cleanup(cleanupTopic) + + exchange := dt.(*topic).exchange + url := fmt.Sprintf(test.URLTemplate, exchange) + + topic, err := pubsub.OpenTopic(ctx, url) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URLTemplate, err, test.WantErr) + } + if topic != nil { + topic.Shutdown(ctx) + } + }) + } +} + +func TestOpenSubscriptionFromURL(t *testing.T) { + t.Setenv("RABBIT_SERVER_URL", rabbitURL) + + tests := []struct { + label string + URLTemplate string + WantErr bool + }{ + {"url with no QoS prefetch count", "rabbit://%s", false}, + {"invalid parameters", "rabbit://%s?param=value", true}, + {"valid url with QoS prefetch count", "rabbit://%s?prefetch_count=1024", false}, + {"invalid url with QoS prefetch count", "rabbit://%s?prefetch_count=value", true}, + } + + for _, test := range tests { + t.Run(test.label, func(t *testing.T) { + conn := mustDialRabbit(t) + _, isFake := conn.(*fakeConnection) + if isFake { + t.Skip("test requires real rabbitmq") + } + + h := &harness{conn: conn} + + ctx := context.Background() + + dt, cleanupTopic, err := h.CreateTopic(ctx, t.Name()) + if err != nil { + t.Fatalf("unable to create topic: %v", err) + } + + t.Cleanup(cleanupTopic) + + ds, cleanupSubscription, err := h.CreateSubscription(ctx, dt, t.Name()) + if err != nil { + t.Fatalf("unable to create subscription: %v", err) + } + + t.Cleanup(cleanupSubscription) + + queue := ds.(*subscription).queue + url := fmt.Sprintf(test.URLTemplate, queue) + + sub, err := pubsub.OpenSubscription(ctx, url) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URLTemplate, err, test.WantErr) + } + + if sub != nil { + sub.Shutdown(ctx) + } + }) + } +} diff --git a/go-cloud/pubsub/sub_test.go b/go-cloud/pubsub/sub_test.go new file mode 100644 index 000000000..e29418880 --- /dev/null +++ b/go-cloud/pubsub/sub_test.go @@ -0,0 +1,82 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 pubsub_test + +import ( + "context" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + "github.com/DataDog/iceberg-go/go-cloud/pubsub/driver" +) + +// scriptedSub returns batches of messages in a predefined order from +// ReceiveBatch. +type scriptedSub struct { + driver.Subscription + // batches contains slices of messages to return from ReceiveBatch, one + // after the other. + batches [][]*driver.Message + + // calls counts how many times ReceiveBatch has been called. + calls int + + // closed records if Close was called. + closed bool +} + +func (s *scriptedSub) ReceiveBatch(ctx context.Context, maxMessages int) ([]*driver.Message, error) { + b := s.batches[s.calls] + s.calls++ + return b, nil +} + +func (s *scriptedSub) SendAcks(ctx context.Context, ackIDs []driver.AckID) error { + return nil +} + +func (*scriptedSub) CanNack() bool { return false } +func (s *scriptedSub) Close() error { + s.closed = true + return nil +} + +func TestReceiveWithEmptyBatchReturnedFromDriver(t *testing.T) { + ctx := context.Background() + ds := &scriptedSub{ + batches: [][]*driver.Message{ + // First call gets an empty batch. + {}, + // Second call gets a non-empty batch. + {&driver.Message{}}, + }, + } + sub := pubsub.NewSubscription(ds, nil, nil) + defer sub.Shutdown(ctx) + m, err := sub.Receive(ctx) + if err != nil { + t.Fatal(err) + } + m.Ack() +} + +func TestSubscriptionCloseIsCalled(t *testing.T) { + ctx := context.Background() + ds := &scriptedSub{} + sub := pubsub.NewSubscription(ds, nil, nil) + sub.Shutdown(ctx) + if !ds.closed { + t.Error("want Subscription.Close to have been called") + } +} diff --git a/go-cloud/runtimevar/awsparamstore/awsparamstore.go b/go-cloud/runtimevar/awsparamstore/awsparamstore.go new file mode 100644 index 000000000..f179da5cb --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/awsparamstore.go @@ -0,0 +1,313 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awsparamstore provides a runtimevar implementation with variables +// read from AWS Systems Manager Parameter Store +// (https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html) +// Use OpenVariable to construct a *runtimevar.Variable. +// +// # URLs +// +// For runtimevar.OpenVariable, awsparamstore registers for the scheme "awsparamstore". +// The default URL opener will use an AWS session with the default credentials +// and configuration. +// +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// awsparamstore exposes the following types for As: +// - Snapshot: *ssm.GetParameterOutput +// - Error: any error type returned by the service, notably smithy.APIError +package awsparamstore // import "gocloud.dev/runtimevar/awsparamstore" + +import ( + "context" + "errors" + "fmt" + "net/url" + "path" + "strings" + "sync" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/aws/smithy-go" + "github.com/google/wire" + gcaws "github.com/DataDog/iceberg-go/go-cloud/aws" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" +) + +func init() { + runtimevar.DefaultURLMux().RegisterVariable(Scheme, new(lazySessionOpener)) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + Dial, +) + +// Dial gets an AWS SSM service client using the AWS SDK V2. +func Dial(cfg aws.Config) *ssm.Client { + return ssm.NewFromConfig(cfg) +} + +// URLOpener opens AWS Paramstore URLs like "awsparamstore://myvar". +// +// See https://pkg.go.dev/gocloud.dev/aws#V2ConfigFromURLParams. +// +// In addition, the following URL parameters are supported: +// - decoder: The decoder to use. Defaults to URLOpener.Decoder, or +// runtimevar.BytesDecoder if URLOpener.Decoder is nil. +// See runtimevar.DecoderByName for supported values. +// - wait: The poll interval, in time.ParseDuration formats. +// Defaults to 30s. +type URLOpener struct { + // Decoder specifies the decoder to use if one is not specified in the URL. + // Defaults to runtimevar.BytesDecoder. + Decoder *runtimevar.Decoder + + // Options specifies the options to pass to New. + Options Options +} + +// lazySessionOpener obtains the AWS session from the environment on the first +// call to OpenVariableURL. +type lazySessionOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazySessionOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + opener := &URLOpener{} + return opener.OpenVariableURL(ctx, u) +} + +// Scheme is the URL scheme awsparamstore registers its URLOpener under on runtimevar.DefaultMux. +const Scheme = "awsparamstore" + +// OpenVariableURL opens the variable at the URL's path. See the package doc +// for more details. +func (o *URLOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + q := u.Query() + + decoderName := q.Get("decoder") + q.Del("decoder") + decoder, err := runtimevar.DecoderByName(ctx, decoderName, o.Decoder) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid decoder: %v", u, err) + } + opts := o.Options + if s := q.Get("wait"); s != "" { + q.Del("wait") + d, err := time.ParseDuration(s) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid wait %q: %v", u, s, err) + } + opts.WaitDuration = d + } + + cfg, err := gcaws.V2ConfigFromURLParams(ctx, q) + if err != nil { + return nil, fmt.Errorf("open variable %v: %v", u, err) + } + return OpenVariable(ssm.NewFromConfig(cfg), path.Join(u.Host, u.Path), decoder, &opts) +} + +// Options sets options. +type Options struct { + // WaitDuration controls the rate at which Parameter Store is polled. + // Defaults to 30 seconds. + WaitDuration time.Duration +} + +// OpenVariable constructs a *runtimevar.Variable backed by the variable name in +// AWS Systems Manager Parameter Store, using AWS SDK V2. +// Parameter Store returns raw bytes; provide a decoder to decode the raw bytes +// into the appropriate type for runtimevar.Snapshot.Value. +// See the runtimevar package documentation for examples of decoders. +func OpenVariable(client *ssm.Client, name string, decoder *runtimevar.Decoder, opts *Options) (*runtimevar.Variable, error) { + return runtimevar.New(newWatcher(client, name, decoder, opts)), nil +} + +var OpenVariableV2 = OpenVariable + +func newWatcher(client *ssm.Client, name string, decoder *runtimevar.Decoder, opts *Options) *watcher { + if opts == nil { + opts = &Options{} + } + return &watcher{ + client: client, + name: name, + wait: driver.WaitDuration(opts.WaitDuration), + decoder: decoder, + } +} + +// state implements driver.State. +type state struct { + val any + rawGet *ssm.GetParameterOutput + updateTime time.Time + version int64 + err error +} + +// Value implements driver.State.Value. +func (s *state) Value() (any, error) { + return s.val, s.err +} + +// UpdateTime implements driver.State.UpdateTime. +func (s *state) UpdateTime() time.Time { + return s.updateTime +} + +// As implements driver.State.As. +func (s *state) As(i any) bool { + switch p := i.(type) { + case **ssm.GetParameterOutput: + *p = s.rawGet + default: + return false + } + return true +} + +// errorState returns a new State with err, unless prevS also represents +// the same error, in which case it returns nil. +func errorState(err error, prevS driver.State) driver.State { + // Map aws.RequestCanceled to the more standard context package errors. + if getErrorCode(err) == "CancelledError" { + msg := err.Error() + if strings.Contains(msg, "context deadline exceeded") { + err = context.DeadlineExceeded + } else { + err = context.Canceled + } + } + s := &state{err: err} + if prevS == nil { + return s + } + prev := prevS.(*state) + if prev.err == nil { + // New error. + return s + } + if equivalentError(err, prev.err) { + // Same error, return nil to indicate no change. + return nil + } + return s +} + +// equivalentError returns true iff err1 and err2 represent an equivalent error; +// i.e., we don't want to return it to the user as a different error. +func equivalentError(err1, err2 error) bool { + if err1 == err2 || err1.Error() == err2.Error() { + return true + } + code1 := getErrorCode(err1) + code2 := getErrorCode(err2) + return code1 != "" && code1 == code2 +} + +type watcher struct { + // client is the client to use. + client *ssm.Client + // name is the parameter to retrieve. + name string + // wait is the amount of time to wait between querying AWS. + wait time.Duration + // decoder is the decoder that unmarshals the value in the param. + decoder *runtimevar.Decoder +} + +func getParameter(ctx context.Context, client *ssm.Client, name string) (int64, []byte, time.Time, *ssm.GetParameterOutput, error) { + getResp, err := client.GetParameter(ctx, &ssm.GetParameterInput{ + Name: aws.String(name), + // Ignored if the parameter is not encrypted. + WithDecryption: aws.Bool(true), + }) + if err != nil { + return 0, nil, time.Time{}, nil, err + } + if getResp.Parameter == nil { + return 0, nil, time.Time{}, getResp, fmt.Errorf("unable to get %q parameter", name) + } + return getResp.Parameter.Version, []byte(aws.ToString(getResp.Parameter.Value)), aws.ToTime(getResp.Parameter.LastModifiedDate), getResp, nil +} + +func (w *watcher) WatchVariable(ctx context.Context, prev driver.State) (driver.State, time.Duration) { + lastVersion := int64(-1) + if prev != nil { + lastVersion = prev.(*state).version + } + + // GetParameter from S3 to get the current value and version. + newVersion, newVal, newLastModified, rawGet, err := getParameter(ctx, w.client, w.name) + if err != nil { + return errorState(err, prev), w.wait + } + if newVersion == lastVersion { + // Version hasn't changed, so no change; return nil. + return nil, w.wait + } + + // New value (or at least, new version). Decode it. + val, err := w.decoder.Decode(ctx, newVal) + if err != nil { + return errorState(err, prev), w.wait + } + return &state{ + val: val, + rawGet: rawGet, + updateTime: newLastModified, + version: newVersion, + }, w.wait +} + +// Close implements driver.Close. +func (w *watcher) Close() error { + return nil +} + +// ErrorAs implements driver.ErrorAs. +func (w *watcher) ErrorAs(err error, i any) bool { + return errors.As(err, i) +} + +func getErrorCode(err error) string { + var ae smithy.APIError + if errors.As(err, &ae) { + return ae.ErrorCode() + } + return "" +} + +// ErrorCode implements driver.ErrorCode. +func (w *watcher) ErrorCode(err error) gcerrors.ErrorCode { + code := getErrorCode(err) + if code == "ParameterNotFound" { + return gcerrors.NotFound + } + return gcerrors.Unknown +} diff --git a/go-cloud/runtimevar/awsparamstore/awsparamstore_test.go b/go-cloud/runtimevar/awsparamstore/awsparamstore_test.go new file mode 100644 index 000000000..11e4cec3d --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/awsparamstore_test.go @@ -0,0 +1,138 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awsparamstore + +import ( + "context" + "errors" + "testing" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/aws/smithy-go" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/drivertest" +) + +// This constant records the region used for the last --record. +// If you want to use --record mode, +// 1. Update this constant to your AWS region. +// TODO(issue #300): Use Terraform to get this. +const region = "us-east-2" + +type harness struct { + client *ssm.Client + closer func() +} + +func newHarness(t *testing.T) (drivertest.Harness, error) { + t.Helper() + + cfg, _, done, _ := setup.NewAWSv2Config(context.Background(), t, region, false) + return &harness{client: ssm.NewFromConfig(cfg), closer: done}, nil +} + +func (h *harness) MakeWatcher(ctx context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) { + return newWatcher(h.client, name, decoder, nil), nil +} + +func (h *harness) CreateVariable(ctx context.Context, name string, val []byte) error { + _, err := h.client.PutParameter(ctx, &ssm.PutParameterInput{ + Name: aws.String(name), + Type: "String", + Value: aws.String(string(val)), + Overwrite: aws.Bool(true), + }) + return err +} + +func (h *harness) UpdateVariable(ctx context.Context, name string, val []byte) error { + return h.CreateVariable(ctx, name, val) +} + +func (h *harness) DeleteVariable(ctx context.Context, name string) error { + _, err := h.client.DeleteParameter(ctx, &ssm.DeleteParameterInput{Name: aws.String(name)}) + return err +} + +func (h *harness) Close() { + h.closer() +} + +func (h *harness) Mutable() bool { return true } + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct { +} + +func (verifyAs) Name() string { + return "verify As" +} + +func (v verifyAs) SnapshotCheck(s *runtimevar.Snapshot) error { + var getParam *ssm.GetParameterOutput + if !s.As(&getParam) { + return errors.New("Snapshot.As failed for GetParameterOutput") + } + return nil +} + +func (va verifyAs) ErrorCheck(v *runtimevar.Variable, err error) error { + var e smithy.APIError + if !v.ErrorAs(err, &e) { + return errors.New("Keeper.ErrorAs failed") + } + return nil +} + +// Paramstore-specific tests. + +func TestOpenVariable(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"awsparamstore://myvar", false}, + // OK, setting region. + {"awsparamstore://myvar?region=us-west-1", false}, + // OK, setting decoder. + {"awsparamstore://myvar?decoder=string", false}, + // Invalid decoder. + {"awsparamstore://myvar?decoder=notadecoder", true}, + // OK, setting wait. + {"awsparamstore://myvar?wait=2m", false}, + // Invalid wait. + {"awsparamstore://myvar?wait=x", true}, + // Invalid parameter. + {"awsparamstore://myvar?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + v, err := runtimevar.OpenVariable(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if err == nil { + v.Close() + } + } +} diff --git a/go-cloud/runtimevar/awsparamstore/example_test.go b/go-cloud/runtimevar/awsparamstore/example_test.go new file mode 100644 index 000000000..980dd4c5e --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/example_test.go @@ -0,0 +1,59 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 awsparamstore_test + +import ( + "context" + "log" + + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/awsparamstore" +) + +func ExampleOpenVariable() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // Establish a AWS V2 Config. + // See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info. + ctx := context.Background() + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + log.Fatal(err) + } + + // Construct a *runtimevar.Variable that watches the variable. + client := ssm.NewFromConfig(cfg) + v, err := awsparamstore.OpenVariable(client, "cfg-variable-name", runtimevar.StringDecoder, nil) + if err != nil { + log.Fatal(err) + } + defer v.Close() +} + +func Example_openVariableFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/runtimevar/awsparamstore" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // runtimevar.OpenVariable creates a *runtimevar.Variable from a URL. + v, err := runtimevar.OpenVariable(ctx, "awsparamstore://myvar?region=us-west-1&decoder=string") + if err != nil { + log.Fatal(err) + } + defer v.Close() +} diff --git a/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestAs/verify_As.replay b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestAs/verify_As.replay new file mode 100644 index 000000000..ea745e4a0 --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestAs/verify_As.replay @@ -0,0 +1,291 @@ +{ + "Initial": "AQAAAA7gDLJaH0LNWQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "0c2ac2bdaea55381", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "48" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidmFyaWFibGUtZm9yLWFzIiwiV2l0aERlY3J5cHRpb24iOnRydWV9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "50" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "1e5a0f1a-e813-4e71-95ae-cc8f91a5da82" + ] + }, + "Body": "H4sIAAAAAAAA/6tWio8vqSxIVbJSCkgsSsxNLUkt8ssvccsvzUtRqgUAF48DRR4AAAA=" + } + }, + { + "ID": "5b0e7dc9b453e66e", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidmFyaWFibGUtZm9yLWFzIiwiT3ZlcndyaXRlIjp0cnVlLCJUeXBlIjoiU3RyaW5nIiwiVmFsdWUiOiJoZWxsbyB3b3JsZCJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "69e6422a-76bf-4a5b-8f59-4960a947bf29" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMqwFAFB+6N8fAAAA" + } + }, + { + "ID": "3826410a797f491d", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "48" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidmFyaWFibGUtZm9yLWFzIiwiV2l0aERlY3J5cHRpb24iOnRydWV9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "179" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "f3a33ab6-c9e7-4558-94ea-6393286374da" + ] + }, + "Body": "H4sIAAAAAAAA/2XMsQrCMBCA4VeRm1Ol1aTxNqFuWkTF/aRXDaRNSVKrFN9dCjq5/vD9IxzIU8ORPeAIm2MJCORbpCFgCA32IWEKMclwJVUuM6WkzBV2P7V4kDd0tZzUzicUQEBBkc6vjgEh8jOCgB2FuHeVqQ1XBUUGTOe5zHS+1KnWWbpdCyipmcT/7rs6RW/aGwi4kO2ncGdr3Wxw3lZTZR+MawHT9/sDRqq2c9UAAAA=" + } + }, + { + "ID": "5133e2fc2dc4ce81", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "26" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.DeleteParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidmFyaWFibGUtZm9yLWFzIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "22" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "3c6a9171-3c54-493e-a89d-0f3d701ecd16" + ] + }, + "Body": "H4sIAAAAAAAA/6uuBQBDv6ajAgAAAA==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..71f040b9c --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,291 @@ +{ + "Initial": "AQAAAA7gDLJbBN3eSAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "8a86c71a596965d3", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "48" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidmFyaWFibGUtZm9yLWFzIiwiV2l0aERlY3J5cHRpb24iOnRydWV9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "50" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "ab17de99-014d-4b6b-9019-60adf2d92945" + ] + }, + "Body": "H4sIAAAAAAAA/6tWio8vqSxIVbJSCkgsSsxNLUkt8ssvccsvzUtRqgUAF48DRR4AAAA=" + } + }, + { + "ID": "830897d0e1e1eb4e", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "81" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidmFyaWFibGUtZm9yLWFzIiwiT3ZlcndyaXRlIjp0cnVlLCJUeXBlIjoiU3RyaW5nIiwiVmFsdWUiOiJoZWxsbyB3b3JsZCJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "912a6367-c502-4916-959e-d852047bd4a8" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMqwFAFB+6N8fAAAA" + } + }, + { + "ID": "bb21f734fe1c1678", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "48" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidmFyaWFibGUtZm9yLWFzIiwiV2l0aERlY3J5cHRpb24iOnRydWV9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "180" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "c3e2f871-d871-469e-869b-095b413b20c1" + ] + }, + "Body": "H4sIAAAAAAAA/2XMywrCMBBA0V+RWTdKH+ljdkLdaREV9yOdaiBtSpJapfTfpaArtxfOneBIllr2bAEn2J4qQCDbIY0OnWtxcILJeRFhItNMRmkqZZZi/1ObJ1lFN82iMVaQgwBK8nR59wwInl8eAtiT8wdTq0ZxXZJnwHCdySjP4jws4jzZFQFU1C7if/ddnb1V3R0CuJIelvBgrc1qNFbXS2XrlOkAw3n+AOYndmfVAAAA" + } + }, + { + "ID": "7b65e32ca9eef4e2", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "26" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.DeleteParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidmFyaWFibGUtZm9yLWFzIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "22" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:39 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "29471d99-f3d9-4e2d-a85e-7a046630d8e0" + ] + }, + "Body": "H4sIAAAAAAAA/6uuBQBDv6ajAgAAAA==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestDelete.replay b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestDelete.replay new file mode 100644 index 000000000..cfeb557dc --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestDelete.replay @@ -0,0 +1,474 @@ +{ + "Initial": "AQAAAA7gDLJYM2MfpgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "eab96f159ae8ff5d", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "86" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJPdmVyd3JpdGUiOnRydWUsIlR5cGUiOiJTdHJpbmciLCJWYWx1ZSI6ImhlbGxvIHdvcmxkIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "f71de65d-d8ee-46db-b52d-b50be8ba73b5" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMqwFAFB+6N8fAAAA" + } + }, + { + "ID": "b1ea0b30f70fe83b", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJXaXRoRGVjcnlwdGlvbiI6dHJ1ZX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "182" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "71a3e539-d0be-44e4-ba79-ffd591baa395" + ] + }, + "Body": "H4sIAAAAAAAA/23MwQ7BQBCA4VeRObdo2V3mJuGGCOI+dLDJtiu7Q0nTd5cGN9c/+f4GNhSoZOEA2MBsuwYEChVSHTHGEu8xZYqS5jhW2qhca6WMxttPDYSjpCdfne0lfVCwdHQMCcxJaP+6MSAIPwUSWFKUlS/s2XIxJ2HArG9UPjGjSWaGRi+mCayp/Ii/z+9vJ8FWF0jgQO7ehSs753u1D67oKodofQWYte0b4VR32t8AAAA=" + } + }, + { + "ID": "5963148f68c5e552", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.DeleteParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "22" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "554a8886-dae0-4416-bec1-b048257d2763" + ] + }, + "Body": "H4sIAAAAAAAA/6uuBQBDv6ajAgAAAA==" + } + }, + { + "ID": "7f27623246634edb", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJXaXRoRGVjcnlwdGlvbiI6dHJ1ZX0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "50" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "85d6f3f4-f479-44aa-b985-40ff705fcee0" + ] + }, + "Body": "H4sIAAAAAAAA/6tWio8vqSxIVbJSCkgsSsxNLUkt8ssvccsvzUtRqgUAF48DRR4AAAA=" + } + }, + { + "ID": "9658e8dbb5d9f4a2", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "88" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJPdmVyd3JpdGUiOnRydWUsIlR5cGUiOiJTdHJpbmciLCJWYWx1ZSI6Imdvb2RieWUgd29ybGQifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "960f22ca-32db-4af0-96d1-e5ad2bd36112" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMqwFAFB+6N8fAAAA" + } + }, + { + "ID": "dbbdabdc4a35a755", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJXaXRoRGVjcnlwdGlvbiI6dHJ1ZX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "185" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "751fe630-23e0-48f5-843d-633b6db5a6f6" + ] + }, + "Body": "H4sIAAAAAAAA/23MTQuCQBCA4b8Sc9ZCbV2bW2C3kqjoPuUoC+rG7tgH4n8PqW5dX3jeAfbkqGVhBzjA+lAAArkO6eHR+xZ7HzJ5CWNcqlSrOE2V0inefmoh7CW82q4ydXgnZ+jSMASQk9DpdWNAEH4KBLAlLztbmspwmZMwYDTXKs50kkV6mSSbVQAFtR/x9/n9HcWZroYAztT0U6itLS8vnj2sa8qps/PGdoDROL4B7MbvDeEAAAA=" + } + }, + { + "ID": "6dbdfe5165baba8a", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.DeleteParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "22" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "3b9ecb1d-f09e-4cba-a7c2-ace195f33a46" + ] + }, + "Body": "H4sIAAAAAAAA/6uuBQBDv6ajAgAAAA==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestInvalidJSON.replay b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestInvalidJSON.replay new file mode 100644 index 000000000..a0e6ba26b --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestInvalidJSON.replay @@ -0,0 +1,230 @@ +{ + "Initial": "AQAAAA7gDLJXK5ijdwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "616c0cabb4f33ee9", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "83" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJPdmVyd3JpdGUiOnRydWUsIlR5cGUiOiJTdHJpbmciLCJWYWx1ZSI6Im5vdC1qc29uIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "580eccf7-a164-44a7-924d-3e352f3ab367" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMqwFAFB+6N8fAAAA" + } + }, + { + "ID": "4050215df5e18905", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJXaXRoRGVjcnlwdGlvbiI6dHJ1ZX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "179" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "de2409ca-87c7-4603-905c-2a641798211d" + ] + }, + "Body": "H4sIAAAAAAAA/23MTQ/BQBCA4f8y5y5pdVvmJqkbIoj7YNqs6K7sjK80/e8iuLm+yfN2sKJILStHwA6m6yUgUPRId0GRFq9imERNhrktSpsVhbVlgZefGiqLmkPwtWvMjaKj/ZkhgYqUts8LA4LyQyGBOYkuwtHVjo8VKQOmg9Jm43I0Tu0kz2eTBJbUfsTf5/e30eh8Awns6Hx9Bx/UnCT4d+IoLnjAtO9ftL/bQ9wAAAA=" + } + }, + { + "ID": "a2b4aa168665aa53", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.DeleteParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "22" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "3c8fa3f1-f194-4fff-8c73-9b8c8bfeaad8" + ] + }, + "Body": "H4sIAAAAAAAA/6uuBQBDv6ajAgAAAA==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestJSON.replay b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestJSON.replay new file mode 100644 index 000000000..a00ca0d76 --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestJSON.replay @@ -0,0 +1,230 @@ +{ + "Initial": "AQAAAA7gDLJXD8INTAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "1a58444121efddc3", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "177" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJPdmVyd3JpdGUiOnRydWUsIlR5cGUiOiJTdHJpbmciLCJWYWx1ZSI6IltcbntcIk5hbWVcIjogXCJFZFwiLCBcIlRleHRcIjogXCJLbm9jayBrbm9jay5cIn0sXG57XCJOYW1lXCI6IFwiU2FtXCIsIFwiVGV4dFwiOiBcIldobydzIHRoZXJlP1wifVxuXSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "4335ec77-8ce4-4df2-b4f2-a74bd0d012a5" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMqwFAFB+6N8fAAAA" + } + }, + { + "ID": "17547e42bc8209f3", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJXaXRoRGVjcnlwdGlvbiI6dHJ1ZX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "235" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "9b1d283a-4e92-441e-805e-c2c430294aca" + ] + }, + "Body": "H4sIAAAAAAAA/23NQU/CQBQE4L/SzMXLFtPKtnUvxgROKjFC9OB6eNIHbKBbsvtQTNP/bip6IV7mMMk30+GRAjUsHGA63D7NYEDBG/qMJsbGHGLKFCXNzVgXpc6LQuuyMPs/dSkcJV22fuXW6QcFR+87hsKEhBZfe4aB8FGgcE9RHtrarRzXExKGyUalzqvyqsr0uMqm1wozak7i383fvbkE59dQeKbdYShere/sj7UwicW0tlCJxYKPcmrufLvcJtshRxa9OgNzas7Fy6a9iIlsOPCNRW/923DIIbrWw2R9/w30BdaMOgEAAA==" + } + }, + { + "ID": "a1cbfe156fdaac88", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.DeleteParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "22" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "20179fc6-8791-47aa-9606-be1ea717d38e" + ] + }, + "Body": "H4sIAAAAAAAA/6uuBQBDv6ajAgAAAA==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestNonExistentVariable.replay b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestNonExistentVariable.replay new file mode 100644 index 000000000..89c889fb4 --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestNonExistentVariable.replay @@ -0,0 +1,108 @@ +{ + "Initial": "AQAAAA7gDLJQMkQaCwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "6729b0fb8fa4c9b3", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "47" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoiZG9lcy1ub3QtZXhpc3QiLCJXaXRoRGVjcnlwdGlvbiI6dHJ1ZX0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "50" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:29 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "29ad4c9b-d2c3-4882-9d54-33e7c280104a" + ] + }, + "Body": "H4sIAAAAAAAA/6tWio8vqSxIVbJSCkgsSsxNLUkt8ssvccsvzUtRqgUAF48DRR4AAAA=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestString.replay b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestString.replay new file mode 100644 index 000000000..ff6056af5 --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestString.replay @@ -0,0 +1,230 @@ +{ + "Initial": "AQAAAA7gDLJRLWwChgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "65696137ef751be3", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "86" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJPdmVyd3JpdGUiOnRydWUsIlR5cGUiOiJTdHJpbmciLCJWYWx1ZSI6ImhlbGxvIHdvcmxkIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "ced048eb-3b8f-42b8-a15f-1bb352b46ade" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMqwFAFB+6N8fAAAA" + } + }, + { + "ID": "0b6d743b6c50425a", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJXaXRoRGVjcnlwdGlvbiI6dHJ1ZX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "179" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:30 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "1192bd0e-6981-45d2-b4dc-75d66dafb6cd" + ] + }, + "Body": "H4sIAAAAAAAA/22MywrCMBAAf0X2nCqtJtW9CfWmIireV7utgbSRZH1R+u8i6s3rMDMdbChQw8IBsIP5dg0IFFqke8QYG7zGhClKkuFEm1xnxmidG7z8qpFwlOTk28rWyY2CpaNjUFCQ0P55YUAQfggoWFKUlS9tZbksSBgwHeY6m+bjabqYKVhT87H//r6vnQTb1qDgQO76Bmd2zg/uPrjyTTlE61vAtO9f1DUs3tsAAAA=" + } + }, + { + "ID": "c4a5c5a587091460", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.DeleteParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "22" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:35 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "4db321a1-7d81-4810-a7f7-6082e72bfbeb" + ] + }, + "Body": "H4sIAAAAAAAA/6uuBQBDv6ajAgAAAA==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestUpdate.replay b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestUpdate.replay new file mode 100644 index 000000000..a41ce4037 --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestUpdate.replay @@ -0,0 +1,413 @@ +{ + "Initial": "AQAAAA7gDLJYCun7XQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "ba98ac78609aeced", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "86" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJPdmVyd3JpdGUiOnRydWUsIlR5cGUiOiJTdHJpbmciLCJWYWx1ZSI6ImhlbGxvIHdvcmxkIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "2dac112f-9ab6-46f6-acdf-05145b8311b2" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMqwFAFB+6N8fAAAA" + } + }, + { + "ID": "58036211c18abe74", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJXaXRoRGVjcnlwdGlvbiI6dHJ1ZX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "183" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "3f2ca4fb-7164-4948-9938-a13fe0f11380" + ] + }, + "Body": "H4sIAAAAAAAA/23MTQuCQBCA4b8Sc9ZCbVebW2C3iqjoPuVoC6sru9MX0X8PqW5dX3jeJ2zIU8vCHvAJ8+0aEMh3SLeAIbR4CTFTkDjFqdK5SrVWKtfY/9REOEh8cl1tmvhK3tDRMkRQktD+0TMgCN8FIlhSkJWrTG24KkkYMBnnKi3yrEh0NpsuZhGsqf2Iv8/vbyfedA1EcCB7GcKZrXWjm/O2Gir7YFwHmLxebw/AGlDfAAAA" + } + }, + { + "ID": "5b5a685bc9b69fb7", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJXaXRoRGVjcnlwdGlvbiI6dHJ1ZX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "183" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "373a901b-b30a-499c-b6f6-00727eb50381" + ] + }, + "Body": "H4sIAAAAAAAA/23MTQuCQBCA4b8Sc9ZCbVebW2C3iqjoPuVoC6sru9MX0X8PqW5dX3jeJ2zIU8vCHvAJ8+0aEMh3SLeAIbR4CTFTkDjFqdK5SrVWKtfY/9REOEh8cl1tmvhK3tDRMkRQktD+0TMgCN8FIlhSkJWrTG24KkkYMBnnKi3yrEh0NpsuZhGsqf2Iv8/vbyfedA1EcCB7GcKZrXWjm/O2Gir7YFwHmLxebw/AGlDfAAAA" + } + }, + { + "ID": "9317ba039aae096c", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "88" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJPdmVyd3JpdGUiOnRydWUsIlR5cGUiOiJTdHJpbmciLCJWYWx1ZSI6Imdvb2RieWUgd29ybGQifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "346504a2-5e9c-40d4-a2f0-94ea7c3d0411" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMqoFAJMtxfQfAAAA" + } + }, + { + "ID": "d761be96eb8df9f4", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJXaXRoRGVjcnlwdGlvbiI6dHJ1ZX0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "184" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "6c9a1bdf-a7b1-46e0-854b-204582c8216c" + ] + }, + "Body": "H4sIAAAAAAAA/23MTQuCQBCA4b8Sc9ZCbVebW2C3iqjoPuYoC+rK7vSF+N9DqlvXF553gAM5alnYAQ6wPu4BgVyH9PDofYs3HzJ5CWNcKp2qWGulUo39Ty2EvYRX21WmDu/kDBUNQwA5CZ1fPQOC8FMggC152dnSVIbLnIQBo3mq4ixNskjrJNmsAthT+xF/n9/fSZzpagjgQs1tCrW1ZfHi2cO6ppw6O29sBxiP4xvalNYk4QAAAA==" + } + }, + { + "ID": "0992bdc8dbfd5e9d", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "31" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.DeleteParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "22" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:36 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "0e3e5ef6-ab68-421f-81f9-b0a54f9a2007" + ] + }, + "Body": "H4sIAAAAAAAA/6uuBQBDv6ajAgAAAA==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestUpdateWithErrors.replay b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestUpdateWithErrors.replay new file mode 100644 index 000000000..622617bb8 --- /dev/null +++ b/go-cloud/runtimevar/awsparamstore/testdata/TestConformance/TestUpdateWithErrors.replay @@ -0,0 +1,474 @@ +{ + "Initial": "AQAAAA7gDLJZJ/zUoAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "2ea674602b8353c0", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "126" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvciIsIk92ZXJ3cml0ZSI6dHJ1ZSwiVHlwZSI6IlN0cmluZyIsIlZhbHVlIjoiW3tcIk5hbWVcIjogXCJGb29cIiwgXCJUZXh0XCI6IFwiQmFyXCJ9XSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "372fc167-db54-4a21-b595-2503d49801fc" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMqwFAFB+6N8fAAAA" + } + }, + { + "ID": "323cb725a95685d9", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "64" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvciIsIldpdGhEZWNyeXB0aW9uIjp0cnVlfQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "210" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:37 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "da5241be-9622-475a-b9dd-1a2e29ce1a25" + ] + }, + "Body": "H4sIAAAAAAAA/4XMwUrDQBRG4Vcp/3pGSWoy8e6U1pUW0eLG6eJKrmWgyYSZG62EvLvU6trtge9MeOTEnagk0ISbpw0InHriz0w5dzRmK5zVlnRV1a4q67qqXE3Dn7pUyWrHoWUN/d5+cAr8dhCr0UpKMcFgxcrbr0FAUDkqDO4560Nsw3uQdsUqoOLCVWXjlk3hmsatrw023J3Ff/vf9bOm0O9h8MKH8RReJ/8z8aCFx12MHmbhsZWjntMtJ495dyKScog9qJjnb1faNVcSAQAA" + } + }, + { + "ID": "c5065543b67de27a", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "98" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvciIsIk92ZXJ3cml0ZSI6dHJ1ZSwiVHlwZSI6IlN0cmluZyIsIlZhbHVlIjoiaW52YWxpZC1qc29uIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "07cf03dc-f126-4b1f-9149-b3449f74a8c2" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMqoFAJMtxfQfAAAA" + } + }, + { + "ID": "294b99267c5c75f6", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "64" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvciIsIldpdGhEZWNyeXB0aW9uIjp0cnVlfQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "191" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "f8920ed8-d590-4940-9ee7-971cb5f10e13" + ] + }, + "Body": "H4sIAAAAAAAA/4XMwUrDQBCA4XeZc7aatJuNcyukNy1Fi/eRjGEl2Q0zk7ZS+u4SrGevP3z/FQ4kNLKxAF5h+7oHBJKEdFZUHXFWx6TmKtz4Oviqrr0PNU5/6sFYzc1TRxZT704kkT4GdpYdi2SBAloyOn5PDAjGF4MCnkntJXfxM3LXkjFguQq+asK6KZvHsHsqYE/jL/jvfj+/mcTUQwHvNMxLiOlEQ+zcl+a0ZBaNOQFWt9sPmM35FPUAAAA=" + } + }, + { + "ID": "9376f62304635945", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "99" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.PutParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvciIsIk92ZXJ3cml0ZSI6dHJ1ZSwiVHlwZSI6IlN0cmluZyIsIlZhbHVlIjoiaW52YWxpZC1qc29uMiJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "51" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "7fc582b4-5271-459f-aa0d-8227bb01ed8b" + ] + }, + "Body": "H4sIAAAAAAAA/6tWCslMLVKyUgouScxLSSxKUdJRCkstKs7Mz1OyMq4FANIc3u0fAAAA" + } + }, + { + "ID": "15fa50a6c9bb0278", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "64" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.GetParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvciIsIldpdGhEZWNyeXB0aW9uIjp0cnVlfQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "192" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "f0ca72ca-7a0c-454c-9a0a-25aeccd5f493" + ] + }, + "Body": "H4sIAAAAAAAA/4XMTWvCQBCA4f8y56zixk3SuQn2piJaeh/JVLYku2Fm4gfify+iPXt94XlvsCWhno0F8AaL3QYQSBLSWVG1x1Edk5rzOA9VHXxVhVBXOPyrqbGaG4eWLKajO5FEOnTsLDsWyQIFLMno6zowIBhfDApYkdo6t/EncrskY8DZpA6+qctm1vh5+flRwIb6p3i3f633JjEdoYBv6sZHiOlEXWzdr+bkH51FY06A5f3+B5bs5un3AAAA" + } + }, + { + "ID": "f0a3c0f84fc1a79d", + "Request": { + "Method": "POST", + "URL": "https://ssm.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "42" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "AmazonSSM.DeleteParameter" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJOYW1lIjoidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvciJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Encoding": [ + "gzip" + ], + "Content-Length": [ + "22" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:38 GMT" + ], + "Server": [ + "Server" + ], + "X-Amzn-Requestid": [ + "cb257be2-fb0c-4943-91d1-f6a176dc8282" + ] + }, + "Body": "H4sIAAAAAAAA/6uuBQBDv6ajAgAAAA==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/awssecretsmanager.go b/go-cloud/runtimevar/awssecretsmanager/awssecretsmanager.go new file mode 100644 index 000000000..f4ef40b6c --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/awssecretsmanager.go @@ -0,0 +1,360 @@ +// Copyright 2020 The Go Cloud Development Kit 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 +// +// https://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 awssecretsmanager provides a runtimevar implementation with variables +// read from AWS Secrets Manager (https://aws.amazon.com/secrets-manager) +// Use OpenVariable to construct a *runtimevar.Variable. +// +// # URLs +// +// For runtimevar.OpenVariable, awssecretsmanager registers for the scheme "awssecretsmanager". +// The default URL opener will use an AWS session with the default credentials +// and configuration. +// +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// awssecretsmanager exposes the following types for As: +// - Snapshot: *secretsmanager.GetSecretValueOutput, *secretsmanager.DescribeSecretOutput +// - Error: any error type returned by the service, notably smithy.APIError +package awssecretsmanager // import "gocloud.dev/runtimevar/awssecretsmanager" + +import ( + "context" + "errors" + "fmt" + "net/url" + "path" + "strings" + "sync" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager/types" + "github.com/aws/smithy-go" + "github.com/google/wire" + gcaws "github.com/DataDog/iceberg-go/go-cloud/aws" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" +) + +func init() { + runtimevar.DefaultURLMux().RegisterVariable(Scheme, new(lazySessionOpener)) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + Dial, +) + +// Dial gets an AWS secretsmanager service client using the AWS SDK V2. +func Dial(cfg aws.Config) *secretsmanager.Client { + return secretsmanager.NewFromConfig(cfg) +} + +// URLOpener opens AWS Secrets Manager URLs like "awssecretsmanager://my-secret-var-name". +// A friendly name of the secret must be specified. You can NOT specify the Amazon Resource Name (ARN). +// +// See https://pkg.go.dev/gocloud.dev/aws#V2ConfigFromURLParams. +// +// In addition, the following URL parameters are supported: +// - decoder: The decoder to use. Defaults to URLOpener.Decoder, or +// runtimevar.BytesDecoder if URLOpener.Decoder is nil. +// See runtimevar.DecoderByName for supported values. +// - wait: The poll interval, in time.ParseDuration formats. +// Defaults to 30s. +type URLOpener struct { + // Decoder specifies the decoder to use if one is not specified in the URL. + // Defaults to runtimevar.BytesDecoder. + Decoder *runtimevar.Decoder + + // Options specifies the options to pass to New. + Options Options +} + +// lazySessionOpener obtains the AWS session from the environment on the first +// call to OpenVariableURL. +type lazySessionOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazySessionOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + opener := &URLOpener{} + return opener.OpenVariableURL(ctx, u) +} + +// Scheme is the URL scheme awssecretsmanager registers its URLOpener under on runtimevar.DefaultMux. +const Scheme = "awssecretsmanager" + +// OpenVariableURL opens the variable at the URL's path. See the package doc +// for more details. +func (o *URLOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + q := u.Query() + + decoderName := q.Get("decoder") + q.Del("decoder") + decoder, err := runtimevar.DecoderByName(ctx, decoderName, o.Decoder) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid decoder: %v", u, err) + } + opts := o.Options + if s := q.Get("wait"); s != "" { + q.Del("wait") + d, err := time.ParseDuration(s) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid wait %q: %v", u, s, err) + } + opts.WaitDuration = d + } + cfg, err := gcaws.V2ConfigFromURLParams(ctx, q) + if err != nil { + return nil, fmt.Errorf("open variable %v: %v", u, err) + } + return OpenVariable(secretsmanager.NewFromConfig(cfg), path.Join(u.Host, u.Path), decoder, &opts) +} + +// Options sets options. +type Options struct { + // WaitDuration controls the rate at which AWS Secrets Manager is polled. + // Defaults to 30 seconds. + WaitDuration time.Duration +} + +// OpenVariable constructs a *runtimevar.Variable backed by the variable name in AWS Secrets Manager, +// using AWS SDK V2. +// A friendly name of the secret must be specified. You can NOT specify the Amazon Resource Name (ARN). +// Secrets Manager returns raw bytes; provide a decoder to decode the raw bytes +// into the appropriate type for runtimevar.Snapshot.Value. +// See the runtimevar package documentation for examples of decoders. +func OpenVariable(client *secretsmanager.Client, name string, decoder *runtimevar.Decoder, opts *Options) (*runtimevar.Variable, error) { + return runtimevar.New(newWatcher(client, name, decoder, opts)), nil +} + +var OpenVariableV2 = OpenVariable + +// state implements driver.State. +type state struct { + val any + rawGet *secretsmanager.GetSecretValueOutput + rawDesc *secretsmanager.DescribeSecretOutput + updateTime time.Time + versionID string + err error +} + +// Value implements driver.State.Value. +func (s *state) Value() (any, error) { + return s.val, s.err +} + +// UpdateTime implements driver.State.UpdateTime. +func (s *state) UpdateTime() time.Time { + return s.updateTime +} + +// As implements driver.State.As. +func (s *state) As(i any) bool { + switch p := i.(type) { + case **secretsmanager.GetSecretValueOutput: + *p = s.rawGet + case **secretsmanager.DescribeSecretOutput: + *p = s.rawDesc + default: + return false + } + return true +} + +// errorState returns a new State with err, unless prevS also represents +// the same error, in which case it returns nil. +func errorState(err error, prevS driver.State) driver.State { + // Map to the more standard context package error. + if strings.Contains(err.Error(), "context deadline exceeded") { + err = context.DeadlineExceeded + } else if getErrorCode(err) == "CancelledError" { + err = context.Canceled + } + s := &state{err: err} + if prevS == nil { + return s + } + prev := prevS.(*state) + if prev.err == nil { + // New error. + return s + } + if equivalentError(err, prev.err) { + // Same error, return nil to indicate no change. + return nil + } + return s +} + +// equivalentError returns true iff err1 and err2 represent an equivalent error; +// i.e., we don't want to return it to the user as a different error. +func equivalentError(err1, err2 error) bool { + if err1 == err2 || err1.Error() == err2.Error() { + return true + } + code1 := getErrorCode(err1) + code2 := getErrorCode(err2) + return code1 != "" && code1 == code2 +} + +type watcher struct { + // client is the client to use. + client *secretsmanager.Client + // name is an ID of a secret to retrieve. + name string + // wait is the amount of time to wait between querying AWS. + wait time.Duration + // decoder is the decoder that unmarshalls the value in the param. + decoder *runtimevar.Decoder +} + +func newWatcher(client *secretsmanager.Client, name string, decoder *runtimevar.Decoder, opts *Options) *watcher { + if opts == nil { + opts = &Options{} + } + return &watcher{ + client: client, + name: name, + wait: driver.WaitDuration(opts.WaitDuration), + decoder: decoder, + } +} + +func getSecretValue(ctx context.Context, client *secretsmanager.Client, secretID string) (string, []byte, string, *secretsmanager.GetSecretValueOutput, error) { + getResp, err := client.GetSecretValue(ctx, &secretsmanager.GetSecretValueInput{ + SecretId: aws.String(secretID), + }) + if err != nil { + return "", nil, "", nil, err + } + return aws.ToString(getResp.VersionId), getResp.SecretBinary, aws.ToString(getResp.SecretString), getResp, nil +} + +func describeSecret(ctx context.Context, client *secretsmanager.Client, secretID string) (time.Time, *secretsmanager.DescribeSecretOutput, error) { + descResp, err := client.DescribeSecret(ctx, &secretsmanager.DescribeSecretInput{ + SecretId: aws.String(secretID), + }) + if err != nil { + return time.Time{}, nil, err + } + return aws.ToTime(descResp.LastChangedDate), descResp, nil +} + +// WatchVariable implements driver.WatchVariable. +func (w *watcher) WatchVariable(ctx context.Context, prev driver.State) (driver.State, time.Duration) { + var lastVersionID string + if prev != nil { + lastVersionID = prev.(*state).versionID + } + + // GetParameter from S3 to get the current value and version. + newVersionID, newValBinary, newValString, rawGet, err := getSecretValue(ctx, w.client, w.name) + if err != nil { + return errorState(err, prev), w.wait + } + if newVersionID == lastVersionID { + // Version hasn't changed, so no change; return nil. + return nil, w.wait + } + // Both SecretBinary and SecretString fields are not empty + // which could indicate some internal Secrets Manager issues. + // Hence, return explicit error instead of choosing one field over another. + if len(newValBinary) > 0 && newValString != "" { + err = fmt.Errorf("invalid %q response: both SecretBinary and SecretString are not empty", w.name) + return errorState(err, prev), w.wait + } + + data := newValBinary + if len(data) == 0 { + if newValString == "" { + err = fmt.Errorf("invalid %q response: both SecretBinary and SecretString are empty", w.name) + return errorState(err, prev), w.wait + } + // SecretBinary is empty so use SecretString + data = []byte(newValString) + } + + // DescribeParameters from S3 to get the LastModified date. + newLastModified, rawDesc, err := describeSecret(ctx, w.client, w.name) + if err != nil { + return errorState(err, prev), w.wait + } + + // New value (or at least, new version). Decode it. + val, err := w.decoder.Decode(ctx, data) + if err != nil { + return errorState(err, prev), w.wait + } + + return &state{ + val: val, + rawGet: rawGet, + rawDesc: rawDesc, + updateTime: newLastModified, + versionID: newVersionID, + }, w.wait +} + +// Close implements driver.Close. +func (w *watcher) Close() error { + return nil +} + +// ErrorAs implements driver.ErrorAs. +func (w *watcher) ErrorAs(err error, i any) bool { + return errors.As(err, i) +} + +func getErrorCode(err error) string { + var ae smithy.APIError + if errors.As(err, &ae) { + return ae.ErrorCode() + } + return "" +} + +// ErrorCode implements driver.ErrorCode. +func (w *watcher) ErrorCode(err error) gcerrors.ErrorCode { + code := getErrorCode(err) + ec, ok := errorCodeMap[code] + if !ok { + return gcerrors.Unknown + } + return ec +} + +var errorCodeMap = map[string]gcerrors.ErrorCode{ + (&types.ResourceNotFoundException{}).ErrorCode(): gcerrors.NotFound, + (&types.InvalidParameterException{}).ErrorCode(): gcerrors.InvalidArgument, + (&types.InvalidRequestException{}).ErrorCode(): gcerrors.InvalidArgument, + (&types.InvalidNextTokenException{}).ErrorCode(): gcerrors.InvalidArgument, + (&types.EncryptionFailure{}).ErrorCode(): gcerrors.Internal, + (&types.DecryptionFailure{}).ErrorCode(): gcerrors.Internal, + (&types.InternalServiceError{}).ErrorCode(): gcerrors.Internal, + (&types.ResourceExistsException{}).ErrorCode(): gcerrors.AlreadyExists, + (&types.PreconditionNotMetException{}).ErrorCode(): gcerrors.FailedPrecondition, + (&types.MalformedPolicyDocumentException{}).ErrorCode(): gcerrors.FailedPrecondition, + (&types.LimitExceededException{}).ErrorCode(): gcerrors.ResourceExhausted, +} diff --git a/go-cloud/runtimevar/awssecretsmanager/awssecretsmanager_test.go b/go-cloud/runtimevar/awssecretsmanager/awssecretsmanager_test.go new file mode 100644 index 000000000..f7b34875e --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/awssecretsmanager_test.go @@ -0,0 +1,266 @@ +// Copyright 2020 The Go Cloud Development Kit 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 +// +// https://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 awssecretsmanager + +import ( + "bytes" + "context" + "crypto/sha1" + "errors" + "fmt" + "testing" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/smithy-go" + "github.com/googleapis/gax-go/v2" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/retry" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/drivertest" +) + +// This constant records the region used for the last --record. +// If you want to use --record mode, +// 1. Update this constant to your AWS region. +// TODO(issue #300): Use Terraform to get this. +const region = "us-east-2" + +type harness struct { + client *secretsmanager.Client + closer func() +} + +// waitForMutation uses check to wait until a mutation has taken effect. +// The check function should return nil to indicate success (the mutation has +// taken effect), an error with gcerrors.ErrorCode == NotFound to trigger +// a retry, or any other error to signal permanent failure. +func waitForMutation(ctx context.Context, check func() error) error { + backoff := gax.Backoff{Multiplier: 1.0} + var initial time.Duration + if *setup.Record { + // When recording, wait 3 seconds and then poll every 2s. + initial = 3 * time.Second + backoff.Initial = 2 * time.Second + } else { + // During replay, we don't wait at all. + // The recorded file may have retries, but we don't need to actually wait between them. + backoff.Initial = 1 * time.Millisecond + } + backoff.Max = backoff.Initial + + // Sleep before the check, since we know it doesn't take effect right away. + time.Sleep(initial) + + // retryIfNotFound returns true if err is NotFound. + retryIfNotFound := func(err error) bool { return gcerrors.Code(err) == gcerrors.NotFound } + + // Poll until the mtuation is seen. + return retry.Call(ctx, backoff, retryIfNotFound, check) +} + +// AWS Secrets Manager requires unique token for Create and Update requests to ensure idempotency. +// From the other side, request data must be deterministic in order to make tests reproducible. +// generateClientRequestToken generates token which is unique per test session but deterministic. +func generateClientRequestToken(name string, data []byte) string { + const maxClientRequestTokenLen = 64 + h := sha1.New() + _, _ = h.Write(data) + + token := fmt.Sprintf("%s-%x", name, h.Sum(nil)) + + // Token must have length less than or equal to 64 + if len(token) > maxClientRequestTokenLen { + token = token[:maxClientRequestTokenLen] + } + + return token +} + +func newHarness(t *testing.T) (drivertest.Harness, error) { + t.Helper() + + cfg, _, done, _ := setup.NewAWSv2Config(context.Background(), t, region, false) + return &harness{ + client: secretsmanager.NewFromConfig(cfg), + closer: done, + }, nil +} + +func (h *harness) MakeWatcher(_ context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) { + return newWatcher(h.client, name, decoder, nil), nil +} + +func (h *harness) CreateVariable(ctx context.Context, name string, val []byte) error { + if _, err := h.client.CreateSecret(ctx, &secretsmanager.CreateSecretInput{ + Name: aws.String(name), + ClientRequestToken: aws.String(generateClientRequestToken(name, val)), + SecretBinary: val, + }); err != nil { + return err + } + // Secret Manager is only eventually consistent, so we retry until we've + // verified that the mutation was applied. This is still not a guarantee + // but in practice seems to work well enough to make tests repeatable. + return waitForMutation(ctx, func() error { + _, err := h.client.GetSecretValue(ctx, &secretsmanager.GetSecretValueInput{SecretId: aws.String(name)}) + if err == nil { + // Create was seen. + return nil + } + // Failure; we'll retry if it's a NotFound. + w := &watcher{} + return gcerr.New(w.ErrorCode(err), err, 1, "runtimevar") + }) +} + +func (h *harness) UpdateVariable(ctx context.Context, name string, val []byte) error { + if _, err := h.client.PutSecretValue(ctx, &secretsmanager.PutSecretValueInput{ + ClientRequestToken: aws.String(generateClientRequestToken(name, val)), + SecretBinary: val, + SecretId: aws.String(name), + }); err != nil { + return err + } + // Secret Manager is only eventually consistent, so we retry until we've + // verified that the mutation was applied. This is still not a guarantee + // but in practice seems to work well enough to make tests repeatable. + return waitForMutation(ctx, func() error { + var err error + var bb []byte + var getResp *secretsmanager.GetSecretValueOutput + getResp, err = h.client.GetSecretValue(ctx, &secretsmanager.GetSecretValueInput{SecretId: aws.String(name)}) + if err == nil { + bb = getResp.SecretBinary + } + if err != nil { + // Failure; we'll retry if it's a NotFound, but that's not + // really expected for an Update. + w := &watcher{} + return gcerr.New(w.ErrorCode(err), err, 1, "runtimevar") + } + if !bytes.Equal(bb, val) { + // Value hasn't been updated yet, return a NotFound to + // trigger retry. + return gcerr.Newf(gcerr.NotFound, nil, "updated value not seen yet") + } + // Update was seen. + return nil + }) +} + +func (h *harness) DeleteVariable(ctx context.Context, name string) error { + if _, err := h.client.DeleteSecret(ctx, &secretsmanager.DeleteSecretInput{ + ForceDeleteWithoutRecovery: aws.Bool(true), + SecretId: aws.String(name), + }); err != nil { + return err + } + // Secret Manager is only eventually consistent, so we retry until we've + // verified that the mutation was applied. This is still not a guarantee + // but in practice seems to work well enough to make tests repeatable. + // Note that "success" after a delete is a NotFound error, so we massage + // the err returned from DescribeSecret to reflect that. + return waitForMutation(ctx, func() error { + _, err := h.client.DescribeSecret(ctx, &secretsmanager.DescribeSecretInput{SecretId: aws.String(name)}) + if err == nil { + // Secret still exists, return a NotFound to trigger a retry. + return gcerr.Newf(gcerr.NotFound, nil, "delete not seen yet") + } + w := &watcher{} + if w.ErrorCode(err) == gcerrors.NotFound { + // Delete was seen. + return nil + } + // Other errors are not retryable. + return gcerr.New(w.ErrorCode(err), err, 1, "runtimevar") + }) +} + +func (h *harness) Close() { + h.closer() +} + +func (h *harness) Mutable() bool { return true } + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct { +} + +func (verifyAs) Name() string { + return "verify As" +} + +func (v verifyAs) SnapshotCheck(s *runtimevar.Snapshot) error { + var getParam *secretsmanager.GetSecretValueOutput + if !s.As(&getParam) { + return errors.New("Snapshot.As failed for GetSecretValueOutput") + } + var descParam *secretsmanager.DescribeSecretOutput + if !s.As(&descParam) { + return errors.New("Snapshot.As failed for DescribeSecretOutput") + } + return nil +} + +func (va verifyAs) ErrorCheck(v *runtimevar.Variable, err error) error { + var e smithy.APIError + if !v.ErrorAs(err, &e) { + return errors.New("Keeper.ErrorAs failed") + } + return nil +} + +// Secrets Manager-specific tests. + +func TestOpenVariable(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"awssecretsmanager://myvar", false}, + // OK, setting region. + {"awssecretsmanager://myvar?region=us-west-1", false}, + // OK, setting decoder. + {"awssecretsmanager://myvar?decoder=string", false}, + // Invalid decoder. + {"awssecretsmanager://myvar?decoder=notadecoder", true}, + // OK, setting wait. + {"awssecretsmanager://myvar?wait=5m", false}, + // Invalid wait. + {"awssecretsmanager://myvar?wait=xx", true}, + // Invalid parameter. + {"awssecretsmanager://myvar?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + v, err := runtimevar.OpenVariable(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if err == nil { + v.Close() + } + } +} diff --git a/go-cloud/runtimevar/awssecretsmanager/example_test.go b/go-cloud/runtimevar/awssecretsmanager/example_test.go new file mode 100644 index 000000000..686645481 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/example_test.go @@ -0,0 +1,61 @@ +// Copyright 2020 The Go Cloud Development Kit 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 +// +// https://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 awssecretsmanager_test + +import ( + "context" + "log" + + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/awssecretsmanager" +) + +func ExampleOpenVariable() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // Establish a AWS V2 Config. + // See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info. + ctx := context.Background() + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + log.Fatal(err) + } + + // Construct a *runtimevar.Variable that watches the variable. + // `secret-variable-name` must be a friendly name of the secret, NOT the Amazon Resource Name (ARN). + client := secretsmanager.NewFromConfig(cfg) + v, err := awssecretsmanager.OpenVariable(client, "secret-variable-name", runtimevar.StringDecoder, nil) + if err != nil { + log.Fatal(err) + } + defer v.Close() +} + +func Example_openVariableFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/runtimevar/awssecretsmanager" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // runtimevar.OpenVariable creates a *runtimevar.Variable from a URL. + // `secret-variable-name` must be a friendly name of the secret, NOT the Amazon Resource Name (ARN). + v, err := runtimevar.OpenVariable(ctx, "awssecretsmanager://secret-variable-name?region=us-east-2&decoder=string") + if err != nil { + log.Fatal(err) + } + defer v.Close() +} diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestAs/verify_As.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestAs/verify_As.replay new file mode 100644 index 000000000..a0bc576fc --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestAs/verify_As.replay @@ -0,0 +1,487 @@ +{ + "Initial": "AQAAAA7gDLKxIeGBiAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "5d7f200bc6839912", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:05 GMT" + ], + "X-Amzn-Requestid": [ + "4c7bbad3-c876-4cbc-b6f9-a388f8e0beaa" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + }, + { + "ID": "08c01c8440654591", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "140" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9In0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "181" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:06 GMT" + ], + "X-Amzn-Requestid": [ + "229af00f-de65-4f95-b143-cd2593318fe0" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RUmFMMWoiLCJOYW1lIjoidmFyaWFibGUtZm9yLWFzIiwiVmVyc2lvbklkIjoidmFyaWFibGUtZm9yLWFzLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQifQ==" + } + }, + { + "ID": "92c59c51bd014cbd", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:09 GMT" + ], + "X-Amzn-Requestid": [ + "ca443464-d951-4d33-b55a-930124471686" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RUmFMMWoiLCJDcmVhdGVkRGF0ZSI6MS43NTI4NzM5MDYxNzFFOSwiTmFtZSI6InZhcmlhYmxlLWZvci1hcyIsIlNlY3JldEJpbmFyeSI6ImFHVnNiRzhnZDI5eWJHUT0iLCJWZXJzaW9uSWQiOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "64edcc1ba19062b2", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:09 GMT" + ], + "X-Amzn-Requestid": [ + "7b7d6cd8-f1a5-436a-9bb0-6cc0d4bf4fda" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RUmFMMWoiLCJDcmVhdGVkRGF0ZSI6MS43NTI4NzM5MDYxNzFFOSwiTmFtZSI6InZhcmlhYmxlLWZvci1hcyIsIlNlY3JldEJpbmFyeSI6ImFHVnNiRzhnZDI5eWJHUT0iLCJWZXJzaW9uSWQiOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "c25d52a3e0b71f9e", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "304" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:09 GMT" + ], + "X-Amzn-Requestid": [ + "0516b1fb-1298-4f39-9c0b-d88900f688e0" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RUmFMMWoiLCJDcmVhdGVkRGF0ZSI6MS43NTI4NzM5MDYxNDRFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM5MDYxNzZFOSwiTmFtZSI6InZhcmlhYmxlLWZvci1hcyIsIlZlcnNpb25JZHNUb1N0YWdlcyI6eyJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "b095148d32f4282f", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "64" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ2YXJpYWJsZS1mb3ItYXMifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "142" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:09 GMT" + ], + "X-Amzn-Requestid": [ + "bba013b1-0ba3-46f2-ad22-fa59a0d9b286" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RUmFMMWoiLCJEZWxldGlvbkRhdGUiOjEuNzUyODczOTA5NDk3RTksIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMifQ==" + } + }, + { + "ID": "db9a12814ed4895c", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "335" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:12 GMT" + ], + "X-Amzn-Requestid": [ + "454669b5-7eb8-43a2-97be-a96234e11f4d" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RUmFMMWoiLCJDcmVhdGVkRGF0ZSI6MS43NTI4NzM5MDYxNDRFOSwiRGVsZXRlZERhdGUiOjEuNzUyODczOTA5NTA0RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzUyNzk2OEU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzUyODczOTA5NTA4RTksIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidmFyaWFibGUtZm9yLWFzLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "cb1d6615c752ae04", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:14 GMT" + ], + "X-Amzn-Requestid": [ + "372de8ab-3546-4ed9-8414-123539350384" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..6548c613a --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,542 @@ +{ + "Initial": "AQAAAA7gDLK6F47nnAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "762acdd323f0061b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:14 GMT" + ], + "X-Amzn-Requestid": [ + "0c1f8bd5-6ee9-49e2-a0ee-53a964228a0b" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + }, + { + "ID": "5bc362e7c19a4252", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "140" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9In0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "181" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:14 GMT" + ], + "X-Amzn-Requestid": [ + "940c7041-05e5-4a0d-bf70-77fc7baadb67" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1pU1p1ckEiLCJOYW1lIjoidmFyaWFibGUtZm9yLWFzIiwiVmVyc2lvbklkIjoidmFyaWFibGUtZm9yLWFzLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQifQ==" + } + }, + { + "ID": "e3e9375cbedd70ef", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:17 GMT" + ], + "X-Amzn-Requestid": [ + "f6909aad-2a6c-4183-ab57-69f2beae4d37" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1pU1p1ckEiLCJDcmVhdGVkRGF0ZSI6MS43NTI4NzM5MTQ4MTdFOSwiTmFtZSI6InZhcmlhYmxlLWZvci1hcyIsIlNlY3JldEJpbmFyeSI6ImFHVnNiRzhnZDI5eWJHUT0iLCJWZXJzaW9uSWQiOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "dbc62a635973983d", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:18 GMT" + ], + "X-Amzn-Requestid": [ + "1c89fedb-1681-41c6-8de8-0362ae6e6085" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1pU1p1ckEiLCJDcmVhdGVkRGF0ZSI6MS43NTI4NzM5MTQ4MTdFOSwiTmFtZSI6InZhcmlhYmxlLWZvci1hcyIsIlNlY3JldEJpbmFyeSI6ImFHVnNiRzhnZDI5eWJHUT0iLCJWZXJzaW9uSWQiOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "9f28f79ce9385ea6", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "303" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:18 GMT" + ], + "X-Amzn-Requestid": [ + "8aea146b-c161-4917-a876-289a4585c6c3" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1pU1p1ckEiLCJDcmVhdGVkRGF0ZSI6MS43NTI4NzM5MTQ3ODVFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM5MTQ4MkU5LCJOYW1lIjoidmFyaWFibGUtZm9yLWFzIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InZhcmlhYmxlLWZvci1hcy0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIjpbIkFXU0NVUlJFTlQiXX19" + } + }, + { + "ID": "554f4860a9d367b8", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "64" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ2YXJpYWJsZS1mb3ItYXMifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "142" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:18 GMT" + ], + "X-Amzn-Requestid": [ + "6bd61f3c-a348-4dcb-bfd4-badf56ae9350" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1pU1p1ckEiLCJEZWxldGlvbkRhdGUiOjEuNzUyODczOTE4MTQ3RTksIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMifQ==" + } + }, + { + "ID": "7eb729c7577c0ac3", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "335" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:21 GMT" + ], + "X-Amzn-Requestid": [ + "95782671-197a-4dab-953d-4ef35d61b3f3" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1pU1p1ckEiLCJDcmVhdGVkRGF0ZSI6MS43NTI4NzM5MTQ3ODVFOSwiRGVsZXRlZERhdGUiOjEuNzUyODczOTE4MTU1RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzUyNzk2OEU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzUyODczOTE4MTYzRTksIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidmFyaWFibGUtZm9yLWFzLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "9f2e7ddf751434eb", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "335" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:21 GMT" + ], + "X-Amzn-Requestid": [ + "59474ec9-4877-4898-b85c-23f28c58fcdf" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1pU1p1ckEiLCJDcmVhdGVkRGF0ZSI6MS43NTI4NzM5MTQ3ODVFOSwiRGVsZXRlZERhdGUiOjEuNzUyODczOTE4MTU1RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzUyNzk2OEU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzUyODczOTE4MTYzRTksIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidmFyaWFibGUtZm9yLWFzLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "a309ee69fd2637c0", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:23 GMT" + ], + "X-Amzn-Requestid": [ + "5f691471-9b52-4fae-b4c0-f760a32477bd" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestAs/verify_As.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestAs/verify_As.replay new file mode 100644 index 000000000..cbdf3fee6 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestAs/verify_As.replay @@ -0,0 +1,542 @@ +{ + "Initial": "AQAAAA7eRgZADTGztAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "e5e75378dd81adcf", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:15 GMT" + ], + "X-Amzn-Requestid": [ + "740ca705-83b1-4de2-a8de-9e1cbcb18d9e" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + }, + { + "ID": "255d4e41eb662826", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "140" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9In0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "181" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:16 GMT" + ], + "X-Amzn-Requestid": [ + "c83f75c6-dc60-494e-8e76-21c3e938d368" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1lOWFpcU8iLCJOYW1lIjoidmFyaWFibGUtZm9yLWFzIiwiVmVyc2lvbklkIjoidmFyaWFibGUtZm9yLWFzLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQifQ==" + } + }, + { + "ID": "430f308ce3dc00d6", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:19 GMT" + ], + "X-Amzn-Requestid": [ + "6deb5986-63c0-4cd1-9569-82b8e736ad43" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1lOWFpcU8iLCJDcmVhdGVkRGF0ZSI6MS43MjMwNzY0MTY1ODhFOSwiTmFtZSI6InZhcmlhYmxlLWZvci1hcyIsIlNlY3JldEJpbmFyeSI6ImFHVnNiRzhnZDI5eWJHUT0iLCJWZXJzaW9uSWQiOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "bb7f433a694039b4", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:19 GMT" + ], + "X-Amzn-Requestid": [ + "f7e82c25-7644-4da3-b51a-41d42a37c65b" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1lOWFpcU8iLCJDcmVhdGVkRGF0ZSI6MS43MjMwNzY0MTY1ODhFOSwiTmFtZSI6InZhcmlhYmxlLWZvci1hcyIsIlNlY3JldEJpbmFyeSI6ImFHVnNiRzhnZDI5eWJHUT0iLCJWZXJzaW9uSWQiOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "4a8c21bcb877e3a1", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "304" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:19 GMT" + ], + "X-Amzn-Requestid": [ + "4d48501d-d804-4fc6-933f-697f4a1c4156" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1lOWFpcU8iLCJDcmVhdGVkRGF0ZSI6MS43MjMwNzY0MTY1NjNFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43MjMwNzUyRTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43MjMwNzY0MTY1OTFFOSwiTmFtZSI6InZhcmlhYmxlLWZvci1hcyIsIlZlcnNpb25JZHNUb1N0YWdlcyI6eyJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "0f6e251daeb0bd33", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "64" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ2YXJpYWJsZS1mb3ItYXMifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "142" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:19 GMT" + ], + "X-Amzn-Requestid": [ + "f86fdfd9-54a3-4e99-883a-988fb512ff8b" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1lOWFpcU8iLCJEZWxldGlvbkRhdGUiOjEuNzIzMDc2NDE5ODgzRTksIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMifQ==" + } + }, + { + "ID": "a1eb7d42b6d189e9", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "335" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:22 GMT" + ], + "X-Amzn-Requestid": [ + "3a79c38e-3e97-4348-92d6-b2333547ab54" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1lOWFpcU8iLCJDcmVhdGVkRGF0ZSI6MS43MjMwNzY0MTY1NjNFOSwiRGVsZXRlZERhdGUiOjEuNzIzMDc2NDE5ODkxRTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzIzMDc1MkU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzIzMDc2NDE5ODk4RTksIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidmFyaWFibGUtZm9yLWFzLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "7ce9c22fe4f51b84", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "335" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:22 GMT" + ], + "X-Amzn-Requestid": [ + "3519c295-fc5e-46d8-8d8c-0f2b3b76909c" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1lOWFpcU8iLCJDcmVhdGVkRGF0ZSI6MS43MjMwNzY0MTY1NjNFOSwiRGVsZXRlZERhdGUiOjEuNzIzMDc2NDE5ODkxRTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzIzMDc1MkU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzIzMDc2NDE5ODk4RTksIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidmFyaWFibGUtZm9yLWFzLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "31d4610ea61de62b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:23 GMT" + ], + "X-Amzn-Requestid": [ + "2e5cbca3-f4a6-4a7d-b2dc-0314d62db163" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..649e2a9ed --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,542 @@ +{ + "Initial": "AQAAAA7eRgZIIhB0tgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "a62ed477b68f177d", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:24 GMT" + ], + "X-Amzn-Requestid": [ + "20ceff74-442f-4e53-9d89-d952143cdf17" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + }, + { + "ID": "449d4b9a6a9586d0", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "140" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9In0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "181" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:24 GMT" + ], + "X-Amzn-Requestid": [ + "13b90041-9671-41f2-a664-fc67e2355f53" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RZFJ5OVUiLCJOYW1lIjoidmFyaWFibGUtZm9yLWFzIiwiVmVyc2lvbklkIjoidmFyaWFibGUtZm9yLWFzLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQifQ==" + } + }, + { + "ID": "186ab8551c0c9f45", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:27 GMT" + ], + "X-Amzn-Requestid": [ + "8f2a56f0-d2a9-4906-930e-2c4bc6db205d" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RZFJ5OVUiLCJDcmVhdGVkRGF0ZSI6MS43MjMwNzY0MjQ5MzZFOSwiTmFtZSI6InZhcmlhYmxlLWZvci1hcyIsIlNlY3JldEJpbmFyeSI6ImFHVnNiRzhnZDI5eWJHUT0iLCJWZXJzaW9uSWQiOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "17f4dcfccb03ca53", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:27 GMT" + ], + "X-Amzn-Requestid": [ + "24cb0ed3-2337-4a2e-8613-8497ccb3ec7d" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RZFJ5OVUiLCJDcmVhdGVkRGF0ZSI6MS43MjMwNzY0MjQ5MzZFOSwiTmFtZSI6InZhcmlhYmxlLWZvci1hcyIsIlNlY3JldEJpbmFyeSI6ImFHVnNiRzhnZDI5eWJHUT0iLCJWZXJzaW9uSWQiOiJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "4d4e5cfc23d4f317", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "304" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:27 GMT" + ], + "X-Amzn-Requestid": [ + "fba00c12-a669-46d6-a848-c71f572f19ac" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RZFJ5OVUiLCJDcmVhdGVkRGF0ZSI6MS43MjMwNzY0MjQ5MTNFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43MjMwNzUyRTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43MjMwNzY0MjQ5MzlFOSwiTmFtZSI6InZhcmlhYmxlLWZvci1hcyIsIlZlcnNpb25JZHNUb1N0YWdlcyI6eyJ2YXJpYWJsZS1mb3ItYXMtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "2d047a833716d6c1", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "64" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ2YXJpYWJsZS1mb3ItYXMifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "142" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:28 GMT" + ], + "X-Amzn-Requestid": [ + "b1236672-db0f-4f74-9a16-2fd1828d4cbb" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RZFJ5OVUiLCJEZWxldGlvbkRhdGUiOjEuNzIzMDc2NDI4MjQ1RTksIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMifQ==" + } + }, + { + "ID": "82406e28e8e978d8", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "335" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:31 GMT" + ], + "X-Amzn-Requestid": [ + "8739d5c3-8885-4a78-bdec-164f53f34786" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RZFJ5OVUiLCJDcmVhdGVkRGF0ZSI6MS43MjMwNzY0MjQ5MTNFOSwiRGVsZXRlZERhdGUiOjEuNzIzMDc2NDI4MjU1RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzIzMDc1MkU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzIzMDc2NDI4MjU5RTksIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidmFyaWFibGUtZm9yLWFzLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "326e9cea4dd29eb1", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "335" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:31 GMT" + ], + "X-Amzn-Requestid": [ + "01d03688-7f89-451d-be30-1305610693fb" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnZhcmlhYmxlLWZvci1hcy1RZFJ5OVUiLCJDcmVhdGVkRGF0ZSI6MS43MjMwNzY0MjQ5MTNFOSwiRGVsZXRlZERhdGUiOjEuNzIzMDc2NDI4MjU1RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzIzMDc1MkU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzIzMDc2NDI4MjU5RTksIk5hbWUiOiJ2YXJpYWJsZS1mb3ItYXMiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidmFyaWFibGUtZm9yLWFzLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "dd189d54850cb546", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "30" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InZhcmlhYmxlLWZvci1hcyJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:33 GMT" + ], + "X-Amzn-Requestid": [ + "4011360a-5822-431c-aaaa-4b0f0b768ab1" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestDelete.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestDelete.replay new file mode 100644 index 000000000..ce0202fa7 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestDelete.replay @@ -0,0 +1,872 @@ +{ + "Initial": "AQAAAA7eRgYhGbnqcAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "f2ac250745a0990b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "150" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiYUdWc2JHOGdkMjl5YkdRPSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:45 GMT" + ], + "X-Amzn-Requestid": [ + "60122a5b-f5f7-47f5-af37-90749dc17538" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUdvRVdZTSIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQifQ==" + } + }, + { + "ID": "b31bf99e99b7d17b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:48 GMT" + ], + "X-Amzn-Requestid": [ + "6dcf1fbf-f8c5-4516-bda1-be7d8c9dd29c" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUdvRVdZTSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM4NTYwNUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "d7a9f3537b0e924b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:48 GMT" + ], + "X-Amzn-Requestid": [ + "9cb14934-b470-48c0-be13-eb69c169fc1f" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUdvRVdZTSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM4NTYwNUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "4dfd588a9b2fa91e", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "319" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:48 GMT" + ], + "X-Amzn-Requestid": [ + "ca7efaa2-c282-41c6-9c79-a0362d3f0a72" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUdvRVdZTSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM4NTU3OUU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjcyMzA3NTJFOSwiTGFzdENoYW5nZWREYXRlIjoxLjcyMzA3NjM4NTYwOEU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "f49f49e5209786ce", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:48 GMT" + ], + "X-Amzn-Requestid": [ + "d8e5f89d-acce-495e-bc36-366a15d9edc3" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUdvRVdZTSIsIkRlbGV0aW9uRGF0ZSI6MS43MjMwNzYzODg5MjZFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "99d9f33220a95db1", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "350" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:51 GMT" + ], + "X-Amzn-Requestid": [ + "b00cde68-c76b-4b85-8308-6ef0433b08e1" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUdvRVdZTSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM4NTU3OUU5LCJEZWxldGVkRGF0ZSI6MS43MjMwNzYzODg5MzZFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43MjMwNzUyRTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43MjMwNzYzODg5NDNFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "e479ed0443641926", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:52 GMT" + ], + "X-Amzn-Requestid": [ + "fe012b83-45ef-4387-b9ca-9f4c6d001fad" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + }, + { + "ID": "4a14de3cb4d3fba7", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:53 GMT" + ], + "X-Amzn-Requestid": [ + "1ed85d0e-131c-4d0f-b553-2d9c8a9c7cd5" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + }, + { + "ID": "bd3c8115e73f615b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "154" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0wMDc4YmI4ZTVjOWQ4YWJmN2YxZTRlMTRjODdkOTAyMzIzNWI2MjMwIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiWjI5dlpHSjVaU0IzYjNKc1pBPT0ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:53 GMT" + ], + "X-Amzn-Requestid": [ + "f233906f-0911-4cee-8712-52e1678637aa" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVdKaE5oWiIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAifQ==" + } + }, + { + "ID": "1180009a2e2f0e71", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "296" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:56 GMT" + ], + "X-Amzn-Requestid": [ + "2370f2bb-21fe-41b1-87cd-a3fefdd34d7e" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVdKaE5oWiIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM5MzYwNEU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJaMjl2WkdKNVpTQjNiM0pzWkE9PSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "f65fa5627768c742", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "296" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:56 GMT" + ], + "X-Amzn-Requestid": [ + "842cee5e-984d-4ebe-8680-198a556bf477" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVdKaE5oWiIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM5MzYwNEU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJaMjl2WkdKNVpTQjNiM0pzWkE9PSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "c2d329784dd5534b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "319" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:56 GMT" + ], + "X-Amzn-Requestid": [ + "e6e301a0-ed9d-44b2-8324-01811679c2d6" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVdKaE5oWiIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM5MzU3OEU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjcyMzA3NTJFOSwiTGFzdENoYW5nZWREYXRlIjoxLjcyMzA3NjM5MzYwOEU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMDA3OGJiOGU1YzlkOGFiZjdmMWU0ZTE0Yzg3ZDkwMjMyMzViNjIzMCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "7d3fd817f5976256", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:56 GMT" + ], + "X-Amzn-Requestid": [ + "2646eec1-6cbc-4ada-bcda-f0038a19260a" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVdKaE5oWiIsIkRlbGV0aW9uRGF0ZSI6MS43MjMwNzYzOTY5MjJFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "3f9cb44ad6cf985f", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "349" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:59 GMT" + ], + "X-Amzn-Requestid": [ + "b5389401-1eaa-4df0-9970-fdb59e0250c2" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVdKaE5oWiIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM5MzU3OEU5LCJEZWxldGVkRGF0ZSI6MS43MjMwNzYzOTY5M0U5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjcyMzA3NTJFOSwiTGFzdENoYW5nZWREYXRlIjoxLjcyMzA3NjM5NjkzNUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMDA3OGJiOGU1YzlkOGFiZjdmMWU0ZTE0Yzg3ZDkwMjMyMzViNjIzMCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "9423b8d9d0db3816", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:01 GMT" + ], + "X-Amzn-Requestid": [ + "ddcb5774-c1cd-409b-bc6f-9b6fd6ef46cf" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestInvalidJSON.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestInvalidJSON.replay new file mode 100644 index 000000000..fb13b42ce --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestInvalidJSON.replay @@ -0,0 +1,432 @@ +{ + "Initial": "AQAAAA7eRgYNAGuaKgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "1632d340f34be0c5", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "146" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0zMzMzYzU5NjE3OTFjMjg3MDI4MzY2NTgxYWQ3NmQ5MjFjYTYxY2FkIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiYm05MExXcHpiMjQ9In0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:25 GMT" + ], + "X-Amzn-Requestid": [ + "8647c373-62c3-4824-81ae-b88639f7bcdd" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTRZYW1FbSIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTMzMzNjNTk2MTc5MWMyODcwMjgzNjY1ODFhZDc2ZDkyMWNhNjFjYWQifQ==" + } + }, + { + "ID": "b7267c607fe6e7a0", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "288" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:28 GMT" + ], + "X-Amzn-Requestid": [ + "79f71d9d-3b01-43b9-9aa0-3fb51e62cfb0" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTRZYW1FbSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM2NTE5MUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJibTkwTFdwemIyND0iLCJWZXJzaW9uSWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0zMzMzYzU5NjE3OTFjMjg3MDI4MzY2NTgxYWQ3NmQ5MjFjYTYxY2FkIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "3c870cbe9270f7ec", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "288" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:28 GMT" + ], + "X-Amzn-Requestid": [ + "20ee862a-2d7c-4f69-a816-8775efb6767d" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTRZYW1FbSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM2NTE5MUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJibTkwTFdwemIyND0iLCJWZXJzaW9uSWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0zMzMzYzU5NjE3OTFjMjg3MDI4MzY2NTgxYWQ3NmQ5MjFjYTYxY2FkIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "d24675827a024aff", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "319" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:28 GMT" + ], + "X-Amzn-Requestid": [ + "1aaaeff1-13a4-409d-a3d3-a05ebea036a2" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTRZYW1FbSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM2NTE2OEU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjcyMzA3NTJFOSwiTGFzdENoYW5nZWREYXRlIjoxLjcyMzA3NjM2NTE5NUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMzMzM2M1OTYxNzkxYzI4NzAyODM2NjU4MWFkNzZkOTIxY2E2MWNhZCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "459cb68bc950a8f1", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:28 GMT" + ], + "X-Amzn-Requestid": [ + "ac1b5590-671e-4295-b424-7af58786e152" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTRZYW1FbSIsIkRlbGV0aW9uRGF0ZSI6MS43MjMwNzYzNjg0OTdFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "f529fb8e9d859f1f", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "350" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:31 GMT" + ], + "X-Amzn-Requestid": [ + "47073e41-d4b0-40ae-b683-f58ddb2219f5" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTRZYW1FbSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM2NTE2OEU5LCJEZWxldGVkRGF0ZSI6MS43MjMwNzYzNjg1MDdFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43MjMwNzUyRTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43MjMwNzYzNjg1MTFFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTMzMzNjNTk2MTc5MWMyODcwMjgzNjY1ODFhZDc2ZDkyMWNhNjFjYWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "12854ed0aae16e73", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:33 GMT" + ], + "X-Amzn-Requestid": [ + "d69a6ed5-31e8-4227-8134-7b5fe02436e4" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestJSON.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestJSON.replay new file mode 100644 index 000000000..10e15cf68 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestJSON.replay @@ -0,0 +1,432 @@ +{ + "Initial": "AQAAAA7eRgYFFABmpgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "fdf4ab7f4cf9e2c7", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0wNjllMGIzNTU3ZDExZjNiNTg5OGE3YmI3ZTE4Mzg0ZTMxMjVjYWJjIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiV3dwN0lrNWhiV1VpT2lBaVJXUWlMQ0FpVkdWNGRDSTZJQ0pMYm05amF5QnJibTlqYXk0aWZTd0tleUpPWVcxbElqb2dJbE5oYlNJc0lDSlVaWGgwSWpvZ0lsZG9ieWR6SUhSb1pYSmxQeUo5Q2wwPSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:17 GMT" + ], + "X-Amzn-Requestid": [ + "2e37cabe-e1b5-42d8-b91f-96b49c5699be" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVphdXJWbiIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTA2OWUwYjM1NTdkMTFmM2I1ODk4YTdiYjdlMTgzODRlMzEyNWNhYmMifQ==" + } + }, + { + "ID": "00be7a10a5540ade", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "388" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:20 GMT" + ], + "X-Amzn-Requestid": [ + "90ce6f29-9e1c-4d13-8f70-c1a2eb8db279" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVphdXJWbiIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM1NzUwNUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJXd3A3SWs1aGJXVWlPaUFpUldRaUxDQWlWR1Y0ZENJNklDSkxibTlqYXlCcmJtOWpheTRpZlN3S2V5Sk9ZVzFsSWpvZ0lsTmhiU0lzSUNKVVpYaDBJam9nSWxkb2J5ZHpJSFJvWlhKbFB5SjlDbDA9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMDY5ZTBiMzU1N2QxMWYzYjU4OThhN2JiN2UxODM4NGUzMTI1Y2FiYyIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "6589f5d0c8f2d34c", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "388" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:20 GMT" + ], + "X-Amzn-Requestid": [ + "2808a418-be9f-4af7-aa9b-146b64cd7069" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVphdXJWbiIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM1NzUwNUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJXd3A3SWs1aGJXVWlPaUFpUldRaUxDQWlWR1Y0ZENJNklDSkxibTlqYXlCcmJtOWpheTRpZlN3S2V5Sk9ZVzFsSWpvZ0lsTmhiU0lzSUNKVVpYaDBJam9nSWxkb2J5ZHpJSFJvWlhKbFB5SjlDbDA9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMDY5ZTBiMzU1N2QxMWYzYjU4OThhN2JiN2UxODM4NGUzMTI1Y2FiYyIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "7ce70562c939f4ea", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "319" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:20 GMT" + ], + "X-Amzn-Requestid": [ + "42381e06-43ad-4f5e-b382-b931cafdba0a" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVphdXJWbiIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM1NzQ4MUU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjcyMzA3NTJFOSwiTGFzdENoYW5nZWREYXRlIjoxLjcyMzA3NjM1NzUwOUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMDY5ZTBiMzU1N2QxMWYzYjU4OThhN2JiN2UxODM4NGUzMTI1Y2FiYyI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "610a9e56a5f677cc", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:20 GMT" + ], + "X-Amzn-Requestid": [ + "98a1e763-eef7-4d30-93e6-85b544672c66" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVphdXJWbiIsIkRlbGV0aW9uRGF0ZSI6MS43MjMwNzYzNjA4MjJFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "005a8ce48c10f21b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "350" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:23 GMT" + ], + "X-Amzn-Requestid": [ + "b0393fb6-c7ae-4fff-b934-2600ea2a5501" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVphdXJWbiIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM1NzQ4MUU5LCJEZWxldGVkRGF0ZSI6MS43MjMwNzYzNjA4MzNFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43MjMwNzUyRTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43MjMwNzYzNjA4MzhFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTA2OWUwYjM1NTdkMTFmM2I1ODk4YTdiYjdlMTgzODRlMzEyNWNhYmMiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "589c46e1191f01e5", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:24 GMT" + ], + "X-Amzn-Requestid": [ + "bc55a142-e457-4bdc-9ef9-0fd377ba9242" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestNonExistentVariable.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestNonExistentVariable.replay new file mode 100644 index 000000000..601da6384 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestNonExistentVariable.replay @@ -0,0 +1,102 @@ +{ + "Initial": "AQAAAA7eRgX4DSuMEwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "92b8718d3a30881a", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "29" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6ImRvZXMtbm90LWV4aXN0In0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:03 GMT" + ], + "X-Amzn-Requestid": [ + "d0c55a01-c8de-44b6-bbef-7c6ca6c36c6b" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestString.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestString.replay new file mode 100644 index 000000000..748c9e2b2 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestString.replay @@ -0,0 +1,432 @@ +{ + "Initial": "AQAAAA7eRgX4F/72ewAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "ae512b51a0ffd19c", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "150" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiYUdWc2JHOGdkMjl5YkdRPSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:04 GMT" + ], + "X-Amzn-Requestid": [ + "62c3905e-6889-46d1-9646-ee6b6c9a4f97" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUVmQXNtdCIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQifQ==" + } + }, + { + "ID": "9409eaf7eb9007aa", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:07 GMT" + ], + "X-Amzn-Requestid": [ + "820dc6f9-70be-4dd1-8e64-870156ab6297" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUVmQXNtdCIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM0NDU5NUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "549f7b61918fe9f8", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:07 GMT" + ], + "X-Amzn-Requestid": [ + "c8533964-10aa-4441-9efe-05e3cf416e29" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUVmQXNtdCIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM0NDU5NUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "0adba87ca6ab2203", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "318" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:07 GMT" + ], + "X-Amzn-Requestid": [ + "7cdcb0f5-dc93-415c-a3d1-ec23248a6743" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUVmQXNtdCIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM0NDU3RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzIzMDc1MkU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzIzMDc2MzQ0NTk4RTksIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZHNUb1N0YWdlcyI6eyJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIjpbIkFXU0NVUlJFTlQiXX19" + } + }, + { + "ID": "ca97901e7ea923b0", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:12 GMT" + ], + "X-Amzn-Requestid": [ + "ef2b3795-bf8b-4d0a-9418-e079463b1968" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUVmQXNtdCIsIkRlbGV0aW9uRGF0ZSI6MS43MjMwNzYzNTI5MTNFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "e3c16638f79cddc8", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "349" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:15 GMT" + ], + "X-Amzn-Requestid": [ + "11e6a1ba-abfd-4ddf-ba9c-7b99c54a189b" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLUVmQXNtdCIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM0NDU3RTksIkRlbGV0ZWREYXRlIjoxLjcyMzA3NjM1MjkyMkU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjcyMzA3NTJFOSwiTGFzdENoYW5nZWREYXRlIjoxLjcyMzA3NjM1MjkyOUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "500e47bb5fea4287", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:16 GMT" + ], + "X-Amzn-Requestid": [ + "1ad09c40-0d8a-409b-beef-6e630642823a" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestUpdate.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestUpdate.replay new file mode 100644 index 000000000..d18ddd810 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestUpdate.replay @@ -0,0 +1,762 @@ +{ + "Initial": "AQAAAA7eRgYVETQGPQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "82b5beeb65529c07", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "150" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiYUdWc2JHOGdkMjl5YkdRPSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:33 GMT" + ], + "X-Amzn-Requestid": [ + "6cad8177-f705-4ec1-919d-fef97c3270b1" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQifQ==" + } + }, + { + "ID": "bbbf9d1d7cb49b56", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:36 GMT" + ], + "X-Amzn-Requestid": [ + "cd3d9c03-a1f2-4d69-b7b9-30864c5a64dd" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM3MzQ2N0U5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "6af6d348ab564892", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:36 GMT" + ], + "X-Amzn-Requestid": [ + "0d88c9df-2f6a-4015-a91e-7009314e6c13" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM3MzQ2N0U5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "f3901b9ecb9b6c74", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "318" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:36 GMT" + ], + "X-Amzn-Requestid": [ + "9bef7fe0-f482-4cfc-8789-dc9289909868" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM3MzQ0RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzIzMDc1MkU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzIzMDc2MzczNDcxRTksIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZHNUb1N0YWdlcyI6eyJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIjpbIkFXU0NVUlJFTlQiXX19" + } + }, + { + "ID": "0886e0d21c0529e8", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:36 GMT" + ], + "X-Amzn-Requestid": [ + "c2947dd8-09c0-4eda-a293-b401642669bc" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM3MzQ2N0U5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "862ec5d58dde5330", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "158" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.PutSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0wMDc4YmI4ZTVjOWQ4YWJmN2YxZTRlMTRjODdkOTAyMzIzNWI2MjMwIiwiU2VjcmV0QmluYXJ5IjoiWjI5dlpHSjVaU0IzYjNKc1pBPT0iLCJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "227" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:36 GMT" + ], + "X-Amzn-Requestid": [ + "2763739a-3d1f-4adc-b8e4-c6b5cf774e95" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "ce4fc3ae4b671afd", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "296" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:39 GMT" + ], + "X-Amzn-Requestid": [ + "1743d11a-92a2-4b9c-811d-e6320919ddc6" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM3Njg2NUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJaMjl2WkdKNVpTQjNiM0pzWkE9PSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "54b7a0e05bddbeb8", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "296" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:39 GMT" + ], + "X-Amzn-Requestid": [ + "8f59a286-050f-4a72-9500-26f411b1dca4" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM3Njg2NUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJaMjl2WkdKNVpTQjNiM0pzWkE9PSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "9ae67fd4811cdf07", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "398" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:39 GMT" + ], + "X-Amzn-Requestid": [ + "7a91123a-9da8-4523-8130-ae6bb58040e6" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM3MzQ0RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzIzMDc1MkU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzIzMDc2Mzc2ODY5RTksIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZHNUb1N0YWdlcyI6eyJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0wMDc4YmI4ZTVjOWQ4YWJmN2YxZTRlMTRjODdkOTAyMzIzNWI2MjMwIjpbIkFXU0NVUlJFTlQiXSwidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCI6WyJBV1NQUkVWSU9VUyJdfX0=" + } + }, + { + "ID": "fefd523fe4544af9", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:39 GMT" + ], + "X-Amzn-Requestid": [ + "2811a048-57b1-4659-ab45-f1d60f76adf9" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIkRlbGV0aW9uRGF0ZSI6MS43MjMwNzYzODAxMzVFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "af2ae070e049791d", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "429" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:42 GMT" + ], + "X-Amzn-Requestid": [ + "9e2f8432-6004-436c-8870-890cf5f07bb4" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM3MzQ0RTksIkRlbGV0ZWREYXRlIjoxLjcyMzA3NjM4MDE0OEU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjcyMzA3NTJFOSwiTGFzdENoYW5nZWREYXRlIjoxLjcyMzA3NjM4MDE1NEU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMDA3OGJiOGU1YzlkOGFiZjdmMWU0ZTE0Yzg3ZDkwMjMyMzViNjIzMCI6WyJBV1NDVVJSRU5UIl0sInRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTUFJFVklPVVMiXX19" + } + }, + { + "ID": "827844f6a7fc44b6", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "429" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:43 GMT" + ], + "X-Amzn-Requestid": [ + "9c143a37-8a91-4942-b335-c0c7810bea4c" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLXIzSHdVWSIsIkNyZWF0ZWREYXRlIjoxLjcyMzA3NjM3MzQ0RTksIkRlbGV0ZWREYXRlIjoxLjcyMzA3NjM4MDE0OEU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjcyMzA3NTJFOSwiTGFzdENoYW5nZWREYXRlIjoxLjcyMzA3NjM4MDE1NEU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMDA3OGJiOGU1YzlkOGFiZjdmMWU0ZTE0Yzg3ZDkwMjMyMzViNjIzMCI6WyJBV1NDVVJSRU5UIl0sInRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTUFJFVklPVVMiXX19" + } + }, + { + "ID": "73c29d8c1ab6674c", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:19:44 GMT" + ], + "X-Amzn-Requestid": [ + "4b838475-9906-4c92-9d1d-120898381351" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestUpdateWithErrors.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestUpdateWithErrors.replay new file mode 100644 index 000000000..84340f680 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestConformanceV2/TestUpdateWithErrors.replay @@ -0,0 +1,872 @@ +{ + "Initial": "AQAAAA7eRgYxM3lkAgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "e7378230dd7a0fd9", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "192" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTQ3MmFiZDIyZDc5ZDA2MjAzZWQ3MWI4OTc5OWJlNmMzIiwiTmFtZSI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IiLCJTZWNyZXRCaW5hcnkiOiJXM3NpVG1GdFpTSTZJQ0pHYjI4aUxDQWlWR1Y0ZENJNklDSkNZWElpZlYwPSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "221" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:02 GMT" + ], + "X-Amzn-Requestid": [ + "ca78b1b8-1a5a-45c6-849d-b2e8d86cbed0" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiTmFtZSI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IiLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTQ3MmFiZDIyZDc5ZDA2MjAzZWQ3MWI4OTc5OWJlNmMzIn0=" + } + }, + { + "ID": "d0fd50ad8a23e23e", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "345" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:05 GMT" + ], + "X-Amzn-Requestid": [ + "6ea93183-3dbf-4019-81ca-256d7b45e562" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiQ3JlYXRlZERhdGUiOjEuNzIzMDc2NDAyMDU4RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiVzNzaVRtRnRaU0k2SUNKR2IyOGlMQ0FpVkdWNGRDSTZJQ0pDWVhJaWZWMD0iLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTQ3MmFiZDIyZDc5ZDA2MjAzZWQ3MWI4OTc5OWJlNmMzIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "4e31626782f9baa1", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "345" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:05 GMT" + ], + "X-Amzn-Requestid": [ + "b9c130e3-0b1d-4aad-b2f5-6b42f044bb2d" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiQ3JlYXRlZERhdGUiOjEuNzIzMDc2NDAyMDU4RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiVzNzaVRtRnRaU0k2SUNKR2IyOGlMQ0FpVkdWNGRDSTZJQ0pDWVhJaWZWMD0iLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTQ3MmFiZDIyZDc5ZDA2MjAzZWQ3MWI4OTc5OWJlNmMzIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "91b451a2f6cb7da1", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "344" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:05 GMT" + ], + "X-Amzn-Requestid": [ + "4015d3f5-d355-472f-9614-29b985de30e4" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiQ3JlYXRlZERhdGUiOjEuNzIzMDc2NDAyMDM0RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzIzMDc1MkU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzIzMDc2NDAyMDYyRTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNDcyYWJkMjJkNzlkMDYyMDNlZDcxYjg5Nzk5YmU2YzMiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "a82ea2278ba525f1", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.PutSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTcwNWQxMTYxMDhjNmJmYzlkMThlMjUyNmQwODlkNmMxIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dSIsIlNlY3JldElkIjoidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvciJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "252" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:05 GMT" + ], + "X-Amzn-Requestid": [ + "92b8b569-5e1e-47c6-a00b-b59fb5a1d224" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiTmFtZSI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IiLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTcwNWQxMTYxMDhjNmJmYzlkMThlMjUyNmQwODlkNmMxIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "12414765af83e798", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "317" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:08 GMT" + ], + "X-Amzn-Requestid": [ + "ac830d92-14b5-41be-8fa7-0670f74050c9" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiQ3JlYXRlZERhdGUiOjEuNzIzMDc2NDA1MzkyRTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dSIsIlZlcnNpb25JZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNzA1ZDExNjEwOGM2YmZjOWQxOGUyNTI2ZDA4OWQ2YzEiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "877d3a3eda335390", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "317" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:08 GMT" + ], + "X-Amzn-Requestid": [ + "39166b95-606e-4fb5-933e-a13815b0224a" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiQ3JlYXRlZERhdGUiOjEuNzIzMDc2NDA1MzkyRTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dSIsIlZlcnNpb25JZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNzA1ZDExNjEwOGM2YmZjOWQxOGUyNTI2ZDA4OWQ2YzEiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "d977128844c6e41c", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "427" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:08 GMT" + ], + "X-Amzn-Requestid": [ + "f325093b-5711-42b2-a8c6-f94e5b8ec41f" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiQ3JlYXRlZERhdGUiOjEuNzIzMDc2NDAyMDM0RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzIzMDc1MkU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzIzMDc2NDA1Mzk3RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNDcyYWJkMjJkNzlkMDYyMDNlZDcxYjg5Nzk5YmU2YzMiOlsiQVdTUFJFVklPVVMiXSwidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvci03MDVkMTE2MTA4YzZiZmM5ZDE4ZTI1MjZkMDg5ZDZjMSI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "5c56ceda4b302ba8", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "172" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.PutSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTY0NTVhNzI4OWQ4NjY0NGU3OTBiYTU5NjJiNDE2MTEwIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dU1nPT0iLCJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "252" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:08 GMT" + ], + "X-Amzn-Requestid": [ + "36576310-8e5c-4918-ac84-2a2ccd823c1d" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiTmFtZSI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IiLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTY0NTVhNzI4OWQ4NjY0NGU3OTBiYTU5NjJiNDE2MTEwIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "94010ae5fa45f87b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "321" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:11 GMT" + ], + "X-Amzn-Requestid": [ + "663ae774-965d-4d82-9a1d-e986b438f731" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiQ3JlYXRlZERhdGUiOjEuNzIzMDc2NDA4NjgyRTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dU1nPT0iLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTY0NTVhNzI4OWQ4NjY0NGU3OTBiYTU5NjJiNDE2MTEwIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "d0785179280f168b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "321" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:11 GMT" + ], + "X-Amzn-Requestid": [ + "88f1dbef-11a0-4989-8566-36e5eaf76a5c" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiQ3JlYXRlZERhdGUiOjEuNzIzMDc2NDA4NjgyRTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dU1nPT0iLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTY0NTVhNzI4OWQ4NjY0NGU3OTBiYTU5NjJiNDE2MTEwIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "6464d4fef7c1337c", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "427" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:11 GMT" + ], + "X-Amzn-Requestid": [ + "de015a36-debf-402b-bb54-5155ba0d9671" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiQ3JlYXRlZERhdGUiOjEuNzIzMDc2NDAyMDM0RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzIzMDc1MkU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzIzMDc2NDA4Njg2RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNjQ1NWE3Mjg5ZDg2NjQ0ZTc5MGJhNTk2MmI0MTYxMTAiOlsiQVdTQ1VSUkVOVCJdLCJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTcwNWQxMTYxMDhjNmJmYzlkMThlMjUyNmQwODlkNmMxIjpbIkFXU1BSRVZJT1VTIl19fQ==" + } + }, + { + "ID": "6a15da7b83185ceb", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "80" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "174" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:11 GMT" + ], + "X-Amzn-Requestid": [ + "8b6cfcc2-3bd2-4eed-a418-ce7e606352c1" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiRGVsZXRpb25EYXRlIjoxLjcyMzA3NjQxMTk2MUU5LCJOYW1lIjoidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvciJ9" + } + }, + { + "ID": "2b580935647b5985", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "457" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:15 GMT" + ], + "X-Amzn-Requestid": [ + "6233b4aa-cc9c-495f-9f02-b1db1a4a498c" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NjIzODAyMjU3MjI6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3Ita3VrTHJZIiwiQ3JlYXRlZERhdGUiOjEuNzIzMDc2NDAyMDM0RTksIkRlbGV0ZWREYXRlIjoxLjcyMzA3NjQxMTk3RTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzIzMDc1MkU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzIzMDc2NDExOTc1RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNjQ1NWE3Mjg5ZDg2NjQ0ZTc5MGJhNTk2MmI0MTYxMTAiOlsiQVdTQ1VSUkVOVCJdLCJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTcwNWQxMTYxMDhjNmJmYzlkMThlMjUyNmQwODlkNmMxIjpbIkFXU1BSRVZJT1VTIl19fQ==" + } + }, + { + "ID": "5657bca3256a2c5d", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Thu, 08 Aug 2024 00:20:16 GMT" + ], + "X-Amzn-Requestid": [ + "d7ef5491-2eb0-4c5a-badb-f7e0f4edc3f1" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestDelete.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestDelete.replay new file mode 100644 index 000000000..3b4c802e0 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestDelete.replay @@ -0,0 +1,982 @@ +{ + "Initial": "AQAAAA7gDLKREmyHcwAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "845e8d58c7556a9a", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "150" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiYUdWc2JHOGdkMjl5YkdRPSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:33 GMT" + ], + "X-Amzn-Requestid": [ + "58c258fe-629d-4276-a3a6-8de203d52ed9" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVo5VlVYWiIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQifQ==" + } + }, + { + "ID": "5680b81e0c4bf6ac", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:36 GMT" + ], + "X-Amzn-Requestid": [ + "e26bf6fa-f95c-47b7-b5f0-25ac5092b905" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVo5VlVYWiIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg3MzUxNkU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "85737d726d5ba8a0", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:36 GMT" + ], + "X-Amzn-Requestid": [ + "80e7fc46-9cb2-4b32-844d-7a459803fcd6" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVo5VlVYWiIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg3MzUxNkU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "d51a2104cb356260", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "318" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:36 GMT" + ], + "X-Amzn-Requestid": [ + "967263c3-6354-4ff7-a923-7ae4d612310f" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVo5VlVYWiIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg3MzQ4N0U5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjc1Mjc5NjhFOSwiTGFzdENoYW5nZWREYXRlIjoxLjc1Mjg3Mzg3MzUyRTksIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZHNUb1N0YWdlcyI6eyJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIjpbIkFXU0NVUlJFTlQiXX19" + } + }, + { + "ID": "3a8d1a16dd17bdf8", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:36 GMT" + ], + "X-Amzn-Requestid": [ + "9d1cb358-e6aa-4ce3-8960-b3170f2841a5" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVo5VlVYWiIsIkRlbGV0aW9uRGF0ZSI6MS43NTI4NzM4NzY4NDlFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "319e9e05a1b1b5b3", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "350" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:39 GMT" + ], + "X-Amzn-Requestid": [ + "d79f62fe-fb77-4eda-b443-df3ec0690f57" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVo5VlVYWiIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg3MzQ4N0U5LCJEZWxldGVkRGF0ZSI6MS43NTI4NzM4NzY4NTlFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM4NzY4NjVFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "7ebb88cb7a6ebfb2", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "350" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:40 GMT" + ], + "X-Amzn-Requestid": [ + "c41aedaf-f375-45eb-a881-572f81211a57" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLVo5VlVYWiIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg3MzQ4N0U5LCJEZWxldGVkRGF0ZSI6MS43NTI4NzM4NzY4NTlFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM4NzY4NjVFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "6694af79f774ebf9", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:41 GMT" + ], + "X-Amzn-Requestid": [ + "d07e0ccc-29f4-4eb4-8a5d-1f6ea926b67a" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + }, + { + "ID": "e17ca5d476c51755", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:41 GMT" + ], + "X-Amzn-Requestid": [ + "5eba631a-c189-4533-9efb-c6efd055f312" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + }, + { + "ID": "0134f7fc91993608", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "154" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0wMDc4YmI4ZTVjOWQ4YWJmN2YxZTRlMTRjODdkOTAyMzIzNWI2MjMwIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiWjI5dlpHSjVaU0IzYjNKc1pBPT0ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:42 GMT" + ], + "X-Amzn-Requestid": [ + "96ff1458-2a47-42b3-8e48-ade3dd7182f4" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTB5SlFZTSIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAifQ==" + } + }, + { + "ID": "83b84f672d878a7d", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "296" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:45 GMT" + ], + "X-Amzn-Requestid": [ + "35a68894-8b95-4537-980a-5d431ee08575" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTB5SlFZTSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg4MjA0MkU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJaMjl2WkdKNVpTQjNiM0pzWkE9PSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "2841e51e2e26aea7", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "296" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:45 GMT" + ], + "X-Amzn-Requestid": [ + "db52096d-978b-496e-96eb-f63f35b943bf" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTB5SlFZTSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg4MjA0MkU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJaMjl2WkdKNVpTQjNiM0pzWkE9PSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "cef43e5e23878364", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "319" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:45 GMT" + ], + "X-Amzn-Requestid": [ + "94a0a89d-1c86-4307-883f-a12668f43041" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTB5SlFZTSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg4MjAxNEU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjc1Mjc5NjhFOSwiTGFzdENoYW5nZWREYXRlIjoxLjc1Mjg3Mzg4MjA0NkU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMDA3OGJiOGU1YzlkOGFiZjdmMWU0ZTE0Yzg3ZDkwMjMyMzViNjIzMCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "995d2adae0203004", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:45 GMT" + ], + "X-Amzn-Requestid": [ + "b9d93cb4-2ec2-4103-a9c1-fb0d4ce5902b" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTB5SlFZTSIsIkRlbGV0aW9uRGF0ZSI6MS43NTI4NzM4ODUzNjlFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "68d96973470e21d9", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "350" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:48 GMT" + ], + "X-Amzn-Requestid": [ + "57f04117-ea15-4675-8ed7-e9ee3a3762eb" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTB5SlFZTSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg4MjAxNEU5LCJEZWxldGVkRGF0ZSI6MS43NTI4NzM4ODUzNzhFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM4ODUzODNFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "ef77947c6d453c16", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "350" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:49 GMT" + ], + "X-Amzn-Requestid": [ + "e6c5f91b-be00-4c9e-ade2-107779c85922" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTB5SlFZTSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg4MjAxNEU5LCJEZWxldGVkRGF0ZSI6MS43NTI4NzM4ODUzNzhFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM4ODUzODNFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "da21a1b9810db137", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:49 GMT" + ], + "X-Amzn-Requestid": [ + "211e0c4d-d358-4e21-93eb-d98be21f98c5" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestInvalidJSON.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestInvalidJSON.replay new file mode 100644 index 000000000..30defa805 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestInvalidJSON.replay @@ -0,0 +1,432 @@ +{ + "Initial": "AQAAAA7gDLJ7K8ShvgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "4ff7843d91acdd81", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "146" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0zMzMzYzU5NjE3OTFjMjg3MDI4MzY2NTgxYWQ3NmQ5MjFjYTYxY2FkIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiYm05MExXcHpiMjQ9In0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:11 GMT" + ], + "X-Amzn-Requestid": [ + "4477fa24-a4ee-49b8-a078-ba6014ff2789" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLW9samphViIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTMzMzNjNTk2MTc5MWMyODcwMjgzNjY1ODFhZDc2ZDkyMWNhNjFjYWQifQ==" + } + }, + { + "ID": "8e4614d25e17a3e3", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "288" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:15 GMT" + ], + "X-Amzn-Requestid": [ + "ec08234f-4d45-4872-9518-35591eaa3814" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLW9samphViIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg1MTk0NkU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJibTkwTFdwemIyND0iLCJWZXJzaW9uSWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0zMzMzYzU5NjE3OTFjMjg3MDI4MzY2NTgxYWQ3NmQ5MjFjYTYxY2FkIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "d6942c1e7c3bc4ea", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "288" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:15 GMT" + ], + "X-Amzn-Requestid": [ + "759d4088-e662-4ad9-9cb0-a0557e5e93c5" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLW9samphViIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg1MTk0NkU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJibTkwTFdwemIyND0iLCJWZXJzaW9uSWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0zMzMzYzU5NjE3OTFjMjg3MDI4MzY2NTgxYWQ3NmQ5MjFjYTYxY2FkIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "b4e04ebaa3dde095", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "319" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:15 GMT" + ], + "X-Amzn-Requestid": [ + "e9cd823b-07ce-4bf3-8554-dbf43d1e11ef" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLW9samphViIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg1MTkxM0U5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjc1Mjc5NjhFOSwiTGFzdENoYW5nZWREYXRlIjoxLjc1Mjg3Mzg1MTk0OUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMzMzM2M1OTYxNzkxYzI4NzAyODM2NjU4MWFkNzZkOTIxY2E2MWNhZCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "faa660cd5fb2b36c", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:15 GMT" + ], + "X-Amzn-Requestid": [ + "b9937f1f-b810-4f32-97a1-c1ffdb83992e" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLW9samphViIsIkRlbGV0aW9uRGF0ZSI6MS43NTI4NzM4NTUyNzRFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "da20380faefb4bbc", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "350" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:18 GMT" + ], + "X-Amzn-Requestid": [ + "ff036b6d-667b-47d9-bcda-14403707715b" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLW9samphViIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg1MTkxM0U5LCJEZWxldGVkRGF0ZSI6MS43NTI4NzM4NTUyODRFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM4NTUyOTJFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTMzMzNjNTk2MTc5MWMyODcwMjgzNjY1ODFhZDc2ZDkyMWNhNjFjYWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "fe09e997564727f8", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:20 GMT" + ], + "X-Amzn-Requestid": [ + "686e8ca1-eb45-4c26-9ee4-f46b510ce35a" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestJSON.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestJSON.replay new file mode 100644 index 000000000..69626042a --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestJSON.replay @@ -0,0 +1,487 @@ +{ + "Initial": "AQAAAA7gDLJzOduTXQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "22c47a3902fd42aa", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "246" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0wNjllMGIzNTU3ZDExZjNiNTg5OGE3YmI3ZTE4Mzg0ZTMxMjVjYWJjIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiV3dwN0lrNWhiV1VpT2lBaVJXUWlMQ0FpVkdWNGRDSTZJQ0pMYm05amF5QnJibTlqYXk0aWZTd0tleUpPWVcxbElqb2dJbE5oYlNJc0lDSlVaWGgwSWpvZ0lsZG9ieWR6SUhSb1pYSmxQeUo5Q2wwPSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:04 GMT" + ], + "X-Amzn-Requestid": [ + "b3d7ce58-17f5-403d-b5c1-1dcca0acba8b" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWVjVkNsTyIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTA2OWUwYjM1NTdkMTFmM2I1ODk4YTdiYjdlMTgzODRlMzEyNWNhYmMifQ==" + } + }, + { + "ID": "feae7844193b6976", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "388" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:07 GMT" + ], + "X-Amzn-Requestid": [ + "dae71c59-b744-4b8b-9c2b-3b1a37f3e5a3" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWVjVkNsTyIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg0NDE3NEU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJXd3A3SWs1aGJXVWlPaUFpUldRaUxDQWlWR1Y0ZENJNklDSkxibTlqYXlCcmJtOWpheTRpZlN3S2V5Sk9ZVzFsSWpvZ0lsTmhiU0lzSUNKVVpYaDBJam9nSWxkb2J5ZHpJSFJvWlhKbFB5SjlDbDA9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMDY5ZTBiMzU1N2QxMWYzYjU4OThhN2JiN2UxODM4NGUzMTI1Y2FiYyIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "9b2643130285f7f4", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "388" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:07 GMT" + ], + "X-Amzn-Requestid": [ + "564c3e1a-bfd5-4fd3-a4d0-b323f2543068" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWVjVkNsTyIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg0NDE3NEU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJXd3A3SWs1aGJXVWlPaUFpUldRaUxDQWlWR1Y0ZENJNklDSkxibTlqYXlCcmJtOWpheTRpZlN3S2V5Sk9ZVzFsSWpvZ0lsTmhiU0lzSUNKVVpYaDBJam9nSWxkb2J5ZHpJSFJvWlhKbFB5SjlDbDA9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMDY5ZTBiMzU1N2QxMWYzYjU4OThhN2JiN2UxODM4NGUzMTI1Y2FiYyIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "ae854cfc281185ad", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "319" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:07 GMT" + ], + "X-Amzn-Requestid": [ + "ce4664ec-673d-4ccf-bc34-bbdd60629794" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWVjVkNsTyIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg0NDE0NEU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjc1Mjc5NjhFOSwiTGFzdENoYW5nZWREYXRlIjoxLjc1Mjg3Mzg0NDE3N0U5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMDY5ZTBiMzU1N2QxMWYzYjU4OThhN2JiN2UxODM4NGUzMTI1Y2FiYyI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "2a7524b7ac0e0a90", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:07 GMT" + ], + "X-Amzn-Requestid": [ + "e983a274-239a-46d3-8b76-dd5930251b72" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWVjVkNsTyIsIkRlbGV0aW9uRGF0ZSI6MS43NTI4NzM4NDc0OTdFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "84ea3d463a17db59", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "350" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:10 GMT" + ], + "X-Amzn-Requestid": [ + "0c6559af-cac5-4324-a496-0bf25d34b8c2" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWVjVkNsTyIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg0NDE0NEU5LCJEZWxldGVkRGF0ZSI6MS43NTI4NzM4NDc1MDRFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM4NDc1MDhFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTA2OWUwYjM1NTdkMTFmM2I1ODk4YTdiYjdlMTgzODRlMzEyNWNhYmMiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "c923a6d28c42c2ff", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "350" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:10 GMT" + ], + "X-Amzn-Requestid": [ + "28cbc65a-1ee2-4781-b528-4e63ae673390" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWVjVkNsTyIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg0NDE0NEU5LCJEZWxldGVkRGF0ZSI6MS43NTI4NzM4NDc1MDRFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM4NDc1MDhFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTA2OWUwYjM1NTdkMTFmM2I1ODk4YTdiYjdlMTgzODRlMzEyNWNhYmMiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "939aba047968b8ab", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:11 GMT" + ], + "X-Amzn-Requestid": [ + "c76607cb-4a52-4b94-933d-5f6625d36313" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestNonExistentVariable.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestNonExistentVariable.replay new file mode 100644 index 000000000..97bb965cb --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestNonExistentVariable.replay @@ -0,0 +1,102 @@ +{ + "Initial": "AQAAAA7gDLJjJiKADQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "c3034417bcc8c3cf", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "29" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6ImRvZXMtbm90LWV4aXN0In0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:50 GMT" + ], + "X-Amzn-Requestid": [ + "f32c877c-ce81-4f28-974e-ec88b740a143" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestString.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestString.replay new file mode 100644 index 000000000..1575afb32 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestString.replay @@ -0,0 +1,432 @@ +{ + "Initial": "AQAAAA7gDLJmLpsj7QAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "97c0aa39db1ad4e2", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "150" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiYUdWc2JHOGdkMjl5YkdRPSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:51 GMT" + ], + "X-Amzn-Requestid": [ + "636f8a9c-eb17-447f-88fe-3dec42a96835" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWpnQW4yMyIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQifQ==" + } + }, + { + "ID": "3393cb6d803fbaf0", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:54 GMT" + ], + "X-Amzn-Requestid": [ + "9228bf00-2984-4559-84c9-f8ffbc2e6942" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWpnQW4yMyIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3MzgzMDk5NUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "abffdc4d5f665d0f", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:54 GMT" + ], + "X-Amzn-Requestid": [ + "40914c89-3b97-4e85-857f-b1375fd56cab" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWpnQW4yMyIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3MzgzMDk5NUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "882e6db9eac573f0", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "319" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:54 GMT" + ], + "X-Amzn-Requestid": [ + "399f498e-447b-47bf-883e-ce21b413fc89" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWpnQW4yMyIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3MzgzMDk2MUU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjc1Mjc5NjhFOSwiTGFzdENoYW5nZWREYXRlIjoxLjc1Mjg3MzgzMDk5OEU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "762ee8b2ca670a46", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:23:59 GMT" + ], + "X-Amzn-Requestid": [ + "218e2838-d83a-45b3-a1af-99ff6e66b6e9" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWpnQW4yMyIsIkRlbGV0aW9uRGF0ZSI6MS43NTI4NzM4MzkzMzNFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "14172f3fc9be3346", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "350" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:02 GMT" + ], + "X-Amzn-Requestid": [ + "3b998e9a-32d8-4355-9488-f5f4e56bb295" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLWpnQW4yMyIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3MzgzMDk2MUU5LCJEZWxldGVkRGF0ZSI6MS43NTI4NzM4MzkzNDFFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM4MzkzNDhFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "1c5ae9005d24be46", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:03 GMT" + ], + "X-Amzn-Requestid": [ + "4a4ab3b0-9784-49a9-914a-a3954d2a5744" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestUpdate.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestUpdate.replay new file mode 100644 index 000000000..c3d6846d1 --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestUpdate.replay @@ -0,0 +1,762 @@ +{ + "Initial": "AQAAAA7gDLKEHFQTsQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "b7340c4bf2173d06", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "150" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIiwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiU2VjcmV0QmluYXJ5IjoiYUdWc2JHOGdkMjl5YkdRPSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "196" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:20 GMT" + ], + "X-Amzn-Requestid": [ + "3f345508-b333-4677-a54d-b28fc01564f6" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQifQ==" + } + }, + { + "ID": "7b7cce5794d9c160", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:23 GMT" + ], + "X-Amzn-Requestid": [ + "8a2fc569-5ac3-455d-8f6e-1914f66a0f02" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg2MDY4NUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "b8d4010add9265a7", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:23 GMT" + ], + "X-Amzn-Requestid": [ + "5c398e07-07ef-4832-a055-7b4ba5dcdb75" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg2MDY4NUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "2c549ceb921ce754", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "319" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:23 GMT" + ], + "X-Amzn-Requestid": [ + "d82b3bd5-2b52-422c-8c80-5907042bc979" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg2MDY1M0U5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjc1Mjc5NjhFOSwiTGFzdENoYW5nZWREYXRlIjoxLjc1Mjg3Mzg2MDY4OUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "44f92fb04125d73f", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "292" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:24 GMT" + ], + "X-Amzn-Requestid": [ + "c98309bd-3d30-43bb-a005-6e11b092c5c6" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg2MDY4NUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJhR1ZzYkc4Z2QyOXliR1E9IiwiVmVyc2lvbklkIjoidGVzdC1jb25maWctdmFyaWFibGUtMmFhZTZjMzVjOTRmY2ZiNDE1ZGJlOTVmNDA4YjljZTkxZWU4NDZlZCIsIlZlcnNpb25TdGFnZXMiOlsiQVdTQ1VSUkVOVCJdfQ==" + } + }, + { + "ID": "a5f7f00f75a8d791", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "158" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.PutSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0wMDc4YmI4ZTVjOWQ4YWJmN2YxZTRlMTRjODdkOTAyMzIzNWI2MjMwIiwiU2VjcmV0QmluYXJ5IjoiWjI5dlpHSjVaU0IzYjNKc1pBPT0iLCJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "227" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:24 GMT" + ], + "X-Amzn-Requestid": [ + "126ff891-152e-43b8-af7f-5985980b4a19" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIk5hbWUiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "262117cb2d1ba125", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "296" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:27 GMT" + ], + "X-Amzn-Requestid": [ + "e3c723bb-756b-4e32-b1e6-7102592e63df" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg2NDExOEU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJaMjl2WkdKNVpTQjNiM0pzWkE9PSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "501fa5dea86df97b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "296" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:27 GMT" + ], + "X-Amzn-Requestid": [ + "c0ac8207-e62e-4584-8b48-c2ec0929d6f5" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg2NDExOEU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJTZWNyZXRCaW5hcnkiOiJaMjl2WkdKNVpTQjNiM0pzWkE9PSIsIlZlcnNpb25JZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "ec25d073e186ef9b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "399" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:27 GMT" + ], + "X-Amzn-Requestid": [ + "0e2d7dc5-c3b0-482b-9b1b-6f7ada24a744" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg2MDY1M0U5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjc1Mjc5NjhFOSwiTGFzdENoYW5nZWREYXRlIjoxLjc1Mjg3Mzg2NDEyMUU5LCJOYW1lIjoidGVzdC1jb25maWctdmFyaWFibGUiLCJWZXJzaW9uSWRzVG9TdGFnZXMiOnsidGVzdC1jb25maWctdmFyaWFibGUtMDA3OGJiOGU1YzlkOGFiZjdmMWU0ZTE0Yzg3ZDkwMjMyMzViNjIzMCI6WyJBV1NDVVJSRU5UIl0sInRlc3QtY29uZmlnLXZhcmlhYmxlLTJhYWU2YzM1Yzk0ZmNmYjQxNWRiZTk1ZjQwOGI5Y2U5MWVlODQ2ZWQiOlsiQVdTUFJFVklPVVMiXX19" + } + }, + { + "ID": "8a613eb2169b563e", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "69" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LWNvbmZpZy12YXJpYWJsZSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "152" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:27 GMT" + ], + "X-Amzn-Requestid": [ + "80dfb8a3-7876-4086-b6f0-ac3d28e561be" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIkRlbGV0aW9uRGF0ZSI6MS43NTI4NzM4NjczOTdFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + } + }, + { + "ID": "e046c898880e59a3", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "430" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:30 GMT" + ], + "X-Amzn-Requestid": [ + "373496ab-c66a-4213-a1b5-482e1f31d5cf" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg2MDY1M0U5LCJEZWxldGVkRGF0ZSI6MS43NTI4NzM4Njc0MDVFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM4Njc0MTFFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiOlsiQVdTQ1VSUkVOVCJdLCJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIjpbIkFXU1BSRVZJT1VTIl19fQ==" + } + }, + { + "ID": "d3c42c2b9fec816e", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "430" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:31 GMT" + ], + "X-Amzn-Requestid": [ + "8ff78926-efed-4df1-9b7e-3cb5cd12d10a" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtY29uZmlnLXZhcmlhYmxlLTV4WUJiNSIsIkNyZWF0ZWREYXRlIjoxLjc1Mjg3Mzg2MDY1M0U5LCJEZWxldGVkRGF0ZSI6MS43NTI4NzM4Njc0MDVFOSwiTGFzdEFjY2Vzc2VkRGF0ZSI6MS43NTI3OTY4RTksIkxhc3RDaGFuZ2VkRGF0ZSI6MS43NTI4NzM4Njc0MTFFOSwiTmFtZSI6InRlc3QtY29uZmlnLXZhcmlhYmxlIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtY29uZmlnLXZhcmlhYmxlLTAwNzhiYjhlNWM5ZDhhYmY3ZjFlNGUxNGM4N2Q5MDIzMjM1YjYyMzAiOlsiQVdTQ1VSUkVOVCJdLCJ0ZXN0LWNvbmZpZy12YXJpYWJsZS0yYWFlNmMzNWM5NGZjZmI0MTVkYmU5NWY0MDhiOWNlOTFlZTg0NmVkIjpbIkFXU1BSRVZJT1VTIl19fQ==" + } + }, + { + "ID": "c398a139ae49d682", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "35" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtY29uZmlnLXZhcmlhYmxlIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:33 GMT" + ], + "X-Amzn-Requestid": [ + "c78ad9d4-4265-413d-9b48-3bcb25200241" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestUpdateWithErrors.replay b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestUpdateWithErrors.replay new file mode 100644 index 000000000..a9004e0fa --- /dev/null +++ b/go-cloud/runtimevar/awssecretsmanager/testdata/TestConformance/TestUpdateWithErrors.replay @@ -0,0 +1,927 @@ +{ + "Initial": "AQAAAA7gDLKhOqlMKQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "c6196b5e16ceae0b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "192" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.CreateSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTQ3MmFiZDIyZDc5ZDA2MjAzZWQ3MWI4OTc5OWJlNmMzIiwiTmFtZSI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IiLCJTZWNyZXRCaW5hcnkiOiJXM3NpVG1GdFpTSTZJQ0pHYjI4aUxDQWlWR1Y0ZENJNklDSkNZWElpZlYwPSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "221" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:50 GMT" + ], + "X-Amzn-Requestid": [ + "b8d608e9-022c-40dd-a150-0cf2c2d357c9" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiTmFtZSI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IiLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTQ3MmFiZDIyZDc5ZDA2MjAzZWQ3MWI4OTc5OWJlNmMzIn0=" + } + }, + { + "ID": "b580dbf357981e24", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "345" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:53 GMT" + ], + "X-Amzn-Requestid": [ + "5c5eb53a-ba5d-4a37-a52e-23d235fb779d" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiQ3JlYXRlZERhdGUiOjEuNzUyODczODkwNDE0RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiVzNzaVRtRnRaU0k2SUNKR2IyOGlMQ0FpVkdWNGRDSTZJQ0pDWVhJaWZWMD0iLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTQ3MmFiZDIyZDc5ZDA2MjAzZWQ3MWI4OTc5OWJlNmMzIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "712db489ba06f4a9", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "345" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:53 GMT" + ], + "X-Amzn-Requestid": [ + "3c487d93-6835-4555-abe8-73ef67ab14cc" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiQ3JlYXRlZERhdGUiOjEuNzUyODczODkwNDE0RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiVzNzaVRtRnRaU0k2SUNKR2IyOGlMQ0FpVkdWNGRDSTZJQ0pDWVhJaWZWMD0iLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTQ3MmFiZDIyZDc5ZDA2MjAzZWQ3MWI4OTc5OWJlNmMzIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "2dd5399b94a0b4a4", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "344" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:53 GMT" + ], + "X-Amzn-Requestid": [ + "590b29b5-b738-4432-9b83-4217485c8c54" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiQ3JlYXRlZERhdGUiOjEuNzUyODczODkwMzgxRTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzUyNzk2OEU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzUyODczODkwNDE5RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNDcyYWJkMjJkNzlkMDYyMDNlZDcxYjg5Nzk5YmU2YzMiOlsiQVdTQ1VSUkVOVCJdfX0=" + } + }, + { + "ID": "630952a64e0269ff", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "168" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.PutSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTcwNWQxMTYxMDhjNmJmYzlkMThlMjUyNmQwODlkNmMxIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dSIsIlNlY3JldElkIjoidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvciJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "252" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:53 GMT" + ], + "X-Amzn-Requestid": [ + "fd2e7f95-0db3-4b29-aed2-989216410ada" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiTmFtZSI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IiLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTcwNWQxMTYxMDhjNmJmYzlkMThlMjUyNmQwODlkNmMxIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "5be4080700eb138d", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "317" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:56 GMT" + ], + "X-Amzn-Requestid": [ + "90c81cf7-5fea-46a8-bf59-a66b63ce73df" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiQ3JlYXRlZERhdGUiOjEuNzUyODczODkzNzYyRTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dSIsIlZlcnNpb25JZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNzA1ZDExNjEwOGM2YmZjOWQxOGUyNTI2ZDA4OWQ2YzEiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "af25c5fe7068b2d1", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "317" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:56 GMT" + ], + "X-Amzn-Requestid": [ + "756a680f-8316-4a8a-872b-6d141094d6d7" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiQ3JlYXRlZERhdGUiOjEuNzUyODczODkzNzYyRTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dSIsIlZlcnNpb25JZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNzA1ZDExNjEwOGM2YmZjOWQxOGUyNTI2ZDA4OWQ2YzEiLCJWZXJzaW9uU3RhZ2VzIjpbIkFXU0NVUlJFTlQiXX0=" + } + }, + { + "ID": "6a7afcf17661ad30", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "427" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:56 GMT" + ], + "X-Amzn-Requestid": [ + "cabb7b78-b78c-4842-85aa-9c2ae1144471" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiQ3JlYXRlZERhdGUiOjEuNzUyODczODkwMzgxRTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzUyNzk2OEU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzUyODczODkzNzY2RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNDcyYWJkMjJkNzlkMDYyMDNlZDcxYjg5Nzk5YmU2YzMiOlsiQVdTUFJFVklPVVMiXSwidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvci03MDVkMTE2MTA4YzZiZmM5ZDE4ZTI1MjZkMDg5ZDZjMSI6WyJBV1NDVVJSRU5UIl19fQ==" + } + }, + { + "ID": "39d71eb3bdc14b58", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "172" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.PutSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDbGllbnRSZXF1ZXN0VG9rZW4iOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTY0NTVhNzI4OWQ4NjY0NGU3OTBiYTU5NjJiNDE2MTEwIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dU1nPT0iLCJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "252" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:24:57 GMT" + ], + "X-Amzn-Requestid": [ + "9db65ce0-237e-4489-9975-3b75d786e6be" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiTmFtZSI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IiLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTY0NTVhNzI4OWQ4NjY0NGU3OTBiYTU5NjJiNDE2MTEwIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "03e25b88e245c09c", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "321" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:00 GMT" + ], + "X-Amzn-Requestid": [ + "8eb3fdd8-cdfc-4260-8a32-ab4186112d45" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiQ3JlYXRlZERhdGUiOjEuNzUyODczODk3MDc0RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dU1nPT0iLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTY0NTVhNzI4OWQ4NjY0NGU3OTBiYTU5NjJiNDE2MTEwIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "a329d8d57c3e56b3", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.GetSecretValue" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "321" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:00 GMT" + ], + "X-Amzn-Requestid": [ + "f6527c12-8689-4187-8370-6c0cda4c3db8" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiQ3JlYXRlZERhdGUiOjEuNzUyODczODk3MDc0RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiU2VjcmV0QmluYXJ5IjoiYVc1MllXeHBaQzFxYzI5dU1nPT0iLCJWZXJzaW9uSWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTY0NTVhNzI4OWQ4NjY0NGU3OTBiYTU5NjJiNDE2MTEwIiwiVmVyc2lvblN0YWdlcyI6WyJBV1NDVVJSRU5UIl19" + } + }, + { + "ID": "daad0d3a42adb5c6", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "427" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:00 GMT" + ], + "X-Amzn-Requestid": [ + "c37e086c-14be-48f3-874b-64ffd13d9245" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiQ3JlYXRlZERhdGUiOjEuNzUyODczODkwMzgxRTksIkxhc3RBY2Nlc3NlZERhdGUiOjEuNzUyNzk2OEU5LCJMYXN0Q2hhbmdlZERhdGUiOjEuNzUyODczODk3MDc4RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNjQ1NWE3Mjg5ZDg2NjQ0ZTc5MGJhNTk2MmI0MTYxMTAiOlsiQVdTQ1VSUkVOVCJdLCJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTcwNWQxMTYxMDhjNmJmYzlkMThlMjUyNmQwODlkNmMxIjpbIkFXU1BSRVZJT1VTIl19fQ==" + } + }, + { + "ID": "7f77f3abdcd5c7dc", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "80" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DeleteSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJGb3JjZURlbGV0ZVdpdGhvdXRSZWNvdmVyeSI6dHJ1ZSwiU2VjcmV0SWQiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "174" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:00 GMT" + ], + "X-Amzn-Requestid": [ + "98d18e41-47a2-4d42-a822-57998befb5d6" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiRGVsZXRpb25EYXRlIjoxLjc1Mjg3MzkwMDM3NkU5LCJOYW1lIjoidGVzdC11cGRhdGluZy12YXJpYWJsZS10by1lcnJvciJ9" + } + }, + { + "ID": "3dea5b7fcf60d98b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "457" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:03 GMT" + ], + "X-Amzn-Requestid": [ + "a89295ea-a64a-46eb-a9b1-d5676247820a" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiQ3JlYXRlZERhdGUiOjEuNzUyODczODkwMzgxRTksIkRlbGV0ZWREYXRlIjoxLjc1Mjg3MzkwMDM4NEU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjc1Mjc5NjhFOSwiTGFzdENoYW5nZWREYXRlIjoxLjc1Mjg3MzkwMDM5RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNjQ1NWE3Mjg5ZDg2NjQ0ZTc5MGJhNTk2MmI0MTYxMTAiOlsiQVdTQ1VSUkVOVCJdLCJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTcwNWQxMTYxMDhjNmJmYzlkMThlMjUyNmQwODlkNmMxIjpbIkFXU1BSRVZJT1VTIl19fQ==" + } + }, + { + "ID": "81a67c0df714277b", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "457" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:04 GMT" + ], + "X-Amzn-Requestid": [ + "a5513780-1bbc-45db-9565-173a9edd4800" + ] + }, + "Body": "eyJBUk4iOiJhcm46YXdzOnNlY3JldHNtYW5hZ2VyOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6c2VjcmV0OnRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItTzF2MVYzIiwiQ3JlYXRlZERhdGUiOjEuNzUyODczODkwMzgxRTksIkRlbGV0ZWREYXRlIjoxLjc1Mjg3MzkwMDM4NEU5LCJMYXN0QWNjZXNzZWREYXRlIjoxLjc1Mjc5NjhFOSwiTGFzdENoYW5nZWREYXRlIjoxLjc1Mjg3MzkwMDM5RTksIk5hbWUiOiJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yIiwiVmVyc2lvbklkc1RvU3RhZ2VzIjp7InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3ItNjQ1NWE3Mjg5ZDg2NjQ0ZTc5MGJhNTk2MmI0MTYxMTAiOlsiQVdTQ1VSUkVOVCJdLCJ0ZXN0LXVwZGF0aW5nLXZhcmlhYmxlLXRvLWVycm9yLTcwNWQxMTYxMDhjNmJmYzlkMThlMjUyNmQwODlkNmMxIjpbIkFXU1BSRVZJT1VTIl19fQ==" + } + }, + { + "ID": "d15c1807d902b1d9", + "Request": { + "Method": "POST", + "URL": "https://secretsmanager.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "46" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "secretsmanager.DescribeSecret" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJTZWNyZXRJZCI6InRlc3QtdXBkYXRpbmctdmFyaWFibGUtdG8tZXJyb3IifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Content-Length": [ + "99" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 21:25:05 GMT" + ], + "X-Amzn-Requestid": [ + "63972073-68fe-477f-86f2-4fef3d5e473b" + ] + }, + "Body": "eyJfX3R5cGUiOiJSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIiwiTWVzc2FnZSI6IlNlY3JldHMgTWFuYWdlciBjYW4ndCBmaW5kIHRoZSBzcGVjaWZpZWQgc2VjcmV0LiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/runtimevar/blobvar/blobvar.go b/go-cloud/runtimevar/blobvar/blobvar.go new file mode 100644 index 000000000..25aec56f3 --- /dev/null +++ b/go-cloud/runtimevar/blobvar/blobvar.go @@ -0,0 +1,252 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 blobvar provides a runtimevar implementation with +// variables read from a blob.Bucket. +// Use OpenVariable to construct a *runtimevar.Variable. +// +// # URLs +// +// For runtimevar.OpenVariable, blobvar registers for the scheme "blob". +// The default URL opener will open a blob.Bucket based on the environment +// variable "BLOBVAR_BUCKET_URL". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// blobvar exposes the following types for As: +// - Snapshot: Not supported. +// - Error: error, which can be passed to blob.ErrorAs. +package blobvar // import "gocloud.dev/runtimevar/blobvar" + +import ( + "bytes" + "context" + "errors" + "fmt" + "net/url" + "os" + "path" + "sync" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" +) + +func init() { + runtimevar.DefaultURLMux().RegisterVariable(Scheme, &defaultOpener{}) +} + +type defaultOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *defaultOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + o.init.Do(func() { + bucketURL := os.Getenv("BLOBVAR_BUCKET_URL") + if bucketURL == "" { + o.err = errors.New("BLOBVAR_BUCKET_URL environment variable is not set") + return + } + bucket, err := blob.OpenBucket(ctx, bucketURL) + if err != nil { + o.err = fmt.Errorf("failed to open default bucket %q: %v", bucketURL, err) + return + } + o.opener = &URLOpener{Bucket: bucket} + }) + if o.err != nil { + return nil, fmt.Errorf("open variable %v: %v", u, o.err) + } + return o.opener.OpenVariableURL(ctx, u) +} + +// Scheme is the URL scheme blobvar registers its URLOpener under on runtimevar.DefaultMux. +const Scheme = "blob" + +// URLOpener opens blob-backed URLs like "blob://myblobkey?decoder=string". +// It supports the following URL parameters: +// - decoder: The decoder to use. Defaults to URLOpener.Decoder, or +// runtimevar.BytesDecoder if URLOpener.Decoder is nil. +// See runtimevar.DecoderByName for supported values. +// - wait: The poll interval, in time.ParseDuration formats. +// Defaults to 30s. +type URLOpener struct { + // Bucket is required. + Bucket *blob.Bucket + + // Decoder specifies the decoder to use if one is not specified in the URL. + // Defaults to runtimevar.BytesDecoder. + Decoder *runtimevar.Decoder + + // Options specifies the Options for OpenVariable. + Options Options +} + +// OpenVariableURL opens the variable at the URL's path. See the package doc +// for more details. +func (o *URLOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + q := u.Query() + + if o.Bucket == nil { + return nil, fmt.Errorf("open variable %v: bucket is required", u) + } + + decoderName := q.Get("decoder") + q.Del("decoder") + decoder, err := runtimevar.DecoderByName(ctx, decoderName, o.Decoder) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid decoder: %v", u, err) + } + + opts := o.Options + if s := q.Get("wait"); s != "" { + q.Del("wait") + d, err := time.ParseDuration(s) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid wait %q: %v", u, s, err) + } + opts.WaitDuration = d + } + for param := range q { + return nil, fmt.Errorf("open variable %v: invalid query parameter %q", u, param) + } + return OpenVariable(o.Bucket, path.Join(u.Host, u.Path), decoder, &opts) +} + +// Options sets options. +type Options struct { + // WaitDuration controls the rate at which the blob is polled. + // Defaults to 30 seconds. + WaitDuration time.Duration +} + +// OpenVariable constructs a *runtimevar.Variable backed by the referenced blob. +// Reads of the blob return raw bytes; provide a decoder to decode the raw bytes +// into the appropriate type for runtimevar.Snapshot.Value. +// See the runtimevar package documentation for examples of decoders. +func OpenVariable(bucket *blob.Bucket, key string, decoder *runtimevar.Decoder, opts *Options) (*runtimevar.Variable, error) { + return runtimevar.New(newWatcher(bucket, key, decoder, nil, opts)), nil +} + +func newWatcher(bucket *blob.Bucket, key string, decoder *runtimevar.Decoder, opener *URLOpener, opts *Options) driver.Watcher { + if opts == nil { + opts = &Options{} + } + return &watcher{ + bucket: bucket, + opener: opener, + key: key, + wait: driver.WaitDuration(opts.WaitDuration), + decoder: decoder, + } +} + +// state implements driver.State. +type state struct { + val any + updateTime time.Time + rawBytes []byte + err error +} + +// Value implements driver.State.Value. +func (s *state) Value() (any, error) { + return s.val, s.err +} + +// UpdateTime implements driver.State.UpdateTime. +func (s *state) UpdateTime() time.Time { + return s.updateTime +} + +// As implements driver.State.As. +func (s *state) As(i any) bool { + return false +} + +// errorState returns a new State with err, unless prevS also represents +// the same error, in which case it returns nil. +func errorState(err error, prevS driver.State) driver.State { + s := &state{err: err} + if prevS == nil { + return s + } + prev := prevS.(*state) + if prev.err == nil { + // New error. + return s + } + if err == prev.err || err.Error() == prev.err.Error() { + // Same error, return nil to indicate no change. + return nil + } + return s +} + +// watcher implements driver.Watcher for configurations provided by the Runtime Configurator +// service. +type watcher struct { + bucket *blob.Bucket + opener *URLOpener + key string + wait time.Duration + decoder *runtimevar.Decoder +} + +// WatchVariable implements driver.WatchVariable. +func (w *watcher) WatchVariable(ctx context.Context, prev driver.State) (driver.State, time.Duration) { + // Read the blob. + b, err := w.bucket.ReadAll(ctx, w.key) + if err != nil { + return errorState(err, prev), w.wait + } + // See if it's the same raw bytes as before. + if prev != nil && bytes.Equal(b, prev.(*state).rawBytes) { + // No change! + return nil, w.wait + } + + // Decode the value. + val, err := w.decoder.Decode(ctx, b) + if err != nil { + return errorState(err, prev), w.wait + } + return &state{val: val, updateTime: time.Now(), rawBytes: b}, w.wait +} + +// Close implements driver.Close. +func (w *watcher) Close() error { + return nil +} + +// ErrorAs implements driver.ErrorAs. +// Since blobvar uses the blob package, ErrorAs delegates +// to the bucket's ErrorAs method. +func (w *watcher) ErrorAs(err error, i any) bool { + return w.bucket.ErrorAs(err, i) +} + +// ErrorCode implements driver.ErrorCode. +func (*watcher) ErrorCode(err error) gcerrors.ErrorCode { + // err might have come from blob, in which case use its code. + return gcerrors.Code(err) +} diff --git a/go-cloud/runtimevar/blobvar/blobvar_test.go b/go-cloud/runtimevar/blobvar/blobvar_test.go new file mode 100644 index 000000000..56661f856 --- /dev/null +++ b/go-cloud/runtimevar/blobvar/blobvar_test.go @@ -0,0 +1,186 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 blobvar + +import ( + "context" + "errors" + "net/url" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/fileblob" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/drivertest" +) + +type harness struct { + dir string + bucket *blob.Bucket +} + +func newHarness(t *testing.T) (drivertest.Harness, error) { + t.Helper() + + dir := t.TempDir() + + b, err := fileblob.OpenBucket(dir, nil) + if err != nil { + return nil, err + } + + return &harness{dir: dir, bucket: b}, nil +} + +func (h *harness) MakeWatcher(ctx context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) { + return newWatcher(h.bucket, name, decoder, nil, nil), nil +} + +func (h *harness) CreateVariable(ctx context.Context, name string, val []byte) error { + return h.bucket.WriteAll(ctx, name, val, nil) +} + +func (h *harness) UpdateVariable(ctx context.Context, name string, val []byte) error { + return h.bucket.WriteAll(ctx, name, val, nil) +} + +func (h *harness) DeleteVariable(ctx context.Context, name string) error { + return h.bucket.Delete(ctx, name) +} + +func (h *harness) Close() { + h.bucket.Close() + _ = os.RemoveAll(h.dir) +} + +func (h *harness) Mutable() bool { return true } + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct{} + +func (verifyAs) Name() string { + return "verify As" +} + +func (verifyAs) SnapshotCheck(s *runtimevar.Snapshot) error { + return nil +} + +func (verifyAs) ErrorCheck(v *runtimevar.Variable, err error) error { + var perr *os.PathError + if !v.ErrorAs(err, &perr) { + return errors.New("runtimevar.ErrorAs failed with *os.PathError") + } + return nil +} + +func TestOpenVariable(t *testing.T) { + dir := t.TempDir() + + if err := os.WriteFile(filepath.Join(dir, "myvar.json"), []byte(`{"Foo": "Bar"}`), 0o666); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(dir, "myvar.txt"), []byte("hello world!"), 0o666); err != nil { + t.Fatal(err) + } + + // Convert dir to a URL path, adding a leading "/" if needed on Windows + // (on Unix, dirpath already has a leading "/"). + dirpath := filepath.ToSlash(dir) + if os.PathSeparator != '/' && !strings.HasPrefix(dirpath, "/") { + dirpath = "/" + dirpath + } + bucketURL := "file://" + dirpath + + tests := []struct { + BucketURL string + URL string + WantErr bool + WantWatchErr bool + Want any + }{ + // myvar does not exist. + {"mem://", "blob://myvar", false, true, nil}, + // badscheme does not exist. + {"badscheme://", "blob://myvar", true, false, nil}, + // directory dirnotfound does not exist, so Bucket creation fails. + {"file:///dirnotfound", "blob://myvar.txt", true, false, nil}, + // filenotfound does not exist so Watch returns an error. + {bucketURL, "blob://filenotfound", false, true, nil}, + // Missing bucket env variable. + {"", "blob://myvar.txt", true, false, nil}, + // Invalid decoder. + {bucketURL, "blob://myvar.txt?decoder=notadecoder", true, false, nil}, + // Invalid arg. + {bucketURL, "blob://myvar.txt?param=value", true, false, nil}, + // Working example with default decoder. + {bucketURL, "blob://myvar.txt", false, false, []byte("hello world!")}, + // Working example with string decoder. + {bucketURL, "blob://myvar.txt?decoder=string", false, false, "hello world!"}, + // Working example with JSON decoder. + {bucketURL, "blob://myvar.json?decoder=jsonmap", false, false, &map[string]any{"Foo": "Bar"}}, + // Setting wait. + {bucketURL, "blob://myvar.txt?wait=2m", false, false, []byte("hello world!")}, + // Invalid wait. + {bucketURL, "blob://myvar.txt?wait=x", true, false, nil}, + } + + ctx := context.Background() + for _, test := range tests { + t.Run(test.BucketURL, func(t *testing.T) { + t.Setenv("BLOBVAR_BUCKET_URL", test.BucketURL) + + opener := &defaultOpener{} + defer func() { + if opener.opener != nil && opener.opener.Bucket != nil { + opener.opener.Bucket.Close() + } + }() + u, err := url.Parse(test.URL) + if err != nil { + t.Error(err) + } + v, err := opener.OpenVariableURL(ctx, u) + if v != nil { + defer v.Close() + } + if (err != nil) != test.WantErr { + t.Errorf("BucketURL %s URL %s: got error %v, want error %v", test.BucketURL, test.URL, err, test.WantErr) + } + if err != nil { + return + } + defer v.Close() + snapshot, err := v.Watch(ctx) + if (err != nil) != test.WantWatchErr { + t.Errorf("BucketURL %s URL %s: got Watch error %v, want error %v", test.BucketURL, test.URL, err, test.WantWatchErr) + } + if err != nil { + return + } + if !cmp.Equal(snapshot.Value, test.Want) { + t.Errorf("BucketURL %s URL %s: got snapshot value\n%v\n want\n%v", test.BucketURL, test.URL, snapshot.Value, test.Want) + } + }) + } +} diff --git a/go-cloud/runtimevar/blobvar/example_test.go b/go-cloud/runtimevar/blobvar/example_test.go new file mode 100644 index 000000000..75e497b02 --- /dev/null +++ b/go-cloud/runtimevar/blobvar/example_test.go @@ -0,0 +1,72 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 blobvar_test + +import ( + "context" + "fmt" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/blob/memblob" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/blobvar" +) + +func ExampleOpenVariable() { + // Create a *blob.Bucket. + // Here, we use an in-memory implementation and write a sample value. + bucket := memblob.OpenBucket(nil) + defer bucket.Close() + ctx := context.Background() + err := bucket.WriteAll(ctx, "cfg-variable-name", []byte("hello world"), nil) + if err != nil { + log.Fatal(err) + } + + // Construct a *runtimevar.Variable that watches the blob. + v, err := blobvar.OpenVariable(bucket, "cfg-variable-name", runtimevar.StringDecoder, nil) + if err != nil { + log.Fatal(err) + } + defer v.Close() + + // We can now read the current value of the variable from v. + snapshot, err := v.Latest(ctx) + if err != nil { + log.Fatal(err) + } + // runtimevar.Snapshot.Value is decoded to a string. + fmt.Println(snapshot.Value.(string)) + + // Output: + // hello world +} + +func Example_openVariableFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/runtimevar/blobvar" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // runtimevar.OpenVariable creates a *runtimevar.Variable from a URL. + // The default opener opens a blob.Bucket via a URL, based on the environment + // variable BLOBVAR_BUCKET_URL. + + v, err := runtimevar.OpenVariable(ctx, "blob://myvar.txt?decoder=string") + if err != nil { + log.Fatal(err) + } + defer v.Close() +} diff --git a/go-cloud/runtimevar/constantvar/constantvar.go b/go-cloud/runtimevar/constantvar/constantvar.go new file mode 100644 index 000000000..28545d239 --- /dev/null +++ b/go-cloud/runtimevar/constantvar/constantvar.go @@ -0,0 +1,191 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 constantvar provides a runtimevar implementation with Variables +// that never change. Use New, NewBytes, NewFromEnv, or NewError to construct a +// *runtimevar.Variable. +// +// # URLs +// +// For runtimevar.OpenVariable, constantvar registers for the scheme "constant". +// For more details on the URL format, see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// constantvar does not support any types for As. +package constantvar // import "gocloud.dev/runtimevar/constantvar" + +import ( + "context" + "errors" + "fmt" + "net/url" + "os" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" +) + +func init() { + runtimevar.DefaultURLMux().RegisterVariable(Scheme, &URLOpener{}) +} + +// Scheme is the URL scheme constantvar registers its URLOpener under on blob.DefaultMux. +const Scheme = "constant" + +// URLOpener opens constantvar URLs like "constant://?val=foo&decoder=string". +// +// The host and path are ignored. +// +// The following URL parameters are supported: +// - val: The value to use for the constant Variable. The bytes from val +// are passed to NewBytes. +// - envvar: The name of an environment variable to read the value from. +// - err: The error to use for the constant Variable. A new error is created +// using errors.New and passed to NewError. +// - decoder: The decoder to use. Defaults to runtimevar.BytesDecoder. +// See runtimevar.DecoderByName for supported values. +// +// If multiple of "val", "envvar", or "err" are provided, "err" wins, then "envvar", +// then "val". +type URLOpener struct { + // Decoder specifies the decoder to use if one is not specified in the URL. + // Defaults to runtimevar.BytesDecoder. + Decoder *runtimevar.Decoder +} + +// OpenVariableURL opens the variable at the URL's path. See the package doc +// for more details. +func (o *URLOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + q := u.Query() + + val := q.Get("val") + q.Del("val") + + envvar := q.Get("envvar") + q.Del("envvar") + + errVal := q.Get("err") + q.Del("err") + + decoderName := q.Get("decoder") + q.Del("decoder") + decoder, err := runtimevar.DecoderByName(ctx, decoderName, o.Decoder) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid decoder: %v", u, err) + } + + for param := range q { + return nil, fmt.Errorf("open variable %v: invalid query parameter %q", u, param) + } + if errVal != "" { + return NewError(errors.New(errVal)), nil + } + if envvar != "" { + return NewFromEnv(envvar, decoder), nil + } + return NewBytes([]byte(val), decoder), nil +} + +var errNotExist = errors.New("variable does not exist") + +// New constructs a *runtimevar.Variable holding value. +func New(value any) *runtimevar.Variable { + return runtimevar.New(&watcher{value: value, t: time.Now()}) +} + +// NewBytes uses decoder to decode b. If the decode succeeds, it constructs +// a *runtimevar.Variable holding the decoded value. If the decode fails, it +// constructs a runtimevar.Variable that always fails with the error. +func NewBytes(b []byte, decoder *runtimevar.Decoder) *runtimevar.Variable { + value, err := decoder.Decode(context.Background(), b) + if err != nil { + return NewError(err) + } + return New(value) +} + +// NewFromEnv reads an environment variable and uses decoder to decode it. +// If the decode succeeds, it constructs a *runtimevar.Variable holding the +// decoded value. If the decode fails, it constructs a runtimevar.Variable +// that always fails with the error. +// Note that the value of the constantvar is frozen at initialization time; +// it does not get a new value if the underlying environment variable value +// changes. +func NewFromEnv(envVarName string, decoder *runtimevar.Decoder) *runtimevar.Variable { + val := os.Getenv(envVarName) + value, err := decoder.Decode(context.Background(), []byte(val)) + if err != nil { + return NewError(err) + } + return New(value) +} + +// NewError constructs a *runtimevar.Variable that always fails. Runtimevar +// wraps errors returned by drivers, so the error returned +// by runtimevar will not equal err. +func NewError(err error) *runtimevar.Variable { + return runtimevar.New(&watcher{err: err}) +} + +// watcher implements driver.Watcher and driver.State. +type watcher struct { + value any + err error + t time.Time +} + +// Value implements driver.State.Value. +func (w *watcher) Value() (any, error) { + return w.value, w.err +} + +// UpdateTime implements driver.State.UpdateTime. +func (w *watcher) UpdateTime() time.Time { + return w.t +} + +// As implements driver.State.As. +func (w *watcher) As(i any) bool { + return false +} + +// WatchVariable implements driver.WatchVariable. +func (w *watcher) WatchVariable(ctx context.Context, prev driver.State) (driver.State, time.Duration) { + // The first time this is called, return the constant value. + if prev == nil { + return w, 0 + } + // On subsequent calls, block forever as the value will never change. + <-ctx.Done() + w.err = ctx.Err() + return w, 0 +} + +// Close implements driver.Close. +func (*watcher) Close() error { return nil } + +// ErrorAs implements driver.ErrorAs. +func (*watcher) ErrorAs(err error, i any) bool { return false } + +// ErrorCode implements driver.ErrorCode +func (*watcher) ErrorCode(err error) gcerrors.ErrorCode { + if err == errNotExist { + return gcerrors.NotFound + } + return gcerrors.Unknown +} diff --git a/go-cloud/runtimevar/constantvar/constantvar_test.go b/go-cloud/runtimevar/constantvar/constantvar_test.go new file mode 100644 index 000000000..39be712bb --- /dev/null +++ b/go-cloud/runtimevar/constantvar/constantvar_test.go @@ -0,0 +1,231 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 constantvar + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/drivertest" +) + +type harness struct { + // vars stores the variable value(s) that have been set using CreateVariable. + vars map[string][]byte +} + +func newHarness(t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return &harness{vars: map[string][]byte{}}, nil +} + +func (h *harness) MakeWatcher(ctx context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) { + rawVal, found := h.vars[name] + if !found { + // The variable isn't set. Create a Variable that always returns an error. + return &watcher{err: errNotExist}, nil + } + val, err := decoder.Decode(ctx, rawVal) + if err != nil { + // The variable didn't decode. + return &watcher{err: err}, nil + } + return &watcher{value: val, t: time.Now()}, nil +} + +func (h *harness) CreateVariable(ctx context.Context, name string, val []byte) error { + h.vars[name] = val + return nil +} + +func (h *harness) UpdateVariable(ctx context.Context, name string, val []byte) error { + return errors.New("not supported") +} + +func (h *harness) DeleteVariable(ctx context.Context, name string) error { + return errors.New("not supported") +} + +func (h *harness) Close() {} + +func (h *harness) Mutable() bool { return false } + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct{} + +func (verifyAs) Name() string { + return "verify As" +} + +func (verifyAs) SnapshotCheck(s *runtimevar.Snapshot) error { + var ss string + if s.As(&ss) { + return errors.New("Snapshot.As expected to fail") + } + return nil +} + +func (verifyAs) ErrorCheck(v *runtimevar.Variable, err error) error { + var ss string + if v.ErrorAs(err, &ss) { + return errors.New("runtimevar.ErrorAs expected to fail") + } + return nil +} + +func TestNew(t *testing.T) { + ctx := context.Background() + + // Use New with an error value; it should be plumbed through as a Value. + errFail := errors.New("fail") + v := New(errFail) + defer v.Close() + val, err := v.Watch(ctx) + if err != nil { + t.Fatal(err) + } + if val.Value != errFail { + t.Errorf("got %v want %v", val.Value, errFail) + } +} + +func TestNewBytes(t *testing.T) { + ctx := context.Background() + content := "hello world" + + // Decode succeeds. + v := NewBytes([]byte(content), runtimevar.StringDecoder) + defer v.Close() + val, err := v.Watch(ctx) + if err != nil { + t.Fatal(err) + } + if val.Value != content { + t.Errorf("got %v want %v", val.Value, content) + } + + // Decode fails. + var jsonData []string + v = NewBytes([]byte(content), runtimevar.NewDecoder(jsonData, runtimevar.JSONDecode)) + defer v.Close() + val, err = v.Watch(ctx) + if err == nil { + t.Errorf("got nil error and %v, want error", val) + } +} + +func TestNewFromEnv(t *testing.T) { + ctx := context.Background() + const ( + content = "hello world" + name = "RUNTIMEVAR_CONST_TEST" + ) + t.Setenv(name, content) + + // Decode succeeds. + v := NewFromEnv(name, runtimevar.StringDecoder) + defer v.Close() + val, err := v.Watch(ctx) + if err != nil { + t.Fatal(err) + } + if val.Value != content { + t.Errorf("got %v want %v", val.Value, content) + } + + // Decode fails. + var jsonData []string + v = NewFromEnv(name, runtimevar.NewDecoder(jsonData, runtimevar.JSONDecode)) + defer v.Close() + val, err = v.Watch(ctx) + if err == nil { + t.Errorf("got nil error and %v, want error", val) + } +} + +func TestNewError(t *testing.T) { + ctx := context.Background() + + v := NewError(errors.New("fail")) + defer v.Close() + _, err := v.Watch(ctx) + if err == nil { + t.Errorf("got nil err want fail err") + } +} + +func TestOpenVariable(t *testing.T) { + t.Setenv("RUNTIMEVAR_CONST_TEST", "hello world") + tests := []struct { + URL string + WantErr bool + WantWatchErr bool + Want any + }{ + // Empty URL results in empty byte slice. + {"constant://", false, false, []byte("")}, + // Invalid query param. + {"constant://?param=value", true, false, nil}, + // String value. + {"constant://?val=hello+world&decoder=string", false, false, "hello world"}, + // JSON value; val parameter is {"Foo": "Bar"}, URL-encoded. + {"constant://?val=%7B%22Foo%22%3A%22Bar%22%7d&decoder=jsonmap", false, false, &map[string]any{"Foo": "Bar"}}, + // Environment variable value. + {"constant://?envvar=RUNTIMEVAR_CONST_TEST&decoder=string", false, false, "hello world"}, + // Error. + {"constant://?err=fail", false, true, nil}, + // Invalid decoder. + {"constant://?decoder=notadecoder", true, false, nil}, + } + + ctx := context.Background() + for _, test := range tests { + t.Run(test.URL, func(t *testing.T) { + v, err := runtimevar.OpenVariable(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if err != nil { + return + } + defer v.Close() + snapshot, err := v.Watch(ctx) + if (err != nil) != test.WantWatchErr { + t.Errorf("%s: got Watch error %v, want error %v", test.URL, err, test.WantWatchErr) + } + if err != nil { + return + } + if !cmp.Equal(snapshot.Value, test.Want) { + t.Errorf("%s: got snapshot value\n%v\n want\n%v", test.URL, snapshot.Value, test.Want) + } + }) + } +} + +func TestDecryptWithNoURLEnv(t *testing.T) { + if _, err := runtimevar.OpenVariable(context.Background(), "constant://?decoder=decrypt"); err == nil { + t.Error("got nil error, want environment variable not set") + } +} diff --git a/go-cloud/runtimevar/constantvar/example_test.go b/go-cloud/runtimevar/constantvar/example_test.go new file mode 100644 index 000000000..9aa29604c --- /dev/null +++ b/go-cloud/runtimevar/constantvar/example_test.go @@ -0,0 +1,125 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 constantvar_test + +import ( + "context" + "errors" + "fmt" + "log" + "os" + + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/constantvar" +) + +func ExampleNew() { + // Construct a *runtimevar.Variable that always returns "hello world". + v := constantvar.New("hello world") + defer v.Close() + + // We can now read the current value of the variable from v. + snapshot, err := v.Latest(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Println(snapshot.Value.(string)) + + // Output: + // hello world +} + +func ExampleNewBytes() { + // Construct a *runtimevar.Variable with a []byte. + v := constantvar.NewBytes([]byte(`hello world`), runtimevar.BytesDecoder) + defer v.Close() + + // We can now read the current value of the variable from v. + snapshot, err := v.Latest(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("byte slice of length %d\n", len(snapshot.Value.([]byte))) + + // Output: + // byte slice of length 11 +} + +func ExampleNewFromEnv() { + // Construct a *runtimevar.Variable with an environment variable name. + os.Setenv("MY_ENVIRONMENT_VARIABLE", "hello world") + v := constantvar.NewFromEnv("MY_ENVIRONMENT_VARIABLE", runtimevar.BytesDecoder) + defer v.Close() + + // We can now read the value from v. + snapshot, err := v.Latest(context.Background()) + if err != nil { + log.Fatal(err) + } + fmt.Printf("byte slice of length %d\n", len(snapshot.Value.([]byte))) + + // Output: + // byte slice of length 11 +} + +func ExampleNewError() { + // Construct a runtimevar.Variable that always returns errFake. + errFake := errors.New("my error") + v := constantvar.NewError(errFake) + defer v.Close() + + // We can now use Watch to read the current value of the variable + // from v. Note that Latest would block here since it waits for + // a "good" value, and v will never get one. + _, err := v.Watch(context.Background()) + if err == nil { + log.Fatal("Expected an error!") + } + fmt.Println(err) + + // Output: + // runtimevar (code=Unknown): my error +} + +func Example_openVariableFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/runtimevar/constantvar" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // runtimevar.OpenVariable creates a *runtimevar.Variable from a URL. + // The constant value is in the URL param "val". + v, err := runtimevar.OpenVariable(ctx, "constant://?val=hello+world&decoder=string") + if err != nil { + log.Fatal(err) + } + defer v.Close() + + // The constant value is read from an environment variable specified in "envvar". + v2, err := runtimevar.OpenVariable(ctx, "constant://?envvar=MY_ENVIRONMENT_VARIABLE&decoder=string") + if err != nil { + log.Fatal(err) + } + defer v2.Close() + // PRAGMA: On gocloud.dev, hide the rest of the function. + snapshot, err := v.Latest(ctx) + if err != nil { + log.Fatal(err) + } + fmt.Println(snapshot.Value.(string)) + + // Output + // hello world +} diff --git a/go-cloud/runtimevar/driver/driver.go b/go-cloud/runtimevar/driver/driver.go new file mode 100644 index 000000000..f36aa9200 --- /dev/null +++ b/go-cloud/runtimevar/driver/driver.go @@ -0,0 +1,99 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 driver defines interfaces to be implemented by runtimevar drivers, which +// will be used by the runtimevar package to interact with the underlying services. +// Application code should use package runtimevar. +package driver // import "gocloud.dev/runtimevar/driver" + +import ( + "context" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +// DefaultWaitDuration is the default value for WaitDuration. +const DefaultWaitDuration = 30 * time.Second + +// WaitDuration returns DefaultWaitDuration if d is <= 0, otherwise it returns d. +func WaitDuration(d time.Duration) time.Duration { + if d <= 0 { + return DefaultWaitDuration + } + return d +} + +// State represents the current state of a variable. +type State interface { + // Value returns the current variable value. + Value() (any, error) + // UpdateTime returns the update time for the variable. + UpdateTime() time.Time + + // As converts i to driver-specific types. + // See https://gocloud.dev/concepts/as/ for background information. + As(any) bool +} + +// Watcher watches for updates on a variable and returns an updated Variable object if +// there are changes. A Watcher object is associated with a variable upon construction. +// +// An application can have more than one Watcher, one for each variable. It is typical +// to only have one Watcher per variable. +// +// Many services store their configuration data as raw bytes; drivers for such +// services should include a runtimevar.Decoder in their constructor to allow +// users to decode the raw bytes into a particular format (e.g., parsing a +// JSON string). +// +// Drivers for services that don't have raw bytes may dictate the type of the exposed +// Snapshot.Value, or expose custom decoding logic. +type Watcher interface { + // WatchVariable returns the current State of the variable. + // If the State has not changed, it returns nil. + // + // If WatchVariable returns a wait time > 0, the portable type uses + // it as a hint to not call WatchVariable again for the wait time. + // + // Implementations *may* block, but must return if ctx is Done. If the + // variable has changed, then implementations *must* eventually return + // it. + // + // A polling implementation should return (State, ) for + // a new State, or (nil, ) if State hasn't changed. + // + // An implementation that receives notifications from an external source + // about changes to the underlying variable should: + // 1. If prev != nil, subscribe to change notifications. + // 2. Fetch the current State. + // 3. If prev == nil or if the State has changed, return (State, 0). + // A non-zero wait should be returned if State holds an error, to avoid + // spinning. + // 4. Block until it detects a change or ctx is Done, then fetch and return + // (State, 0). + // Note that the subscription in 1 must occur before 2 to avoid race conditions. + WatchVariable(ctx context.Context, prev State) (state State, wait time.Duration) + + // Close cleans up any resources used by the Watcher object. + Close() error + + // ErrorAs allows drivers to expose driver-specific types for returned + // errors; see State.As for more details. + ErrorAs(error, any) bool + + // ErrorCode should return a code that describes the error, which was returned by + // one of the other methods in this interface. + ErrorCode(error) gcerrors.ErrorCode +} diff --git a/go-cloud/runtimevar/drivertest/drivertest.go b/go-cloud/runtimevar/drivertest/drivertest.go new file mode 100644 index 000000000..6b0fd6345 --- /dev/null +++ b/go-cloud/runtimevar/drivertest/drivertest.go @@ -0,0 +1,690 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 drivertest provides a conformance test for implementations of +// runtimevar. +package drivertest // import "gocloud.dev/runtimevar/drivertest" + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" +) + +// Harness describes the functionality test harnesses must provide to run conformance tests. +type Harness interface { + // MakeWatcher creates a driver.Watcher to watch the given variable. + MakeWatcher(ctx context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) + // CreateVariable creates the variable with the given contents. + CreateVariable(ctx context.Context, name string, val []byte) error + // UpdateVariable updates an existing variable to have the given contents. + UpdateVariable(ctx context.Context, name string, val []byte) error + // DeleteVariable deletes an existing variable. + DeleteVariable(ctx context.Context, name string) error + // Close is called when the test is complete. + Close() + // Mutable returns true iff the driver supports UpdateVariable/DeleteVariable. + // If false, those functions should return errors, and the conformance tests + // will skip and/or ignore errors for tests that require them. + Mutable() bool +} + +// HarnessMaker describes functions that construct a harness for running tests. +// It is called exactly once per test; Harness.Close() will be called when the test is complete. +type HarnessMaker func(t *testing.T) (Harness, error) + +// AsTest represents a test of As functionality. +// The conformance test: +// 1. Reads a Snapshot of the variable before it exists. +// 2. Calls ErrorCheck. +// 3. Creates the variable and reads a Snapshot of it. +// 4. Calls SnapshotCheck. +type AsTest interface { + // Name should return a descriptive name for the test. + Name() string + // SnapshotCheck will be called to allow verification of Snapshot.As. + SnapshotCheck(s *runtimevar.Snapshot) error + // ErrorCheck will be called to allow verification of Variable.ErrorAs. + // driver is provided so that errors other than err can be checked; + // Variable.ErrorAs won't work since it expects driver errors to be wrapped. + ErrorCheck(v *runtimevar.Variable, err error) error +} + +type verifyAsFailsOnNil struct{} + +func (verifyAsFailsOnNil) Name() string { + return "verify As returns false when passed nil" +} + +func (verifyAsFailsOnNil) SnapshotCheck(v *runtimevar.Snapshot) error { + if v.As(nil) { + return errors.New("want Snapshot.As to return false when passed nil") + } + return nil +} + +func (verifyAsFailsOnNil) ErrorCheck(v *runtimevar.Variable, err error) (ret error) { + defer func() { + if recover() == nil { + ret = errors.New("want ErrorAs to panic when passed nil") + } + }() + v.ErrorAs(err, nil) + return nil +} + +// RunConformanceTests runs conformance tests for driver implementations +// of runtimevar. +func RunConformanceTests(t *testing.T, newHarness HarnessMaker, asTests []AsTest) { + t.Helper() + + t.Run("TestNonExistentVariable", func(t *testing.T) { + testNonExistentVariable(t, newHarness) + }) + t.Run("TestString", func(t *testing.T) { + testString(t, newHarness) + }) + t.Run("TestJSON", func(t *testing.T) { + testJSON(t, newHarness) + }) + t.Run("TestInvalidJSON", func(t *testing.T) { + testInvalidJSON(t, newHarness) + }) + t.Run("TestUpdate", func(t *testing.T) { + testUpdate(t, newHarness) + }) + t.Run("TestDelete", func(t *testing.T) { + testDelete(t, newHarness) + }) + t.Run("TestUpdateWithErrors", func(t *testing.T) { + testUpdateWithErrors(t, newHarness) + }) + asTests = append(asTests, verifyAsFailsOnNil{}) + t.Run("TestAs", func(t *testing.T) { + for _, st := range asTests { + if st.Name() == "" { + t.Fatalf("AsTest.Name is required") + } + t.Run(st.Name(), func(t *testing.T) { + testAs(t, newHarness, st) + }) + } + }) +} + +// waitTimeForBlockingCheck returns a duration to wait when verifying that a +// call blocks. When in replay mode, it can be quite short to make tests run +// quickly. When in record mode, it has to be long enough that RPCs can +// consistently finish. +func waitTimeForBlockingCheck() time.Duration { + if *setup.Record { + return 5 * time.Second + } + return 10 * time.Millisecond +} + +func testNonExistentVariable(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + h, err := newHarness(t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + ctx := context.Background() + + drv, err := h.MakeWatcher(ctx, "does-not-exist", runtimevar.StringDecoder) + if err != nil { + t.Fatal(err) + } + v := runtimevar.New(drv) + defer func() { + if err := v.Close(); err != nil { + t.Error(err) + } + }() + got, err := v.Watch(ctx) + if err == nil { + t.Errorf("got %v expected not-found error", got.Value) + } else if gcerrors.Code(err) != gcerrors.NotFound { + t.Error("got IsNotExist false, expected true") + } +} + +func testString(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const ( + name = "test-config-variable" + content = "hello world" + ) + + h, err := newHarness(t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + ctx := context.Background() + + if err := h.CreateVariable(ctx, name, []byte(content)); err != nil { + t.Fatal(err) + } + if h.Mutable() { + defer func() { + if err := h.DeleteVariable(ctx, name); err != nil { + t.Fatal(err) + } + }() + } + + drv, err := h.MakeWatcher(ctx, name, runtimevar.StringDecoder) + if err != nil { + t.Fatal(err) + } + v := runtimevar.New(drv) + defer func() { + if err := v.Close(); err != nil { + t.Error(err) + } + }() + got, err := v.Watch(ctx) + if err != nil { + t.Fatal(err) + } + // The variable is decoded to a string and matches the expected content. + if gotS, ok := got.Value.(string); !ok { + t.Fatalf("got value of type %T expected string", got.Value) + } else if gotS != content { + t.Errorf("got %q want %q", got.Value, content) + } + + // A second watch should block forever since the value hasn't changed. + // A short wait here doesn't guarantee that this is working, but will catch + // most problems. + tCtx, cancel := context.WithTimeout(ctx, waitTimeForBlockingCheck()) + defer cancel() + got, err = v.Watch(tCtx) + if err == nil { + t.Errorf("got %v want error", got) + } + // tCtx should be cancelled. However, tests using record/replay mode can + // be in the middle of an RPC when that happens, and save the resulting + // RPC error during record. During replay, that error can be returned + // immediately (before tCtx is cancelled). So, we accept deadline exceeded + // errors as well. + if tCtx.Err() == nil && gcerrors.Code(err) != gcerrors.DeadlineExceeded { + t.Errorf("got err %v/%v; want Watch to have blocked until context was Done, or for the error to be deadline exceeded", err, gcerrors.Code(err)) + } +} + +// Message is used as a target for JSON decoding. +type Message struct { + Name, Text string +} + +func testJSON(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const ( + name = "test-config-variable" + jsonContent = `[ +{"Name": "Ed", "Text": "Knock knock."}, +{"Name": "Sam", "Text": "Who's there?"} +]` + ) + want := []*Message{{Name: "Ed", Text: "Knock knock."}, {Name: "Sam", Text: "Who's there?"}} + + h, err := newHarness(t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + ctx := context.Background() + + if err := h.CreateVariable(ctx, name, []byte(jsonContent)); err != nil { + t.Fatal(err) + } + if h.Mutable() { + defer func() { + if err := h.DeleteVariable(ctx, name); err != nil { + t.Fatal(err) + } + }() + } + + var jsonData []*Message + drv, err := h.MakeWatcher(ctx, name, runtimevar.NewDecoder(jsonData, runtimevar.JSONDecode)) + if err != nil { + t.Fatal(err) + } + v := runtimevar.New(drv) + defer func() { + if err := v.Close(); err != nil { + t.Error(err) + } + }() + got, err := v.Watch(ctx) + if err != nil { + t.Fatal(err) + } + // The variable is decoded to a []*Message and matches the expected content. + if gotSlice, ok := got.Value.([]*Message); !ok { + t.Fatalf("got value of type %T expected []*Message", got.Value) + } else if !cmp.Equal(gotSlice, want) { + t.Errorf("got %v want %v", gotSlice, want) + } +} + +func testInvalidJSON(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const ( + name = "test-config-variable" + content = "not-json" + ) + + h, err := newHarness(t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + ctx := context.Background() + + if err := h.CreateVariable(ctx, name, []byte(content)); err != nil { + t.Fatal(err) + } + if h.Mutable() { + defer func() { + if err := h.DeleteVariable(ctx, name); err != nil { + t.Fatal(err) + } + }() + } + + var jsonData []*Message + drv, err := h.MakeWatcher(ctx, name, runtimevar.NewDecoder(jsonData, runtimevar.JSONDecode)) + if err != nil { + t.Fatal(err) + } + v := runtimevar.New(drv) + defer func() { + if err := v.Close(); err != nil { + t.Error(err) + } + }() + got, err := v.Watch(ctx) + if err == nil { + t.Errorf("got %v wanted invalid-json error", got.Value) + } +} + +func testUpdate(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const ( + name = "test-config-variable" + content1 = "hello world" + content2 = "goodbye world" + ) + + h, err := newHarness(t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + if !h.Mutable() { + return + } + ctx := context.Background() + + // Create the variable and verify WatchVariable sees the value. + if err := h.CreateVariable(ctx, name, []byte(content1)); err != nil { + t.Fatal(err) + } + defer func() { + if err := h.DeleteVariable(ctx, name); err != nil { + t.Fatal(err) + } + }() + + drv, err := h.MakeWatcher(ctx, name, runtimevar.StringDecoder) + if err != nil { + t.Fatal(err) + } + defer func() { + if err := drv.Close(); err != nil { + t.Error(err) + } + }() + state, _ := drv.WatchVariable(ctx, nil) + if state == nil { + t.Fatalf("got nil state, want a non-nil state with a value") + } + got, err := state.Value() + if err != nil { + t.Fatal(err) + } + if gotS, ok := got.(string); !ok { + t.Fatalf("got value of type %T expected string", got) + } else if gotS != content1 { + t.Errorf("got %q want %q", got, content1) + } + + // The variable hasn't changed, so drv.WatchVariable should either + // return nil or block. + cancelCtx, cancel := context.WithTimeout(ctx, waitTimeForBlockingCheck()) + defer cancel() + unchangedState, _ := drv.WatchVariable(cancelCtx, state) + if unchangedState == nil { + // OK + } else { + got, err = unchangedState.Value() + if gcerrors.Code(err) != gcerrors.DeadlineExceeded { + t.Fatalf("got state %v/%v/%v, wanted nil or nil/DeadlineExceeded after no change", got, err, gcerrors.Code(err)) + } + } + + // Update the variable and verify WatchVariable sees the updated value. + if err := h.UpdateVariable(ctx, name, []byte(content2)); err != nil { + t.Fatal(err) + } + state, _ = drv.WatchVariable(ctx, state) + // In rare race conditions during replay, if the earlier WatchVariable + // was cancelled/timed out before actually calling an RPC, this one + // might have returned the old/unchanged value. This only happens during + // replay mode. Just try again, the next RPC should get the updated value. + // BTW this is easy to reproduce by setting the timeout in + // waitForBlockingCheck to 1 nanosecond. + if state == nil && !*setup.Record { + state, _ = drv.WatchVariable(ctx, state) + } + if state == nil { + t.Fatalf("got nil state, want a non-nil state with a value") + } + got, err = state.Value() + if err != nil { + t.Fatal(err) + } + if gotS, ok := got.(string); !ok { + t.Fatalf("got value of type %T expected string", got) + } else if gotS != content2 { + t.Errorf("got %q want %q", got, content2) + } +} + +func testDelete(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const ( + name = "test-config-variable" + content1 = "hello world" + content2 = "goodbye world" + ) + + h, err := newHarness(t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + if !h.Mutable() { + return + } + ctx := context.Background() + + // Create the variable and verify WatchVariable sees the value. + if err := h.CreateVariable(ctx, name, []byte(content1)); err != nil { + t.Fatal(err) + } + needToDelete := true + defer func() { + if needToDelete { + if err := h.DeleteVariable(ctx, name); err != nil { + t.Fatal(err) + } + } + }() + + drv, err := h.MakeWatcher(ctx, name, runtimevar.StringDecoder) + if err != nil { + t.Fatal(err) + } + defer func() { + if err := drv.Close(); err != nil { + t.Error(err) + } + }() + state, _ := drv.WatchVariable(ctx, nil) + if state == nil { + t.Fatalf("got nil state, want a non-nil state with a value") + } + got, err := state.Value() + if err != nil { + t.Fatal(err) + } + if gotS, ok := got.(string); !ok { + t.Fatalf("got value of type %T expected string", got) + } else if gotS != content1 { + t.Errorf("got %q want %q", got, content1) + } + prev := state + + // Delete the variable. + if err := h.DeleteVariable(ctx, name); err != nil { + t.Fatal(err) + } + needToDelete = false + + // WatchVariable should return a state with an error now. + state, _ = drv.WatchVariable(ctx, state) + if state == nil { + t.Fatalf("got nil state, want a non-nil state with an error") + } + got, err = state.Value() + if err == nil { + t.Fatalf("got %v want error because variable is deleted", got) + } + + // Reset the variable with new content and verify via WatchVariable. + if err := h.CreateVariable(ctx, name, []byte(content2)); err != nil { + t.Fatal(err) + } + needToDelete = true + state, _ = drv.WatchVariable(ctx, state) + if state == nil { + t.Fatalf("got nil state, want a non-nil state with a value") + } + got, err = state.Value() + if err != nil { + t.Fatal(err) + } + if gotS, ok := got.(string); !ok { + t.Fatalf("got value of type %T expected string", got) + } else if gotS != content2 { + t.Errorf("got %q want %q", got, content2) + } + if state.UpdateTime().Before(prev.UpdateTime()) { + t.Errorf("got UpdateTime %v < previous %v, want >=", state.UpdateTime(), prev.UpdateTime()) + } +} + +func testUpdateWithErrors(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + const ( + name = "test-updating-variable-to-error" + content1 = `[{"Name": "Foo", "Text": "Bar"}]` + content2 = "invalid-json" + content3 = "invalid-json2" + ) + want := []*Message{{Name: "Foo", Text: "Bar"}} + + h, err := newHarness(t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + if !h.Mutable() { + return + } + ctx := context.Background() + + // Create the variable and verify WatchVariable sees the value. + if err := h.CreateVariable(ctx, name, []byte(content1)); err != nil { + t.Fatal(err) + } + defer func() { + if err := h.DeleteVariable(ctx, name); err != nil { + t.Fatal(err) + } + }() + + var jsonData []*Message + drv, err := h.MakeWatcher(ctx, name, runtimevar.NewDecoder(jsonData, runtimevar.JSONDecode)) + if err != nil { + t.Fatal(err) + } + defer func() { + if err := drv.Close(); err != nil { + t.Error(err) + } + }() + state, _ := drv.WatchVariable(ctx, nil) + if state == nil { + t.Fatal("got nil state, want a non-nil state with a value") + } + got, err := state.Value() + if err != nil { + t.Fatal(err) + } + if gotSlice, ok := got.([]*Message); !ok { + t.Fatalf("got value of type %T expected []*Message", got) + } else if !cmp.Equal(gotSlice, want) { + t.Errorf("got %v want %v", gotSlice, want) + } + + // Update the variable to invalid JSON and verify WatchVariable returns an error. + if err := h.UpdateVariable(ctx, name, []byte(content2)); err != nil { + t.Fatal(err) + } + state, _ = drv.WatchVariable(ctx, state) + if state == nil { + t.Fatal("got nil state, want a non-nil state with an error") + } + _, err = state.Value() + if err == nil { + t.Fatal("got nil err want invalid JSON error") + } + + // Update the variable again, with different invalid JSON. + // WatchVariable should block or return nil since it's the same error as before. + if err := h.UpdateVariable(ctx, name, []byte(content3)); err != nil { + t.Fatal(err) + } + tCtx, cancel := context.WithTimeout(ctx, waitTimeForBlockingCheck()) + defer cancel() + state, _ = drv.WatchVariable(tCtx, state) + if state == nil { + // OK: nil indicates no change. + } else { + // WatchVariable should have blocked until tCtx was cancelled, and we + // should have gotten that error back. + got, err := state.Value() + if err == nil { + t.Fatalf("got %v and nil error, want non-nil error", got) + } + // tCtx should be cancelled. However, tests using record/replay mode can + // be in the middle of an RPC when that happens, and save the resulting + // RPC error during record. During replay, that error can be returned + // immediately (before tCtx is cancelled). So, we accept deadline exceeded + // errors as well. + if tCtx.Err() == nil && gcerrors.Code(err) != gcerrors.DeadlineExceeded { + t.Errorf("got err %v/%v; want Watch to have blocked until context was Done, or for the error to be deadline exceeded", err, gcerrors.Code(err)) + } + } +} + +// testAs tests the various As functions, using AsTest. +func testAs(t *testing.T, newHarness HarnessMaker, st AsTest) { + t.Helper() + + const ( + name = "variable-for-as" + content = "hello world" + ) + + h, err := newHarness(t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + ctx := context.Background() + + // Try to read the variable before it exists. + drv, err := h.MakeWatcher(ctx, name, runtimevar.StringDecoder) + if err != nil { + t.Fatal(err) + } + v := runtimevar.New(drv) + s, gotErr := v.Watch(ctx) + if gotErr == nil { + t.Fatalf("got nil error and %v, expected non-nil error", v) + } + if err := st.ErrorCheck(v, gotErr); err != nil { + t.Error(err) + } + var dummy string + if s.As(&dummy) { + t.Error(errors.New("want Snapshot.As to return false when Snapshot is zero value")) + } + if err := v.Close(); err != nil { + t.Error(err) + } + + // Create the variable and verify WatchVariable sees the value. + if err := h.CreateVariable(ctx, name, []byte(content)); err != nil { + t.Fatal(err) + } + if h.Mutable() { + defer func() { + if err := h.DeleteVariable(ctx, name); err != nil { + t.Fatal(err) + } + }() + } + + drv, err = h.MakeWatcher(ctx, name, runtimevar.StringDecoder) + if err != nil { + t.Fatal(err) + } + v = runtimevar.New(drv) + defer func() { + if err := v.Close(); err != nil { + t.Error(err) + } + }() + s, err = v.Watch(ctx) + if err != nil { + t.Fatal(err) + } + if err := st.SnapshotCheck(&s); err != nil { + t.Error(err) + } +} diff --git a/go-cloud/runtimevar/etcdvar/etcdvar.go b/go-cloud/runtimevar/etcdvar/etcdvar.go new file mode 100644 index 000000000..a00c90fec --- /dev/null +++ b/go-cloud/runtimevar/etcdvar/etcdvar.go @@ -0,0 +1,325 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 etcdvar provides a runtimevar implementation with variables +// backed by etcd. Use OpenVariable to construct a *runtimevar.Variable. +// +// # URLs +// +// For runtimevar.OpenVariable, etcdvar registers for the scheme "etcd". +// The default URL opener will dial an etcd server based on the environment +// variable "ETCD_SERVER_URL". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// etcdvar exposes the following types for As: +// - Snapshot: *clientv3.GetResponse +// - Error: rpctypes.EtcdError +package etcdvar // import "gocloud.dev/runtimevar/etcdvar" + +import ( + "context" + "errors" + "fmt" + "net/url" + "os" + "path" + "sync" + "time" + + "go.etcd.io/etcd/client/v3" + "go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "google.golang.org/grpc/codes" +) + +func init() { + runtimevar.DefaultURLMux().RegisterVariable(Scheme, &defaultDialer{}) +} + +// Scheme is the URL scheme etcdvar registers its URLOpener under on runtimevar.DefaultMux. +const Scheme = "etcd" + +type defaultDialer struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *defaultDialer) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + o.init.Do(func() { + serverURL := os.Getenv("ETCD_SERVER_URL") + if serverURL == "" { + o.err = errors.New("ETCD_SERVER_URL environment variable is not set") + return + } + client, err := clientv3.NewFromURL(serverURL) + if err != nil { + o.err = fmt.Errorf("failed to connect to default client %q: %v", serverURL, err) + return + } + o.opener = &URLOpener{Client: client} + }) + if o.err != nil { + return nil, fmt.Errorf("open variable %v: %v", u, o.err) + } + return o.opener.OpenVariableURL(ctx, u) +} + +// URLOpener opens etcd URLs like "etcd://mykey?decoder=string". +// +// The host+path is used as the variable name. +// +// The following URL parameters are supported: +// - decoder: The decoder to use. Defaults to runtimevar.BytesDecoder. +// See runtimevar.DecoderByName for supported values. +type URLOpener struct { + // The Client to use; required. + Client *clientv3.Client + + // Decoder specifies the decoder to use if one is not specified in the URL. + // Defaults to runtimevar.BytesDecoder. + Decoder *runtimevar.Decoder + + // Options specifies the options to pass to OpenVariable. + Options Options +} + +// OpenVariableURL opens a etcdvar Variable for u. +func (o *URLOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + q := u.Query() + + decoderName := q.Get("decoder") + q.Del("decoder") + decoder, err := runtimevar.DecoderByName(ctx, decoderName, o.Decoder) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid decoder: %v", u, err) + } + + for param := range q { + return nil, fmt.Errorf("open variable %v: invalid query parameter %q", u, param) + } + return OpenVariable(o.Client, path.Join(u.Host, u.Path), decoder, &o.Options) +} + +// Options sets options. +type Options struct { + // Timeout controls the timeout on RPCs to etcd; timeouts will result in + // errors being returned from Watch. Defaults to 30 seconds. + Timeout time.Duration +} + +// OpenVariable constructs a *runtimevar.Variable that uses client to watch the variable +// name on an etcd server. +// etcd returns raw bytes; provide a decoder to decode the raw bytes into the +// appropriate type for runtimevar.Snapshot.Value. +// See the runtimevar package documentation for examples of decoders. +func OpenVariable(cli *clientv3.Client, name string, decoder *runtimevar.Decoder, opts *Options) (*runtimevar.Variable, error) { + return runtimevar.New(newWatcher(cli, name, decoder, opts)), nil +} + +func newWatcher(cli *clientv3.Client, name string, decoder *runtimevar.Decoder, opts *Options) *watcher { + if opts == nil { + opts = &Options{} + } + // Create a ctx for the background goroutine that does all of the reading. + // The cancel function will be used to shut it down during Close. + ctx, cancel := context.WithCancel(context.Background()) + w := &watcher{ + // See struct comments for why it's buffered. + ch: make(chan *state, 1), + shutdown: cancel, + } + go w.watch(ctx, cli, name, decoder, driver.WaitDuration(opts.Timeout)) + return w +} + +// errNotExist is a sentinel error for nonexistent variables. +var errNotExist = errors.New("variable does not exist") + +// state implements driver.State. +type state struct { + val any + raw *clientv3.GetResponse + updateTime time.Time + version int64 + err error +} + +// Value implements driver.State.Value. +func (s *state) Value() (any, error) { + return s.val, s.err +} + +// UpdateTime implements driver.State.UpdateTime. +func (s *state) UpdateTime() time.Time { + return s.updateTime +} + +// As implements driver.State.As. +func (s *state) As(i any) bool { + if s.raw == nil { + return false + } + p, ok := i.(**clientv3.GetResponse) + if !ok { + return false + } + *p = s.raw + return true +} + +// watcher implements driver.Watcher. +type watcher struct { + // The background goroutine writes new *state values to ch. + // It is buffered so that the background goroutine can write without + // blocking; it always drains the buffer before writing so that the latest + // write is buffered. If writes could block, the background goroutine could be + // blocked indefinitely from reading etcd's Watch events. + // The background goroutine closes ch during shutdown. + ch chan *state + // shutdown tells the background goroutine to exit. + shutdown func() +} + +// WatchVariable implements driver.WatchVariable. +func (w *watcher) WatchVariable(ctx context.Context, _ driver.State) (driver.State, time.Duration) { + select { + case <-ctx.Done(): + return &state{err: ctx.Err()}, 0 + case cur := <-w.ch: + return cur, 0 + } +} + +// updateState checks to see if s and prev both represent the same error. +// If not, it drains any previous state buffered in w.ch, then writes s to it. +// It always return s. +func (w *watcher) updateState(s, prev *state) *state { + if s.err != nil && prev != nil && prev.err != nil { + if equivalentError(s.err, prev.err) { + // s represents the same error as prev. + return s + } + } + // Drain any buffered value on ch; it is now stale. + select { + case <-w.ch: + default: + } + // This write can't block, since we're the only writer, ch has a buffer + // size of 1, and we just read anything that was buffered. + w.ch <- s + return s +} + +// equivalentError returns true iff err1 and err2 represent an equivalent error; +// i.e., we don't want to return it to the user as a different error. +func equivalentError(err1, err2 error) bool { + if err1 == err2 || err1.Error() == err2.Error() { + return true + } + var code1, code2 codes.Code + if etcdErr, ok := err1.(rpctypes.EtcdError); ok { + code1 = etcdErr.Code() + } + if etcdErr, ok := err2.(rpctypes.EtcdError); ok { + code2 = etcdErr.Code() + } + return code1 != codes.OK && code1 == code2 +} + +// watch is run by a background goroutine. +// It watches file using cli.Watch, and writes new states to w.ch. +// It exits when ctx is canceled, and closes w.ch. +func (w *watcher) watch(ctx context.Context, cli *clientv3.Client, name string, decoder *runtimevar.Decoder, timeout time.Duration) { + var cur *state + defer close(w.ch) + + var watchCh clientv3.WatchChan + for { + if watchCh == nil { + ctxWithTimeout, cancel := context.WithTimeout(ctx, timeout) + watchCh = cli.Watch(ctxWithTimeout, name) + cancel() + } + + ctxWithTimeout, cancel := context.WithTimeout(ctx, timeout) + resp, err := cli.Get(ctxWithTimeout, name) + cancel() + if err != nil { + cur = w.updateState(&state{err: err}, cur) + } else if len(resp.Kvs) == 0 { + cur = w.updateState(&state{err: errNotExist}, cur) + } else if len(resp.Kvs) > 1 { + cur = w.updateState(&state{err: fmt.Errorf("%q has multiple values", name)}, cur) + } else { + kv := resp.Kvs[0] + if cur == nil || cur.err != nil || kv.Version != cur.version { + val, err := decoder.Decode(ctx, kv.Value) + if err != nil { + cur = w.updateState(&state{err: err}, cur) + } else { + cur = w.updateState(&state{val: val, raw: resp, updateTime: time.Now(), version: kv.Version}, cur) + } + } + } + + // Value hasn't changed. Wait for change events. + select { + case <-ctx.Done(): + return + case _, ok := <-watchCh: + if !ok { + // watchCh has closed; retry in next loop iteration. + watchCh = nil + } + } + } +} + +// Close implements driver.Close. +func (w *watcher) Close() error { + // Tell the background goroutine to shut down by canceling its ctx. + w.shutdown() + // Wait for it to exit. + for range w.ch { + } + return nil +} + +// ErrorAs implements driver.ErrorAs. +func (w *watcher) ErrorAs(err error, i any) bool { + switch v := err.(type) { + case rpctypes.EtcdError: + if p, ok := i.(*rpctypes.EtcdError); ok { + *p = v + return true + } + } + return false +} + +// ErrorCode implements driver.ErrorCode. +func (*watcher) ErrorCode(err error) gcerrors.ErrorCode { + if err == errNotExist { + return gcerrors.NotFound + } + return gcerrors.Unknown +} diff --git a/go-cloud/runtimevar/etcdvar/etcdvar_test.go b/go-cloud/runtimevar/etcdvar/etcdvar_test.go new file mode 100644 index 000000000..df41cb863 --- /dev/null +++ b/go-cloud/runtimevar/etcdvar/etcdvar_test.go @@ -0,0 +1,204 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 etcdvar + +import ( + "context" + "errors" + "os" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "go.etcd.io/etcd/client/v3" + "go.etcd.io/etcd/etcdserver/api/v3rpc/rpctypes" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/drivertest" +) + +// To run these tests against a local etcd server, first run ./localetcd.sh. +// Then wait a few seconds for the server to be ready. + +type harness struct { + client *clientv3.Client +} + +func newHarness(t *testing.T) (drivertest.Harness, error) { + if !setup.HasDockerTestEnvironment() { + t.Skip("Skipping etcd tests since the etcd server is not available") + } + c, err := clientv3.NewFromURL("http://localhost:2379") + if err != nil { + t.Fatalf("No local etcd server running: %v; see runtimevar/etcdvar/localetcd.sh", err) + } + return &harness{client: c}, nil +} + +func (h *harness) MakeWatcher(ctx context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) { + return newWatcher(h.client, name, decoder, nil), nil +} + +func (h *harness) CreateVariable(ctx context.Context, name string, val []byte) error { + _, err := h.client.Put(ctx, name, string(val)) + return err +} + +func (h *harness) UpdateVariable(ctx context.Context, name string, val []byte) error { + return h.CreateVariable(ctx, name, val) +} + +func (h *harness) DeleteVariable(ctx context.Context, name string) error { + _, err := h.client.Delete(ctx, name) + return err +} + +func (h *harness) Mutable() bool { return true } + +func (h *harness) Close() {} + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct{} + +func (verifyAs) Name() string { + return "verify As" +} + +func (verifyAs) SnapshotCheck(s *runtimevar.Snapshot) error { + var resp *clientv3.GetResponse + if !s.As(&resp) { + return errors.New("Snapshot.As failed") + } + return nil +} + +func (verifyAs) ErrorCheck(v *runtimevar.Variable, err error) error { + // etcdvar returns a fmt.Errorf error for "not found", so this is expected + // to fail. + var to rpctypes.EtcdError + if v.ErrorAs(err, &to) { + return errors.New("ErrorAs expected to fail") + } + // Try with a real etcd error. + if !v.ErrorAs(rpctypes.ErrUnhealthy, &to) { + return errors.New("ErrorAs expected to succeed with real etcd error") + } + return nil +} + +// Etcd-specific tests. + +func TestEquivalentError(t *testing.T) { + tests := []struct { + Err1, Err2 error + Want bool + }{ + {Err1: errors.New("not etcd"), Err2: errors.New("not etcd"), Want: true}, + {Err1: errors.New("not etcd"), Err2: errors.New("not etcd but different")}, + {Err1: errors.New("not etcd"), Err2: rpctypes.ErrUnhealthy}, + {Err1: rpctypes.ErrUnhealthy, Err2: rpctypes.ErrRequestTooLarge}, + {Err1: rpctypes.ErrUnhealthy, Err2: rpctypes.ErrUnhealthy, Want: true}, + } + + for _, test := range tests { + got := equivalentError(test.Err1, test.Err2) + if got != test.Want { + t.Errorf("%v vs %v: got %v want %v", test.Err1, test.Err2, got, test.Want) + } + } +} + +func TestNoConnectionError(t *testing.T) { + cli, err := clientv3.NewFromURL("http://no.server.here:999") + if err != nil { + t.Fatal(err) + } + v, err := OpenVariable(cli, "variable-name", nil, nil) + if err != nil { + t.Fatal(err) + } + defer v.Close() + // Watch will block for quite a while trying to connect, + // so use a short timeout. + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond) + defer cancel() + _, err = v.Watch(ctx) + if err == nil { + t.Error("got nil want error") + } +} + +func TestOpenVariable(t *testing.T) { + h, err := newHarness(t) + if err != nil { + t.Fatal(err) + } + os.Setenv("ETCD_SERVER_URL", "http://localhost:2379") + + ctx := context.Background() + if err := h.CreateVariable(ctx, "string-var", []byte("hello world")); err != nil { + t.Fatal(err) + } + if err := h.CreateVariable(ctx, "json-var", []byte(`{"Foo": "Bar"}`)); err != nil { + t.Fatal(err) + } + + tests := []struct { + URL string + WantErr bool + WantWatchErr bool + Want any + }{ + // Nonexistentvar does not exist, so we get an error from Watch. + {"etcd://nonexistentvar", false, true, nil}, + // Invalid decoder arg. + {"etcd://string-var?decoder=notadecoder", true, false, nil}, + // Invalid parameter. + {"etcd://string-var?param=value", true, false, nil}, + // Working example with string decoder. + {"etcd://string-var?decoder=string", false, false, "hello world"}, + // Working example with default decoder. + {"etcd://string-var", false, false, []byte("hello world")}, + // Working example with JSON decoder. + {"etcd://json-var?decoder=jsonmap", false, false, &map[string]any{"Foo": "Bar"}}, + } + + for _, test := range tests { + t.Run(test.URL, func(t *testing.T) { + v, err := runtimevar.OpenVariable(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if err != nil { + return + } + defer v.Close() + snapshot, err := v.Watch(ctx) + if (err != nil) != test.WantWatchErr { + t.Errorf("%s: got Watch error %v, want error %v", test.URL, err, test.WantWatchErr) + } + if err != nil { + return + } + if !cmp.Equal(snapshot.Value, test.Want) { + t.Errorf("%s: got snapshot value\n%v\n want\n%v", test.URL, snapshot.Value, test.Want) + } + }) + } +} diff --git a/go-cloud/runtimevar/etcdvar/example_test.go b/go-cloud/runtimevar/etcdvar/example_test.go new file mode 100644 index 000000000..2d92e80c5 --- /dev/null +++ b/go-cloud/runtimevar/etcdvar/example_test.go @@ -0,0 +1,58 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 etcdvar_test + +import ( + "context" + "log" + + "go.etcd.io/etcd/client/v3" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/etcdvar" +) + +func ExampleOpenVariable() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // Connect to the etcd server. + client, err := clientv3.NewFromURL("http://your.etcd.server:9999") + if err != nil { + log.Fatal(err) + } + + // Construct a *runtimevar.Variable that watches the variable. + v, err := etcdvar.OpenVariable(client, "cfg-variable-name", runtimevar.StringDecoder, nil) + if err != nil { + log.Fatal(err) + } + defer v.Close() +} + +func Example_openVariableFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/runtimevar/etcdvar" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // runtimevar.OpenVariable creates a *runtimevar.Variable from a URL. + // The default opener connects to an etcd server based on the environment + // variable ETCD_SERVER_URL. + + v, err := runtimevar.OpenVariable(ctx, "etcd://myvarname?decoder=string") + if err != nil { + log.Fatal(err) + } + defer v.Close() +} diff --git a/go-cloud/runtimevar/etcdvar/go.mod b/go-cloud/runtimevar/etcdvar/go.mod new file mode 100644 index 000000000..a8f256144 --- /dev/null +++ b/go-cloud/runtimevar/etcdvar/go.mod @@ -0,0 +1,84 @@ +// Copyright 2018-2019 The Go Cloud Development Kit 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 +// +// https://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. + +module gocloud.dev/runtimevar/etcdvar + +go 1.24 + +require ( + github.com/google/go-cmp v0.7.0 + go.etcd.io/etcd v3.3.27+incompatible + go.etcd.io/etcd/client/v3 v3.6.2 + gocloud.dev v0.43.0 + google.golang.org/grpc v1.73.0 +) + +require ( + cloud.google.com/go/auth v0.16.3 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + cloud.google.com/go/compute/metadata v0.7.0 // indirect + github.com/aws/aws-sdk-go v1.55.7 // indirect + github.com/aws/aws-sdk-go-v2 v1.36.5 // indirect + github.com/aws/aws-sdk-go-v2/config v1.29.17 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.70 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 // indirect + github.com/aws/smithy-go v1.22.4 // indirect + github.com/coreos/go-semver v0.3.1 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/go-replayers/grpcreplay v1.3.0 // indirect + github.com/google/go-replayers/httpreplay v1.2.0 // indirect + github.com/google/martian/v3 v3.3.3 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/google/wire v0.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + go.etcd.io/etcd/api/v3 v3.6.2 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.2 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect + go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/sdk v1.37.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect + go.opentelemetry.io/otel/trace v1.37.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + google.golang.org/api v0.242.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 // indirect + google.golang.org/protobuf v1.36.6 // indirect +) diff --git a/go-cloud/runtimevar/etcdvar/go.sum b/go-cloud/runtimevar/etcdvar/go.sum new file mode 100644 index 000000000..d6b42bd3a --- /dev/null +++ b/go-cloud/runtimevar/etcdvar/go.sum @@ -0,0 +1,700 @@ +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +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.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= +cloud.google.com/go v0.121.4 h1:cVvUiY0sX0xwyxPwdSU2KsF9knOVmtRyAMt8xou0iTs= +cloud.google.com/go v0.121.4/go.mod h1:XEBchUiHFJbz4lKBZwYBDHV/rSyfFktk737TLDU089s= +cloud.google.com/go/auth v0.16.3 h1:kabzoQ9/bobUmnseYnBO6qQG7q4a/CffFRlJSxv2wCc= +cloud.google.com/go/auth v0.16.3/go.mod h1:NucRGjaXfzP1ltpcQ7On/VTZ0H4kWB5Jy+Y9Dnm76fA= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/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/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= +cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +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/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= +cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk= +cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8= +cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= +cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= +cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM= +cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U= +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= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.55.0 h1:NESjdAToN9u1tmhVqhXCaCwYBuvEhZLLv0gBr+2znf0= +cloud.google.com/go/storage v1.55.0/go.mod h1:ztSmTTwzsdXe5syLVS0YsbFxXuvEmEyZj7v7zChEmuY= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0= +github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2/config v1.29.17 h1:jSuiQ5jEe4SAMH6lLRMY9OVC+TqJLP5655pBGjmnjr0= +github.com/aws/aws-sdk-go-v2/config v1.29.17/go.mod h1:9P4wwACpbeXs9Pm9w1QTh6BwWwJjwYvJ1iCt5QbCXh8= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70 h1:ONnH5CM16RTXRkS8Z1qg7/s2eDOhHhaXVd72mmyv4/0= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70/go.mod h1:M+lWhhmomVGgtuPOhO85u4pEa3SmssPTdcYpP/5J/xc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 h1:KAXP9JSHO1vKGCr5f4O6WmlVKLFFXgWYAGoJosorxzU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32/go.mod h1:h4Sg6FQdexC1yYG9RDnOvLbW1a/P986++/Y/a+GyEM8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 h1:t0E6FzREdtCsiLIoLCWsYliNsRBgyGD/MCK571qk4MI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17/go.mod h1:ygpklyoaypuyDvOM5ujWGrYWpAK3h7ugnmKCU/76Ys4= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 h1:AIRJ3lfb2w/1/8wOOSqYb9fUKGwQbtysJ2H1MofRUPg= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5/go.mod h1:b7SiVprpU+iGazDUqvRSLf5XmCdn+JtT1on7uNL6Ipc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 h1:BpOxT3yhLwSJ77qIY3DoHAQjZsc4HEGfMCE4NGy3uFg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3/go.mod h1:vq/GQR1gOFLquZMSrxUK/cpvKCNVYibNyJ1m7JrU88E= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 h1:NFOJ/NXEGV4Rq//71Hs1jC/NvPs1ezajK+yQmkwnPV0= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0/go.mod h1:7ph2tGpfQvwzgistp2+zga9f+bCjlQJPkPUmMgDSD7w= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +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= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +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/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= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +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= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-replayers/grpcreplay v1.3.0 h1:1Keyy0m1sIpqstQmgz307zhiJ1pV4uIlFds5weTmxbo= +github.com/google/go-replayers/grpcreplay v1.3.0/go.mod h1:v6NgKtkijC0d3e3RW8il6Sy5sqRVUwoQa4mHOGEy8DI= +github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk= +github.com/google/go-replayers/httpreplay v1.2.0/go.mod h1:WahEFFZZ7a1P4VM1qEeHy+tME4bwyqPcwWbNlUI1Mcg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= +github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +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.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +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/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +go.etcd.io/etcd v3.3.27+incompatible h1:5hMrpf6REqTHV2LW2OclNpRtxI0k9ZplMemJsMSWju0= +go.etcd.io/etcd v3.3.27+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI= +go.etcd.io/etcd/api/v3 v3.6.2 h1:25aCkIMjUmiiOtnBIp6PhNj4KdcURuBak0hU2P1fgRc= +go.etcd.io/etcd/api/v3 v3.6.2/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk= +go.etcd.io/etcd/client/pkg/v3 v3.6.2 h1:zw+HRghi/G8fKpgKdOcEKpnBTE4OO39T6MegA0RopVU= +go.etcd.io/etcd/client/pkg/v3 v3.6.2/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI= +go.etcd.io/etcd/client/v3 v3.6.2 h1:RgmcLJxkpHqpFvgKNwAQHX3K+wsSARMXKgjmUSpoSKQ= +go.etcd.io/etcd/client/v3 v3.6.2/go.mod h1:PL7e5QMKzjybn0FosgiWvCUDzvdChpo5UgGR4Sk4Gzc= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0 h1:B+WbN9RPsvobe6q4vP6KgM8/9plR/HNjgGBrfcOlweA= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0/go.mod h1:K5zQ3TT7p2ru9Qkzk0bKtCql0RGkPj9pRjpXgZJZ+rU= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 h1:rbRJ8BBoVMsQShESYZ0FkvcITu8X8QNwJogcLUmDNNw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0/go.mod h1:ru6KHrNtNHxM4nD/vd6QrLVWgKhxPYgblq4VAtNawTQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/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.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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/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= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +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-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= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/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.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-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/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.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.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +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-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +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.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.242.0 h1:7Lnb1nfnpvbkCiZek6IXKdJ0MFuAZNAJKQfA1ws62xg= +google.golang.org/api v0.242.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= +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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +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= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 h1:Nt6z9UHqSlIdIGJdz6KhTIs2VRx/iOsA5iE8bmQNcxs= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79/go.mod h1:kTmlBHMPqR5uCZPBvwa2B18mvubkjyY3CRLI0c6fj0s= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79 h1:iOye66xuaAK0WnkPuhQPUFy8eJcmwUXqGGP3om6IxX8= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79/go.mod h1:HKJDgKsFUnv5VAGeQjz8kxcgDP0HoE0iZNp0OdZNlhE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 h1:1ZwqphdOdWYXsUHgMpU/101nCtf/kSp9hOrcvFsnl10= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +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.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/go-cloud/runtimevar/etcdvar/localetcd.sh b/go-cloud/runtimevar/etcdvar/localetcd.sh new file mode 100755 index 000000000..e6ed2814a --- /dev/null +++ b/go-cloud/runtimevar/etcdvar/localetcd.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Starts a local etcd instance via Docker. + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +set -euo pipefail + +# Clean up and run etcd. +echo "Starting etcd..." +docker rm -f etcd &> /dev/null || : +docker run -d -p 2379:2379 -p 4001:4001 --name etcd quay.io/coreos/etcd:v3.5.4 /usr/local/bin/etcd --advertise-client-urls http://0.0.0.0:2379 --listen-client-urls http://0.0.0.0:2379 &> /dev/null +echo "...done. Run \"docker rm -f etcd\" to clean up the container." +echo diff --git a/go-cloud/runtimevar/example_openvariable_test.go b/go-cloud/runtimevar/example_openvariable_test.go new file mode 100644 index 000000000..fbff13e60 --- /dev/null +++ b/go-cloud/runtimevar/example_openvariable_test.go @@ -0,0 +1,52 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 runtimevar_test + +import ( + "context" + "fmt" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + _ "github.com/DataDog/iceberg-go/go-cloud/runtimevar/constantvar" +) + +func Example_openVariableFromURL() { + // Connect to a Variable using a URL. + // This example uses "constantvar", an in-memory implementation. + // We need to add a blank import line to register the constantvar driver's + // URLOpener, which implements runtimevar.VariableURLOpener: + // import _ "gocloud.dev/runtimevar/constantvar" + // constantvar registers for the "constant" scheme. + // All runtimevar.OpenVariable URLs also work with "runtimevar+" or "runtimevar+variable+" prefixes, + // e.g., "runtimevar+constant://..." or "runtimevar+variable+constant://...". + ctx := context.Background() + v, err := runtimevar.OpenVariable(ctx, "constant://?val=hello+world&decoder=string") + if err != nil { + log.Fatal(err) + } + defer v.Close() + + // Now we can use the Variable as normal. + snapshot, err := v.Latest(ctx) + if err != nil { + log.Fatal(err) + } + // It's safe to cast the Value to string since we used the string decoder. + fmt.Printf("%s\n", snapshot.Value.(string)) + + // Output: + // hello world +} diff --git a/go-cloud/runtimevar/example_test.go b/go-cloud/runtimevar/example_test.go new file mode 100644 index 000000000..6a08eaa28 --- /dev/null +++ b/go-cloud/runtimevar/example_test.go @@ -0,0 +1,191 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 runtimevar_test + +import ( + "context" + "fmt" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/constantvar" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + + _ "github.com/DataDog/iceberg-go/go-cloud/runtimevar/gcpruntimeconfig" + runtimeconfig "google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1" + "google.golang.org/grpc/status" +) + +func Example_jsonDecoder() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Config is the sample config struct we're going to parse our JSON into. + type Config struct { + Host string + Port int + } + + // A sample JSON config that will decode into Config. + const jsonConfig = `{"Host": "gocloud.dev", "Port": 8080}` + + // Construct a Decoder that decodes raw bytes into our config. + decoder := runtimevar.NewDecoder(Config{}, runtimevar.JSONDecode) + + // Next, a construct a *Variable using a constructor or URL opener. + // This example uses constantvar. + // If you're using a URL opener, you can't decode JSON into a struct, but + // you can use the query parameter "decoder=jsonmap" to decode into a map. + v := constantvar.NewBytes([]byte(jsonConfig), decoder) + defer v.Close() + // snapshot.Value will be of type Config. + + // PRAGMA: On gocloud.dev, hide the rest of the function. + snapshot, err := v.Latest(ctx) + if err != nil { + log.Fatalf("Error in retrieving variable: %v", err) + } + fmt.Printf("Config: %+v\n", snapshot.Value.(Config)) + + // Output: + // Config: {Host:gocloud.dev Port:8080} +} + +func Example_stringDecoder() { + // Construct a *Variable using a constructor from one of the + // runtimevar subpackages. This example uses constantvar. + // The variable value is of type string, so we use StringDecoder. + v := constantvar.NewBytes([]byte("hello world"), runtimevar.StringDecoder) + defer v.Close() + + // Call Latest to retrieve the value. + snapshot, err := v.Latest(context.Background()) + if err != nil { + log.Fatalf("Error in retrieving variable: %v", err) + } + // snapshot.Value will be of type string. + fmt.Printf("%q\n", snapshot.Value.(string)) + + // Output: + // "hello world" +} + +func ExampleVariable_Latest() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + var v *runtimevar.Variable + + snapshot, err := v.Latest(context.Background()) + if err != nil { + log.Fatalf("Error in retrieving variable: %v", err) + } + // PRAGMA: On gocloud.dev, hide the rest of the function. + _ = snapshot +} + +func ExampleSnapshot_As() { + // This example is specific to the gcpruntimeconfig implementation; it + // demonstrates access to the underlying + // google.golang.org/genproto/googleapis/cloud/runtimeconfig.Variable type. + // The types exposed for As by gcpruntimeconfig are documented in + // https://godoc.org/gocloud.dev/runtimevar/gcpruntimeconfig#hdr-As + ctx := context.Background() + + const url = "gcpruntimeconfig://proj/config/key" + v, err := runtimevar.OpenVariable(ctx, url) + if err != nil { + log.Fatal(err) + } + + s, err := v.Latest(ctx) + if err != nil { + log.Fatal(err) + } + + var rcv *runtimeconfig.Variable + if s.As(&rcv) { + fmt.Println(rcv.UpdateTime) + } +} + +func ExampleVariable_ErrorAs() { + // This example is specific to the gcpruntimeconfig implementation; it + // demonstrates access to the underlying google.golang.org/grpc/status.Status + // type. + // The types exposed for As by gcpruntimeconfig are documented in + // https://godoc.org/gocloud.dev/runtimevar/gcpruntimeconfig#hdr-As + ctx := context.Background() + + const url = "gcpruntimeconfig://proj/wrongconfig/key" + v, err := runtimevar.OpenVariable(ctx, url) + if err != nil { + log.Fatal(err) + } + + _, err = v.Watch(ctx) + if err != nil { + var s *status.Status + if v.ErrorAs(err, &s) { + fmt.Println(s.Code()) + } + } +} + +func ExampleVariable_Watch() { + // Construct a *Variable using a constructor from one of the + // runtimevar subpackages. This example uses constantvar. + // The variable value is of type string, so we use StringDecoder. + v := constantvar.NewBytes([]byte("hello world"), runtimevar.StringDecoder) + defer v.Close() + + // Call Watch in a loop from a background goroutine to see all changes, + // including errors. + // + // You can use this for logging, or to trigger behaviors when the + // config changes. + // + // Note that Latest always returns the latest "good" config, so seeing + // an error from Watch doesn't mean that Latest will return one. + go func() { + for { + snapshot, err := v.Watch(context.Background()) + if err == runtimevar.ErrClosed { + // v has been closed; exit. + return + } + if err == nil { + // Casting to a string here because we used StringDecoder. + log.Printf("New config: %v", snapshot.Value.(string)) + } else { + log.Printf("Error loading config: %v", err) + // Even though there's been an error loading the config, + // v.Latest will continue to return the latest "good" value. + } + } + }() +} + +func ExampleDecryptDecode() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + var keeper *secrets.Keeper + + decodeFunc := runtimevar.DecryptDecode(keeper, runtimevar.StringDecode) + decoder := runtimevar.NewDecoder("", decodeFunc) + + // PRAGMA: On gocloud.dev, hide the rest of the function. + _ = decoder +} diff --git a/go-cloud/runtimevar/filevar/example_test.go b/go-cloud/runtimevar/filevar/example_test.go new file mode 100644 index 000000000..04fdc59d8 --- /dev/null +++ b/go-cloud/runtimevar/filevar/example_test.go @@ -0,0 +1,69 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 filevar_test + +import ( + "context" + "fmt" + "log" + "os" + + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/filevar" +) + +func ExampleOpenVariable() { + // Create a temporary file to hold our config. + f, err := os.CreateTemp("", "") + if err != nil { + log.Fatal(err) + } + if _, err := f.Write([]byte("hello world")); err != nil { + log.Fatal(err) + } + + // Construct a *runtimevar.Variable pointing at f. + v, err := filevar.OpenVariable(f.Name(), runtimevar.StringDecoder, nil) + if err != nil { + log.Fatal(err) + } + defer v.Close() + + // We can now read the current value of the variable from v. + snapshot, err := v.Latest(context.Background()) + if err != nil { + log.Fatal(err) + } + // runtimevar.Snapshot.Value is decoded to a string. + fmt.Println(snapshot.Value.(string)) + + // Output: + // hello world +} + +func Example_openVariableFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/runtimevar/filevar" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // runtimevar.OpenVariable creates a *runtimevar.Variable from a URL. + + v, err := runtimevar.OpenVariable(ctx, "file:///path/to/config.txt?decoder=string") + if err != nil { + log.Fatal(err) + } + defer v.Close() +} diff --git a/go-cloud/runtimevar/filevar/filevar.go b/go-cloud/runtimevar/filevar/filevar.go new file mode 100644 index 000000000..3f9b04fec --- /dev/null +++ b/go-cloud/runtimevar/filevar/filevar.go @@ -0,0 +1,344 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 filevar provides a runtimevar implementation with variables +// backed by the filesystem. Use OpenVariable to construct a *runtimevar.Variable. +// +// Configuration files can be updated using any commands (cp, mv) or +// tools/editors. This package does not guarantee read consistency since +// it does not have control over the writes. For example, some kinds of +// updates might result in filevar temporarily receiving an error or an +// empty value. +// +// Known Issues: +// +// * On macOS, if an empty file is copied into a configuration file, +// +// filevar will not detect the change. +// +// # URLs +// +// For runtimevar.OpenVariable, filevar registers for the scheme "file". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// filevar does not support any types for As. +package filevar // import "gocloud.dev/runtimevar/filevar" + +import ( + "bytes" + "context" + "errors" + "fmt" + "net/url" + "os" + "path/filepath" + "strings" + "time" + + "github.com/fsnotify/fsnotify" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" +) + +func init() { + runtimevar.DefaultURLMux().RegisterVariable(Scheme, &URLOpener{}) +} + +// Scheme is the URL scheme filevar registers its URLOpener under on runtimevar.DefaultMux. +const Scheme = "file" + +// URLOpener opens filevar URLs like "file:///path/to/config.json?decoder=json". +// +// The URL's host+path is used as the path to the file to watch. +// If os.PathSeparator != "/", any leading "/" from the path is dropped +// and remaining '/' characters are converted to os.PathSeparator. +// +// The following URL parameters are supported: +// - decoder: The decoder to use. Defaults to URLOpener.Decoder, or +// runtimevar.BytesDecoder if URLOpener.Decoder is nil. +// See runtimevar.DecoderByName for supported values. +// - wait: The frequency for retries after an error, in time.ParseDuration formats. +// Defaults to 30s. +type URLOpener struct { + // Decoder specifies the decoder to use if one is not specified in the URL. + // Defaults to runtimevar.BytesDecoder. + Decoder *runtimevar.Decoder + + // Options specifies the options to pass to OpenVariable. + Options Options +} + +// OpenVariableURL opens the variable at the URL's path. See the package doc +// for more details. +func (o *URLOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + q := u.Query() + + decoderName := q.Get("decoder") + q.Del("decoder") + decoder, err := runtimevar.DecoderByName(ctx, decoderName, o.Decoder) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid decoder: %v", u, err) + } + opts := o.Options + if s := q.Get("wait"); s != "" { + q.Del("wait") + d, err := time.ParseDuration(s) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid wait %q: %v", u, s, err) + } + opts.WaitDuration = d + } + + for param := range q { + return nil, fmt.Errorf("open variable %v: invalid query parameter %q", u, param) + } + path := u.Path + if os.PathSeparator != '/' { + path = strings.TrimPrefix(path, "/") + } + return OpenVariable(filepath.FromSlash(path), decoder, &opts) +} + +// Options sets options. +type Options struct { + // WaitDuration controls the frequency of retries after an error. For example, + // if the file does not exist. Defaults to 30 seconds. + WaitDuration time.Duration +} + +// OpenVariable constructs a *runtimevar.Variable backed by the file at path. +// The file holds raw bytes; provide a decoder to decode the raw bytes into the +// appropriate type for runtimevar.Snapshot.Value. +// See the runtimevar package documentation for examples of decoders. +func OpenVariable(path string, decoder *runtimevar.Decoder, opts *Options) (*runtimevar.Variable, error) { + w, err := newWatcher(path, decoder, opts) + if err != nil { + return nil, err + } + return runtimevar.New(w), nil +} + +func newWatcher(path string, decoder *runtimevar.Decoder, opts *Options) (*watcher, error) { + if opts == nil { + opts = &Options{} + } + if path == "" { + return nil, errors.New("path is required") + } + if decoder == nil { + return nil, errors.New("decoder is required") + } + + // Use absolute file path. + abspath, err := filepath.Abs(path) + if err != nil { + return nil, err + } + + // Construct a fsnotify.Watcher. + notifier, err := fsnotify.NewWatcher() + if err != nil { + return nil, err + } + + // Create a ctx for the background goroutine that does all of the reading. + // The cancel function will be used to shut it down during Close, with the + // result being passed back via closeCh. + ctx, cancel := context.WithCancel(context.Background()) + w := &watcher{ + path: abspath, + // See struct comments for why it's buffered. + ch: make(chan *state, 1), + closeCh: make(chan error), + shutdown: cancel, + } + go w.watch(ctx, notifier, abspath, decoder, driver.WaitDuration(opts.WaitDuration)) + return w, nil +} + +// errNotExist wraps an underlying error in cases where the file likely doesn't +// exist. +type errNotExist struct { + err error +} + +func (e *errNotExist) Error() string { + return e.err.Error() +} + +// state implements driver.State. +type state struct { + val any + updateTime time.Time + raw []byte + err error +} + +func (s *state) Value() (any, error) { + return s.val, s.err +} + +func (s *state) UpdateTime() time.Time { + return s.updateTime +} + +func (s *state) As(i any) bool { + return false +} + +// watcher implements driver.Watcher for configurations stored in files. +type watcher struct { + // The path for the file we're watching. + path string + // The background goroutine writes new *state values to ch. + // It is buffered so that the background goroutine can write without + // blocking; it always drains the buffer before writing so that the latest + // write is buffered. If writes could block, the background goroutine could be + // blocked indefinitely from reading fsnotify events. + ch chan *state + // closeCh is used to return any errors from closing the notifier + // back to watcher.Close. + closeCh chan error + // shutdown tells the background goroutine to exit. + shutdown func() +} + +// WatchVariable implements driver.WatchVariable. +func (w *watcher) WatchVariable(ctx context.Context, _ driver.State) (driver.State, time.Duration) { + select { + case <-ctx.Done(): + return &state{err: ctx.Err()}, 0 + case cur := <-w.ch: + return cur, 0 + } +} + +// updateState checks to see if s and prev both represent the same error. +// If not, it drains any previous state buffered in w.ch, then writes s to it. +// It always return s. +func (w *watcher) updateState(s, prev *state) *state { + if s.err != nil && prev != nil && prev.err != nil && (s.err == prev.err || s.err.Error() == prev.err.Error() || (os.IsNotExist(s.err) && os.IsNotExist(prev.err))) { + // s represents the same error as prev. + return s + } + // Drain any buffered value on ch; it is now stale. + select { + case <-w.ch: + default: + } + // This write can't block, since we're the only writer, ch has a buffer + // size of 1, and we just read anything that was buffered. + w.ch <- s + return s +} + +// watch is run by a background goroutine. +// It watches file using notifier, and writes new states to w.ch. +// If it can't read or watch the file, it re-checks every wait. +// It exits when ctx is canceled, and writes any shutdown errors (or +// nil if there weren't any) to w.closeCh. +func (w *watcher) watch(ctx context.Context, notifier *fsnotify.Watcher, file string, decoder *runtimevar.Decoder, wait time.Duration) { + var cur *state + + for { + // If the current state is an error, pause between attempts + // to avoid spin loops. In particular, this happens when the file + // doesn't exist. + if cur != nil && cur.err != nil { + select { + case <-ctx.Done(): + w.closeCh <- notifier.Close() + return + case <-time.After(wait): + } + } + + // Add the file to the notifier to be watched. It's fine to be + // added multiple times, and fsnotifier is a bit flaky about when + // it's needed during renames, so just always try. + if err := notifier.Add(file); err != nil { + // File probably does not exist. Try again later. + cur = w.updateState(&state{err: &errNotExist{err}}, cur) + continue + } + + // Read the file. + b, err := os.ReadFile(file) + if err != nil { + // File probably does not exist. Try again later. + cur = w.updateState(&state{err: &errNotExist{err}}, cur) + continue + } + + // If it's a new value, decode and return it. + if cur == nil || cur.err != nil || !bytes.Equal(cur.raw, b) { + if val, err := decoder.Decode(ctx, b); err != nil { + cur = w.updateState(&state{err: err}, cur) + } else { + cur = w.updateState(&state{val: val, updateTime: time.Now(), raw: b}, cur) + } + } + + // Block until notifier tells us something relevant changed. + wait := true + for wait { + select { + case <-ctx.Done(): + w.closeCh <- notifier.Close() + return + + case event := <-notifier.Events: + if event.Name != file { + continue + } + // Ignore if not one of the following operations. + if event.Op&(fsnotify.Create|fsnotify.Write|fsnotify.Remove|fsnotify.Rename) == 0 { + continue + } + wait = false + + case err := <-notifier.Errors: + cur = w.updateState(&state{err: err}, cur) + } + } + } +} + +// Close implements driver.WatchVariable. +func (w *watcher) Close() error { + // Tell the background goroutine to shut down by canceling its ctx. + w.shutdown() + // Wait for it to return the result of closing the notifier. + err := <-w.closeCh + // Cleanup our channels. + close(w.ch) + close(w.closeCh) + return err +} + +// ErrorAs implements driver.ErrorAs. +func (w *watcher) ErrorAs(err error, i any) bool { return false } + +// ErrorCode implements driver.ErrorCode. +func (*watcher) ErrorCode(err error) gcerrors.ErrorCode { + if _, ok := err.(*errNotExist); ok { + return gcerrors.NotFound + } + return gcerrors.Unknown +} diff --git a/go-cloud/runtimevar/filevar/filevar_test.go b/go-cloud/runtimevar/filevar/filevar_test.go new file mode 100644 index 000000000..a49ff07d5 --- /dev/null +++ b/go-cloud/runtimevar/filevar/filevar_test.go @@ -0,0 +1,291 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 filevar + +import ( + "context" + "errors" + "net/url" + "os" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/drivertest" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + _ "github.com/DataDog/iceberg-go/go-cloud/secrets/localsecrets" +) + +type harness struct { + dir string + closer func() +} + +func newHarness(t *testing.T) (drivertest.Harness, error) { + t.Helper() + + dir := t.TempDir() + + return &harness{ + dir: dir, + closer: func() { _ = os.RemoveAll(dir) }, + }, nil +} + +func (h *harness) MakeWatcher(ctx context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) { + // filevar uses a goroutine in the background that poll every WaitDuration if + // the file is deleted. Make this fast for tests. + return newWatcher(filepath.Join(h.dir, name), decoder, &Options{WaitDuration: 1 * time.Millisecond}) +} + +func (h *harness) CreateVariable(ctx context.Context, name string, val []byte) error { + // Write to a temporary file and rename; otherwise, + // Watch can read an empty file during the write. + tmp, err := os.CreateTemp(h.dir, "tmp") + if err != nil { + return err + } + if _, err := tmp.Write(val); err != nil { + tmp.Close() + return err + } + tmp.Close() + return os.Rename(tmp.Name(), filepath.Join(h.dir, name)) +} + +func (h *harness) UpdateVariable(ctx context.Context, name string, val []byte) error { + return h.CreateVariable(ctx, name, val) +} + +func (h *harness) DeleteVariable(ctx context.Context, name string) error { + path := filepath.Join(h.dir, name) + return os.Remove(path) +} + +func (h *harness) Close() { + h.closer() +} + +func (h *harness) Mutable() bool { return true } + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct{} + +func (verifyAs) Name() string { + return "verify As" +} + +func (verifyAs) SnapshotCheck(s *runtimevar.Snapshot) error { + var ss string + if s.As(&ss) { + return errors.New("Snapshot.As expected to fail") + } + return nil +} + +func (verifyAs) ErrorCheck(v *runtimevar.Variable, err error) error { + var ss string + if v.ErrorAs(err, &ss) { + return errors.New("runtimevar.ErrorAs expected to fail") + } + return nil +} + +// Filevar-specific tests. + +func TestOpenVariable(t *testing.T) { + dir := t.TempDir() + + tests := []struct { + description string + path string + decoder *runtimevar.Decoder + want string + wantErr bool + }{ + { + description: "empty path results in error", + decoder: runtimevar.StringDecoder, + wantErr: true, + }, + { + description: "empty decoder results in error", + path: filepath.Join(dir, "foo.txt"), + wantErr: true, + }, + { + description: "basic path works", + path: filepath.Join(dir, "foo.txt"), + decoder: runtimevar.StringDecoder, + want: filepath.Join(dir, "foo.txt"), + }, + { + description: "path with extra relative dirs works and is cleaned up", + path: filepath.Join(dir, "bar/../foo.txt"), + decoder: runtimevar.StringDecoder, + want: filepath.Join(dir, "foo.txt"), + }, + } + + for _, test := range tests { + t.Run(test.description, func(t *testing.T) { + // Create driver impl. + drv, err := newWatcher(test.path, test.decoder, nil) + if (err != nil) != test.wantErr { + t.Errorf("got err %v want error %v", err, test.wantErr) + } + if drv != nil { + if drv.path != test.want { + t.Errorf("got %q want %q", drv.path, test.want) + } + drv.Close() + } + + // Create portable type. + w, err := OpenVariable(test.path, test.decoder, nil) + if (err != nil) != test.wantErr { + t.Errorf("got err %v want error %v", err, test.wantErr) + } + if w != nil { + w.Close() + } + }) + } +} + +func TestOpenVariableURL(t *testing.T) { + dir := t.TempDir() + + jsonPath := filepath.Join(dir, "myvar.json") + if err := os.WriteFile(jsonPath, []byte(`{"Foo": "Bar"}`), 0o666); err != nil { + t.Fatal(err) + } + txtPath := filepath.Join(dir, "myvar.txt") + if err := os.WriteFile(txtPath, []byte("hello world!"), 0o666); err != nil { + t.Fatal(err) + } + nonexistentPath := filepath.Join(dir, "filenotfound") + ctx := context.Background() + secretsPath := filepath.Join(dir, "mysecret.txt") + cleanup, err := setupTestSecrets(ctx, dir, secretsPath) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + // Convert paths to a URL path, adding a leading "/" if needed on Windows + // (on Unix, dirpath already has a leading "/"). + jsonPath = filepath.ToSlash(jsonPath) + txtPath = filepath.ToSlash(txtPath) + nonexistentPath = filepath.ToSlash(nonexistentPath) + secretsPath = filepath.ToSlash(secretsPath) + if os.PathSeparator != '/' { + if !strings.HasPrefix(jsonPath, "/") { + jsonPath = "/" + jsonPath + } + if !strings.HasPrefix(txtPath, "/") { + txtPath = "/" + txtPath + } + if !strings.HasPrefix(nonexistentPath, "/") { + nonexistentPath = "/" + nonexistentPath + } + if !strings.HasPrefix(secretsPath, "/") { + secretsPath = "/" + secretsPath + } + } + + tests := []struct { + URL string + WantErr bool + WantWatchErr bool + Want any + }{ + // Variable construction succeeds, but the file does not exist. + {"file://" + nonexistentPath, false, true, nil}, + // Variable construction fails due to invalid decoder arg. + {"file://" + txtPath + "?decoder=notadecoder", true, false, nil}, + // Variable construction fails due to invalid arg. + {"file://" + txtPath + "?param=value", true, false, nil}, + // Working example with default decoder. + {"file://" + txtPath, false, false, []byte("hello world!")}, + // Working example with string decoder. + {"file://" + txtPath + "?decoder=string", false, false, "hello world!"}, + // Working example with JSON decoder. + {"file://" + jsonPath + "?decoder=jsonmap", false, false, &map[string]any{"Foo": "Bar"}}, + // Working example with decrypt (default) decoder. + {"file://" + secretsPath + "?decoder=decrypt", false, false, []byte(`{"Foo":"Bar"}`)}, + // Working example with decrypt+bytes decoder. + {"file://" + secretsPath + "?decoder=decrypt+bytes", false, false, []byte(`{"Foo":"Bar"}`)}, + // Working example with decrypt+json decoder. + {"file://" + secretsPath + "?decoder=decrypt+jsonmap", false, false, &map[string]any{"Foo": "Bar"}}, + // Working example with escaped decrypt+json decoder + {"file://" + secretsPath + "?decoder=" + url.QueryEscape("decrypt+jsonmap"), false, false, &map[string]any{"Foo": "Bar"}}, + // Setting wait. + {"file://" + txtPath + "?decoder=string&wait=1m", false, false, "hello world!"}, + // Invalid wait. + {"file://" + txtPath + "?decoder=string&wait=xx", true, false, nil}, + } + + for _, test := range tests { + t.Run(test.URL, func(t *testing.T) { + v, err := runtimevar.OpenVariable(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if err != nil { + return + } + defer v.Close() + snapshot, err := v.Watch(ctx) + if (err != nil) != test.WantWatchErr { + t.Errorf("%s: got Watch error %v, want error %v", test.URL, err, test.WantWatchErr) + } + if err != nil { + return + } + if !cmp.Equal(snapshot.Value, test.Want) { + t.Errorf("%s: got snapshot value\n%v\n want\n%v", test.URL, snapshot.Value, test.Want) + } + }) + } +} + +func setupTestSecrets(ctx context.Context, dir, secretsPath string) (func(), error) { + const keeperEnv = "RUNTIMEVAR_KEEPER_URL" + const keeperURL = "base64key://smGbjm71Nxd1Ig5FS0wj9SlbzAIrnolCz9bQQ6uAhl4=" + oldURL := os.Getenv(keeperEnv) + os.Setenv(keeperEnv, keeperURL) + cleanup := func() { os.Setenv(keeperEnv, oldURL) } + + k, err := secrets.OpenKeeper(ctx, keeperURL) + if err != nil { + return cleanup, err + } + sc, err := k.Encrypt(ctx, []byte(`{"Foo":"Bar"}`)) + if err != nil { + return cleanup, err + } + if err := os.WriteFile(secretsPath, sc, 0o666); err != nil { + return cleanup, err + } + return cleanup, nil +} diff --git a/go-cloud/runtimevar/gcpruntimeconfig/example_test.go b/go-cloud/runtimevar/gcpruntimeconfig/example_test.go new file mode 100644 index 000000000..57df33c02 --- /dev/null +++ b/go-cloud/runtimevar/gcpruntimeconfig/example_test.go @@ -0,0 +1,81 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcpruntimeconfig_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/gcpruntimeconfig" +) + +func ExampleOpenVariable() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Your GCP credentials. + // See https://cloud.google.com/docs/authentication/production + // for more info on alternatives. + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + log.Fatal(err) + } + + // Connect to the Runtime Configurator service. + client, cleanup, err := gcpruntimeconfig.Dial(ctx, creds.TokenSource) + if err != nil { + log.Fatal(err) + } + defer cleanup() + + // You can use the VariableKey helper to construct a Variable key from + // your project ID, config ID, and the variable name; alternatively, + // you can construct the full string yourself (e.g., + // "projects/gcp-project-id/configs/config-id/variables/variable-name"). + // See https://cloud.google.com/deployment-manager/runtime-configurator/ + // for more details. + // + // For this example, the GCP Cloud Runtime Configurator variable being + // referenced should have a JSON string that decodes into MyConfig. + variableKey := gcpruntimeconfig.VariableKey("gcp-project-id", "config-id", "variable-name") + + // Construct a *runtimevar.Variable that watches the variable. + v, err := gcpruntimeconfig.OpenVariable(client, variableKey, runtimevar.StringDecoder, nil) + if err != nil { + log.Fatal(err) + } + defer v.Close() +} + +func Example_openVariableFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/runtimevar/gcpruntimeconfig" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // runtimevar.OpenVariable creates a *runtimevar.Variable from a URL. + // The URL Host+Path are used as the GCP Runtime Configurator Variable key; + // see https://cloud.google.com/deployment-manager/runtime-configurator/ + // for more details. + + v, err := runtimevar.OpenVariable(ctx, "gcpruntimeconfig://projects/myproject/configs/myconfigid/variables/myvar?decoder=string") + if err != nil { + log.Fatal(err) + } + defer v.Close() +} diff --git a/go-cloud/runtimevar/gcpruntimeconfig/gcpruntimeconfig.go b/go-cloud/runtimevar/gcpruntimeconfig/gcpruntimeconfig.go new file mode 100644 index 000000000..6da900788 --- /dev/null +++ b/go-cloud/runtimevar/gcpruntimeconfig/gcpruntimeconfig.go @@ -0,0 +1,362 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcpruntimeconfig provides a runtimevar implementation with +// variables read from GCP Cloud Runtime Configurator +// (https://cloud.google.com/deployment-manager/runtime-configurator). +// Use OpenVariable to construct a *runtimevar.Variable. +// +// # URLs +// +// For runtimevar.OpenVariable, gcpruntimeconfig registers for the scheme +// "gcpruntimeconfig". +// The default URL opener will creating a connection using use default +// credentials from the environment, as described in +// https://cloud.google.com/docs/authentication/production. +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// gcpruntimeconfig exposes the following types for As: +// - Snapshot: *pb.Variable +// - Error: *status.Status +package gcpruntimeconfig // import "gocloud.dev/runtimevar/gcpruntimeconfig" + +import ( + "bytes" + "context" + "fmt" + "net/url" + "path" + "regexp" + "sync" + "time" + + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/useragent" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + pb "google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/oauth" + "google.golang.org/grpc/status" +) + +const ( + // endpoint is the address of the GCP Runtime Configurator API. + endPoint = "runtimeconfig.googleapis.com:443" +) + +// Dial opens a gRPC connection to the Runtime Configurator API using +// credentials from ts. It is provided as an optional helper with useful +// defaults. +// +// The second return value is a function that should be called to clean up +// the connection opened by Dial. +func Dial(ctx context.Context, ts gcp.TokenSource) (pb.RuntimeConfigManagerClient, func(), error) { + conn, err := grpc.DialContext(ctx, endPoint, + grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), + grpc.WithPerRPCCredentials(oauth.TokenSource{TokenSource: ts}), + useragent.GRPCDialOption("runtimevar"), + ) + if err != nil { + return nil, nil, err + } + return pb.NewRuntimeConfigManagerClient(conn), func() { conn.Close() }, nil +} + +func init() { + runtimevar.DefaultURLMux().RegisterVariable(Scheme, new(lazyCredsOpener)) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + Dial, + wire.Struct(new(URLOpener), "Client"), +) + +// lazyCredsOpener obtains Application Default Credentials on the first call +// to OpenVariableURL. +type lazyCredsOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazyCredsOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + o.init.Do(func() { + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + o.err = err + return + } + client, _, err := Dial(ctx, creds.TokenSource) + if err != nil { + o.err = err + return + } + o.opener = &URLOpener{Client: client} + }) + if o.err != nil { + return nil, fmt.Errorf("open variable %v: %v", u, o.err) + } + return o.opener.OpenVariableURL(ctx, u) +} + +// Scheme is the URL scheme gcpruntimeconfig registers its URLOpener under on runtimevar.DefaultMux. +const Scheme = "gcpruntimeconfig" + +// URLOpener opens gcpruntimeconfig URLs like "gcpruntimeconfig://projects/[project_id]/configs/[CONFIG_ID]/variables/[VARIABLE_NAME]". +// +// The URL Host+Path are used as the GCP Runtime Configurator Variable key; +// see https://cloud.google.com/deployment-manager/runtime-configurator/ +// for more details. +// +// The following query parameters are supported: +// +// - decoder: The decoder to use. Defaults to URLOpener.Decoder, or +// runtimevar.BytesDecoder if URLOpener.Decoder is nil. +// See runtimevar.DecoderByName for supported values. +// - wait: The poll interval, in time.ParseDuration formats. +// Defaults to 30s. +type URLOpener struct { + // Client must be set to a non-nil client authenticated with + // Cloud RuntimeConfigurator scope or equivalent. + Client pb.RuntimeConfigManagerClient + + // Decoder specifies the decoder to use if one is not specified in the URL. + // Defaults to runtimevar.BytesDecoder. + Decoder *runtimevar.Decoder + + // Options specifies the options to pass to New. + Options Options +} + +// OpenVariableURL opens a gcpruntimeconfig Variable for u. +func (o *URLOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + q := u.Query() + + decoderName := q.Get("decoder") + q.Del("decoder") + decoder, err := runtimevar.DecoderByName(ctx, decoderName, o.Decoder) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid decoder: %v", u, err) + } + opts := o.Options + if s := q.Get("wait"); s != "" { + q.Del("wait") + d, err := time.ParseDuration(s) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid wait %q: %v", u, s, err) + } + opts.WaitDuration = d + } + + for param := range q { + return nil, fmt.Errorf("open variable %v: invalid query parameter %q", u, param) + } + return OpenVariable(o.Client, path.Join(u.Host, u.Path), decoder, &opts) +} + +// Options sets options. +type Options struct { + // WaitDuration controls the rate at which Parameter Store is polled. + // Defaults to 30 seconds. + WaitDuration time.Duration +} + +// OpenVariable constructs a *runtimevar.Variable backed by variableKey in +// GCP Cloud Runtime Configurator. +// +// A variableKey will look like: +// +// projects/[project_id]/configs/[CONFIG_ID]/variables/[VARIABLE_NAME] +// +// You can use the full string (e.g., copied from the GCP Console), or +// construct one from its parts using VariableKey. +// +// See https://cloud.google.com/deployment-manager/runtime-configurator/ for +// more details. +// +// Runtime Configurator returns raw bytes; provide a decoder to decode the raw bytes +// into the appropriate type for runtimevar.Snapshot.Value. +// See the runtimevar package documentation for examples of decoders. +func OpenVariable(client pb.RuntimeConfigManagerClient, variableKey string, decoder *runtimevar.Decoder, opts *Options) (*runtimevar.Variable, error) { + w, err := newWatcher(client, variableKey, decoder, opts) + if err != nil { + return nil, err + } + return runtimevar.New(w), nil +} + +var variableKeyRE = regexp.MustCompile("^projects/.+/configs/.+/variables/.+$") + +func newWatcher(client pb.RuntimeConfigManagerClient, variableKey string, decoder *runtimevar.Decoder, opts *Options) (driver.Watcher, error) { + if opts == nil { + opts = &Options{} + } + if !variableKeyRE.MatchString(variableKey) { + return nil, fmt.Errorf("invalid variableKey %q; must match %v", variableKey, variableKeyRE) + } + return &watcher{ + client: client, + wait: driver.WaitDuration(opts.WaitDuration), + name: variableKey, + decoder: decoder, + }, nil +} + +// VariableKey constructs a GCP Runtime Configurator variable key from +// component parts. See +// https://cloud.google.com/deployment-manager/runtime-configurator/ +// for more details. +func VariableKey(projectID gcp.ProjectID, configID, variableName string) string { + return fmt.Sprintf("projects/%s/configs/%s/variables/%s", projectID, configID, variableName) +} + +// state implements driver.State. +type state struct { + val any + raw *pb.Variable + updateTime time.Time + rawBytes []byte + err error +} + +// Value implements driver.State.Value. +func (s *state) Value() (any, error) { + return s.val, s.err +} + +// UpdateTime implements driver.State.UpdateTime. +func (s *state) UpdateTime() time.Time { + return s.updateTime +} + +// As implements driver.State.As. +func (s *state) As(i any) bool { + if s.raw == nil { + return false + } + p, ok := i.(**pb.Variable) + if !ok { + return false + } + *p = s.raw + return true +} + +// errorState returns a new State with err, unless prevS also represents +// the same error, in which case it returns nil. +func errorState(err error, prevS driver.State) driver.State { + s := &state{err: err} + if prevS == nil { + return s + } + prev := prevS.(*state) + if prev.err == nil { + // New error. + return s + } + if equivalentError(err, prev.err) { + // Same error, return nil to indicate no change. + return nil + } + return s +} + +// equivalentError returns true iff err1 and err2 represent an equivalent error; +// i.e., we don't want to return it to the user as a different error. +func equivalentError(err1, err2 error) bool { + if err1 == err2 || err1.Error() == err2.Error() { + return true + } + code1, code2 := status.Code(err1), status.Code(err2) + return code1 != codes.OK && code1 != codes.Unknown && code1 == code2 +} + +// watcher implements driver.Watcher for configurations provided by the Runtime Configurator +// service. +type watcher struct { + client pb.RuntimeConfigManagerClient + wait time.Duration + name string + decoder *runtimevar.Decoder +} + +// WatchVariable implements driver.WatchVariable. +func (w *watcher) WatchVariable(ctx context.Context, prev driver.State) (driver.State, time.Duration) { + // Get the variable from the backend. + vpb, err := w.client.GetVariable(ctx, &pb.GetVariableRequest{Name: w.name}) + if err != nil { + return errorState(err, prev), w.wait + } + updateTime, err := parseUpdateTime(vpb) + if err != nil { + return errorState(err, prev), w.wait + } + // See if it's the same raw bytes as before. + b := bytesFromProto(vpb) + if prev != nil && bytes.Equal(b, prev.(*state).rawBytes) { + // No change! + return nil, w.wait + } + + // Decode the value. + val, err := w.decoder.Decode(ctx, b) + if err != nil { + return errorState(err, prev), w.wait + } + return &state{val: val, raw: vpb, updateTime: updateTime, rawBytes: b}, w.wait +} + +// Close implements driver.Close. +func (w *watcher) Close() error { + return nil +} + +// ErrorAs implements driver.ErrorAs. +func (w *watcher) ErrorAs(err error, i any) bool { + // FromError converts err to a *status.Status. + s, _ := status.FromError(err) + if p, ok := i.(**status.Status); ok { + *p = s + return true + } + return false +} + +// ErrorCode implements driver.ErrorCode. +func (*watcher) ErrorCode(err error) gcerrors.ErrorCode { + return gcerr.GRPCCode(err) +} + +func bytesFromProto(vpb *pb.Variable) []byte { + // Proto may contain either bytes or text. If it contains text content, convert that to []byte. + if _, isBytes := vpb.GetContents().(*pb.Variable_Value); isBytes { + return vpb.GetValue() + } + return []byte(vpb.GetText()) +} + +func parseUpdateTime(vpb *pb.Variable) (time.Time, error) { + return vpb.GetUpdateTime().AsTime(), nil +} diff --git a/go-cloud/runtimevar/gcpruntimeconfig/gcpruntimeconfig_test.go b/go-cloud/runtimevar/gcpruntimeconfig/gcpruntimeconfig_test.go new file mode 100644 index 000000000..e2e4c9f39 --- /dev/null +++ b/go-cloud/runtimevar/gcpruntimeconfig/gcpruntimeconfig_test.go @@ -0,0 +1,236 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcpruntimeconfig + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/drivertest" + pb "google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// This constant records the project used for the last --record. +// If you want to use --record mode, +// 1. Update this constant to your GCP project ID. +// 2. Ensure that the "Runtime Configuration API" is enabled for your project. +// TODO(issue #300): Use Terraform to get this. +const projectID = "go-cloud-test-216917" + +const ( + // configID is the runtimeconfig high-level config that variables sit under. + configID = "go_cloud_runtimeconfigurator_test" +) + +func configPath() string { + return fmt.Sprintf("projects/%s/configs/%s", projectID, configID) +} + +func variableKey(variableName string) string { + return VariableKey(projectID, configID, variableName) +} + +type harness struct { + client pb.RuntimeConfigManagerClient + closer func() +} + +func newHarness(t *testing.T) (drivertest.Harness, error) { + t.Helper() + + ctx := context.Background() + conn, done := setup.NewGCPgRPCConn(ctx, t, endPoint, "runtimevar") + client := pb.NewRuntimeConfigManagerClient(conn) + // Ignore errors if the config already exists. + _, _ = client.CreateConfig(ctx, &pb.CreateConfigRequest{ + Parent: "projects/" + projectID, + Config: &pb.RuntimeConfig{ + Name: configPath(), + Description: t.Name(), + }, + }) + return &harness{ + client: client, + closer: func() { + _, _ = client.DeleteConfig(ctx, &pb.DeleteConfigRequest{Name: configPath()}) + done() + }, + }, nil +} + +func (h *harness) MakeWatcher(ctx context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) { + return newWatcher(h.client, variableKey(name), decoder, nil) +} + +func (h *harness) CreateVariable(ctx context.Context, name string, val []byte) error { + _, err := h.client.CreateVariable(ctx, &pb.CreateVariableRequest{ + Parent: configPath(), + Variable: &pb.Variable{ + Name: variableKey(name), + Contents: &pb.Variable_Value{Value: val}, + }, + }) + return err +} + +func (h *harness) UpdateVariable(ctx context.Context, name string, val []byte) error { + _, err := h.client.UpdateVariable(ctx, &pb.UpdateVariableRequest{ + Name: variableKey(name), + Variable: &pb.Variable{ + Contents: &pb.Variable_Value{Value: val}, + }, + }) + return err +} + +func (h *harness) DeleteVariable(ctx context.Context, name string) error { + _, err := h.client.DeleteVariable(ctx, &pb.DeleteVariableRequest{Name: variableKey(name)}) + return err +} + +func (h *harness) Close() { + h.closer() +} + +func (h *harness) Mutable() bool { return true } + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct{} + +func (verifyAs) Name() string { + return "verify As" +} + +func (verifyAs) SnapshotCheck(s *runtimevar.Snapshot) error { + var v *pb.Variable + if !s.As(&v) { + return errors.New("Snapshot.As failed") + } + return nil +} + +func (verifyAs) ErrorCheck(v *runtimevar.Variable, err error) error { + var s *status.Status + if !v.ErrorAs(err, &s) { + return errors.New("runtimevar.ErrorAs failed") + } + return nil +} + +// Runtimeconfigurator-specific tests. + +func TestEquivalentError(t *testing.T) { + tests := []struct { + Err1, Err2 error + Want bool + }{ + {Err1: errors.New("not grpc"), Err2: errors.New("not grpc"), Want: true}, + {Err1: errors.New("not grpc"), Err2: errors.New("not grpc but different")}, + {Err1: errors.New("not grpc"), Err2: status.Errorf(codes.Internal, "fail")}, + {Err1: status.Errorf(codes.Internal, "fail"), Err2: status.Errorf(codes.InvalidArgument, "fail")}, + {Err1: status.Errorf(codes.Internal, "fail"), Err2: status.Errorf(codes.Internal, "fail"), Want: true}, + } + + for _, test := range tests { + got := equivalentError(test.Err1, test.Err2) + if got != test.Want { + t.Errorf("%v vs %v: got %v want %v", test.Err1, test.Err2, got, test.Want) + } + } +} + +func TestNoConnectionError(t *testing.T) { + ctx := context.Background() + creds, err := setup.FakeGCPCredentials(ctx) + if err != nil { + t.Fatal(err) + } + + // Connect to the Runtime Configurator service. + client, cleanup, err := Dial(ctx, creds.TokenSource) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + variableKey := VariableKey("gcp-project-id", "cfg-name", "cfg-variable-name") + v, err := OpenVariable(client, variableKey, nil, nil) + if err != nil { + t.Fatal(err) + } + defer v.Close() + _, err = v.Watch(context.Background()) + if err == nil { + t.Error("got nil want error") + } +} + +func TestOpenVariable(t *testing.T) { + cleanup := setup.FakeGCPDefaultCredentials(t) + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"gcpruntimeconfig://projects/myproject/configs/mycfg/variables/myvar", false}, + // OK, hierarchical key name. + {"gcpruntimeconfig://projects/myproject/configs/mycfg/variables/myvar1/myvar2", false}, + // OK, setting decoder. + {"gcpruntimeconfig://projects/myproject/configs/mycfg/variables/myvar?decoder=string", false}, + // Missing projects prefix. + {"gcpruntimeconfig://project/myproject/configs/mycfg/variables/myvar", true}, + // Missing project. + {"gcpruntimeconfig://projects//configs/mycfg/variables/myvar", true}, + // Missing configs. + {"gcpruntimeconfig://projects/myproject/mycfg/variables/myvar", true}, + // Missing configID. + {"gcpruntimeconfig://projects/myproject/configs//variables/myvar", true}, + // Missing variables. + {"gcpruntimeconfig://projects/myproject/configs/mycfg//myvar", true}, + // Missing variable name. + {"gcpruntimeconfig://projects/myproject/configs/mycfg/variables/", true}, + // Invalid decoder. + {"gcpruntimeconfig://myproject/mycfg/myvar?decoder=notadecoder", true}, + // Invalid param. + {"gcpruntimeconfig://myproject/mycfg/myvar?param=value", true}, + // OK, setting wait. + {"gcpruntimeconfig://projects/myproject/configs/mycfg/variables/myvar?wait=1m", false}, + // Invalid wait. + {"gcpruntimeconfig://projects/myproject/configs/mycfg/variables/myvar?wait=xx", true}, + } + + ctx := context.Background() + for _, test := range tests { + v, err := runtimevar.OpenVariable(ctx, test.URL) + if v != nil { + defer v.Close() + } + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + } +} diff --git a/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestAs/verify_As.replay b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestAs/verify_As.replay new file mode 100644 index 000000000..aee4ed9a9 Binary files /dev/null and b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestAs/verify_As.replay differ diff --git a/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..510dcfe4f Binary files /dev/null and b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay differ diff --git a/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestDelete.replay b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestDelete.replay new file mode 100644 index 000000000..a6e510c63 Binary files /dev/null and b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestDelete.replay differ diff --git a/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestInvalidJSON.replay b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestInvalidJSON.replay new file mode 100644 index 000000000..a81d34c2e Binary files /dev/null and b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestInvalidJSON.replay differ diff --git a/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestJSON.replay b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestJSON.replay new file mode 100644 index 000000000..0bf69b78e Binary files /dev/null and b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestJSON.replay differ diff --git a/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestNonExistentVariable.replay b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestNonExistentVariable.replay new file mode 100644 index 000000000..0ed665963 Binary files /dev/null and b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestNonExistentVariable.replay differ diff --git a/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestString.replay b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestString.replay new file mode 100644 index 000000000..89ead6693 Binary files /dev/null and b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestString.replay differ diff --git a/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestUpdate.replay b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestUpdate.replay new file mode 100644 index 000000000..6320ba410 Binary files /dev/null and b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestUpdate.replay differ diff --git a/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestUpdateWithErrors.replay b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestUpdateWithErrors.replay new file mode 100644 index 000000000..6204892dc Binary files /dev/null and b/go-cloud/runtimevar/gcpruntimeconfig/testdata/TestConformance/TestUpdateWithErrors.replay differ diff --git a/go-cloud/runtimevar/gcpsecretmanager/example_test.go b/go-cloud/runtimevar/gcpsecretmanager/example_test.go new file mode 100644 index 000000000..3dd681b7c --- /dev/null +++ b/go-cloud/runtimevar/gcpsecretmanager/example_test.go @@ -0,0 +1,83 @@ +// Copyright 2020 The Go Cloud Development Kit 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 +// +// https://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 gcpsecretmanager_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/gcpsecretmanager" +) + +func ExampleOpenVariable() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Your GCP credentials. + // See https://cloud.google.com/docs/authentication/production + // for more info on alternatives. + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + log.Fatal(err) + } + + // Connect to the GCP Secret Manager service. + client, cleanup, err := gcpsecretmanager.Dial(ctx, creds.TokenSource) + if err != nil { + log.Fatal(err) + } + defer cleanup() + + // You can use the SecretKey helper to construct a secret key from + // your project ID and the secret ID; alternatively, + // you can construct the full string yourself (e.g., + // "projects/gcp-project-id/secrets/secret-id"). + // gcpsecretmanager package will always use the latest secret value, + // so `/version/latest` postfix must NOT be added to the secret key. + // See https://cloud.google.com/secret-manager + // for more details. + // + // For this example, the GCP Secret Manager secret being + // referenced should have a JSON string that decodes into MyConfig. + variableKey := gcpsecretmanager.SecretKey("gcp-project-id", "secret-id") + + // Construct a *runtimevar.Variable that watches the variable. + v, err := gcpsecretmanager.OpenVariable(client, variableKey, runtimevar.StringDecoder, nil) + if err != nil { + log.Fatal(err) + } + defer v.Close() +} + +func Example_openVariableFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/runtimevar/gcpsecretmanager" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // runtimevar.OpenVariable creates a *runtimevar.Variable from a URL. + // The URL Host+Path are used as the GCP Secret Manager secret key; + // see https://cloud.google.com/secret-manager + // for more details. + + v, err := runtimevar.OpenVariable(ctx, "gcpsecretmanager://projects/myproject/secrets/mysecret?decoder=string") + if err != nil { + log.Fatal(err) + } + defer v.Close() +} diff --git a/go-cloud/runtimevar/gcpsecretmanager/gcpsecretmanager.go b/go-cloud/runtimevar/gcpsecretmanager/gcpsecretmanager.go new file mode 100644 index 000000000..8fce3a1f3 --- /dev/null +++ b/go-cloud/runtimevar/gcpsecretmanager/gcpsecretmanager.go @@ -0,0 +1,375 @@ +// Copyright 2020 The Go Cloud Development Kit 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 +// +// https://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 gcpsecretmanager provides a runtimevar implementation with +// secrets read from GCP Secret Manager +// (https://cloud.google.com/secret-manager). +// Use OpenVariable to construct a *runtimevar.Variable. +// +// # URLs +// +// For runtimevar.OpenVariable, gcpsecretmanager registers for the scheme +// "gcpsecretmanager". +// The default URL opener will creating a connection using use default +// credentials from the environment, as described in +// https://cloud.google.com/docs/authentication/production. +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// gcpsecretmanager exposes the following types for As: +// - Snapshot: *secretmanagerpb.AccessSecretVersionResponse +// - Error: *status.Status +package gcpsecretmanager // import "gocloud.dev/runtimevar/gcpsecretmanager" + +import ( + "bytes" + "context" + "errors" + "fmt" + "net/url" + "path" + "regexp" + "sync" + "time" + + secretmanager "cloud.google.com/go/secretmanager/apiv1" + "cloud.google.com/go/secretmanager/apiv1/secretmanagerpb" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "google.golang.org/api/option" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/oauth" + "google.golang.org/grpc/status" +) + +// Dial opens a gRPC connection to the Secret Manager API using +// credentials from ts. It is provided as an optional helper with useful +// defaults. +// +// The second return value is a function that should be called to clean up +// the connection opened by Dial. +func Dial(ctx context.Context, ts gcp.TokenSource) (*secretmanager.Client, func(), error) { + client, err := secretmanager.NewClient(ctx, + option.WithGRPCDialOption( + grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), + ), + option.WithTokenSource(oauth.TokenSource{TokenSource: ts}), + option.WithUserAgent("runtimevar"), + ) + if err != nil { + return nil, nil, err + } + + return client, func() { _ = client.Close() }, nil +} + +func init() { + runtimevar.DefaultURLMux().RegisterVariable(Scheme, new(lazyCredsOpener)) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + Dial, + wire.Struct(new(URLOpener), "Client"), +) + +// lazyCredsOpener obtains Application Default Credentials on the first call +// to OpenVariableURL. +type lazyCredsOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazyCredsOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + o.init.Do(func() { + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + o.err = err + return + } + client, _, err := Dial(ctx, creds.TokenSource) + if err != nil { + o.err = err + return + } + o.opener = &URLOpener{Client: client} + }) + if o.err != nil { + return nil, fmt.Errorf("open variable %v: %v", u, o.err) + } + return o.opener.OpenVariableURL(ctx, u) +} + +// Scheme is the URL scheme gcpsecretmanager registers its URLOpener under on runtimevar.DefaultMux. +const Scheme = "gcpsecretmanager" + +// URLOpener opens gcpsecretmanager URLs like "gcpsecretmanager://projects/[project_id]/secrets/[secret_id]". +// +// The URL Host+Path are used as the GCP Secret Manager secret key; +// see https://cloud.google.com/secret-manager +// for more details. +// +// The following query parameters are supported: +// +// - decoder: The decoder to use. Defaults to URLOpener.Decoder, or +// runtimevar.BytesDecoder if URLOpener.Decoder is nil. +// See runtimevar.DecoderByName for supported values. +// - wait: The poll interval, in time.ParseDuration formats. +// Defaults to 30s. +type URLOpener struct { + // Client must be set to a non-nil client authenticated with + // Secret Manager scope or equivalent. + Client *secretmanager.Client + + // Decoder specifies the decoder to use if one is not specified in the URL. + // Defaults to runtimevar.BytesDecoder. + Decoder *runtimevar.Decoder + + // Options specifies the options to pass to New. + Options Options +} + +// OpenVariableURL opens a gcpsecretmanager Secret. +func (o *URLOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + q := u.Query() + + decoderName := q.Get("decoder") + q.Del("decoder") + decoder, err := runtimevar.DecoderByName(ctx, decoderName, o.Decoder) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid decoder: %v", u, err) + } + opts := o.Options + if s := q.Get("wait"); s != "" { + q.Del("wait") + d, err := time.ParseDuration(s) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid wait %q: %v", u, s, err) + } + opts.WaitDuration = d + } + + for param := range q { + return nil, fmt.Errorf("open variable %v: invalid query parameter %q", u, param) + } + return OpenVariable(o.Client, path.Join(u.Host, u.Path), decoder, &opts) +} + +// Options sets options. +type Options struct { + // WaitDuration controls the rate at which Secret Manager is polled. + // Defaults to 30 seconds. + WaitDuration time.Duration +} + +// OpenVariable constructs a *runtimevar.Variable backed by secretKey in GCP Secret Manager. +// +// A secretKey will look like: +// +// projects/[project_id]/secrets/[secret_id] +// +// A project ID is a unique, user-assigned ID of the Project. +// It must be 6 to 30 lowercase letters, digits, or hyphens. +// It must start with a letter. Trailing hyphens are prohibited. +// +// A secret ID is a string with a maximum length of 255 characters and can +// contain uppercase and lowercase letters, numerals, and the hyphen (`-`) and +// underscore (`_`) characters. +// +// gcpsecretmanager package will always use the latest secret value, +// so `/version/latest` postfix must NOT be added to the secret key. +// +// You can use the full string (e.g., copied from the GCP Console), or +// construct one from its parts using SecretKey. +// +// See https://cloud.google.com/secret-manager for more details. +// +// Secret Manager returns raw bytes; provide a decoder to decode the raw bytes +// into the appropriate type for runtimevar.Snapshot.Value. +// See the runtimevar package documentation for examples of decoders. +func OpenVariable(client *secretmanager.Client, secretKey string, decoder *runtimevar.Decoder, opts *Options) (*runtimevar.Variable, error) { + w, err := newWatcher(client, secretKey, decoder, opts) + if err != nil { + return nil, err + } + return runtimevar.New(w), nil +} + +var secretKeyRE = regexp.MustCompile(`^projects/[a-z][a-z0-9_\-]{4,28}[a-z0-9_]/secrets/[a-zA-Z0-9_\-]{1,255}$`) + +const latestVersion = "/versions/latest" + +func newWatcher(client *secretmanager.Client, secretKey string, decoder *runtimevar.Decoder, opts *Options) (driver.Watcher, error) { + if opts == nil { + opts = &Options{} + } + + if !secretKeyRE.MatchString(secretKey) { + return nil, fmt.Errorf("invalid secretKey %q; must match %v", secretKey, secretKeyRE) + } + + return &watcher{ + client: client, + wait: driver.WaitDuration(opts.WaitDuration), + name: secretKey, + decoder: decoder, + }, nil +} + +// SecretKey constructs a GCP Secret Manager secret key from component parts. +// See https://cloud.google.com/secret-manager for more details. +func SecretKey(projectID gcp.ProjectID, secretID string) string { + return "projects/" + string(projectID) + "/secrets/" + secretID +} + +// state implements driver.State. +type state struct { + val any + raw *secretmanagerpb.AccessSecretVersionResponse + updateTime time.Time + rawBytes []byte + err error +} + +// Value implements driver.State.Value. +func (s *state) Value() (any, error) { + return s.val, s.err +} + +// UpdateTime implements driver.State.UpdateTime. +func (s *state) UpdateTime() time.Time { + return s.updateTime +} + +// As implements driver.State.As. +func (s *state) As(i any) bool { + if s.raw == nil { + return false + } + p, ok := i.(**secretmanagerpb.AccessSecretVersionResponse) + if !ok { + return false + } + *p = s.raw + return true +} + +// errorState returns a new State with err, unless prevS also represents +// the same error, in which case it returns nil. +func errorState(err error, prevS driver.State) driver.State { + s := &state{err: err} + if prevS == nil { + return s + } + prev := prevS.(*state) + if prev.err == nil { + // New error. + return s + } + if equivalentError(err, prev.err) { + // Same error, return nil to indicate no change. + return nil + } + return s +} + +// equivalentError returns true iff err1 and err2 represent an equivalent error; +// i.e., we don't want to return it to the user as a different error. +func equivalentError(err1, err2 error) bool { + if err1 == err2 || err1.Error() == err2.Error() { + return true + } + code1, code2 := status.Code(err1), status.Code(err2) + return code1 != codes.OK && code1 != codes.Unknown && code1 == code2 +} + +// watcher implements driver.Watcher for secrets provided by the Secret Manager service. +type watcher struct { + client *secretmanager.Client + wait time.Duration + name string + decoder *runtimevar.Decoder +} + +// WatchVariable implements driver.WatchVariable. +func (w *watcher) WatchVariable(ctx context.Context, prev driver.State) (driver.State, time.Duration) { + latest := w.name + latestVersion + + secret, err := w.client.AccessSecretVersion(ctx, &secretmanagerpb.AccessSecretVersionRequest{Name: latest}) + if err != nil { + return errorState(err, prev), w.wait + } + + if secret == nil || secret.Payload == nil || secret.Payload.Data == nil { + return errorState(errors.New("invalid secret payload"), prev), w.wait + } + + meta, err := w.client.GetSecretVersion(ctx, &secretmanagerpb.GetSecretVersionRequest{Name: latest}) + if err != nil { + return errorState(err, prev), w.wait + } + + createTime := meta.CreateTime.AsTime() + + // See if it's the same raw bytes as before. + if prev != nil { + prevState, ok := prev.(*state) + if ok && prevState != nil && bytes.Equal(secret.Payload.Data, prevState.rawBytes) { + // No change! + return nil, w.wait + } + } + + // Decode the value. + val, err := w.decoder.Decode(ctx, secret.Payload.Data) + if err != nil { + return errorState(err, prev), w.wait + } + + // A secret version is immutable. + // The latest secret value creation time is the last time the secret value has been changed. + // Hence set updateTime as createTime. + return &state{val: val, raw: secret, updateTime: createTime, rawBytes: secret.Payload.Data}, w.wait +} + +// Close implements driver.Close. +func (w *watcher) Close() error { + return nil +} + +// ErrorAs implements driver.ErrorAs. +func (w *watcher) ErrorAs(err error, i any) bool { + // FromError converts err to a *status.Status. + s, _ := status.FromError(err) + if p, ok := i.(**status.Status); ok { + *p = s + return true + } + return false +} + +// ErrorCode implements driver.ErrorCode. +func (*watcher) ErrorCode(err error) gcerrors.ErrorCode { + return gcerr.GRPCCode(err) +} diff --git a/go-cloud/runtimevar/gcpsecretmanager/gcpsecretmanager_test.go b/go-cloud/runtimevar/gcpsecretmanager/gcpsecretmanager_test.go new file mode 100644 index 000000000..b87a1e1f3 --- /dev/null +++ b/go-cloud/runtimevar/gcpsecretmanager/gcpsecretmanager_test.go @@ -0,0 +1,259 @@ +// Copyright 2020 The Go Cloud Development Kit 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 +// +// https://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 gcpsecretmanager + +import ( + "context" + "errors" + "fmt" + "testing" + + secretmanager "cloud.google.com/go/secretmanager/apiv1" + "cloud.google.com/go/secretmanager/apiv1/secretmanagerpb" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/drivertest" + "google.golang.org/api/option" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// This constant records the project used for the last --record. +// If you want to use --record mode, +// 1. Update this constant to your GCP project ID. +// 2. Ensure that the "Secret Manager API" is enabled for your project. +// TODO(issue #300): Use Terraform to get this. +const projectID = "go-cloud-test-216917" + +func secretKey(secretID string) string { + return "projects/" + projectID + "/secrets/" + secretID +} + +type harness struct { + client *secretmanager.Client + closer func() +} + +func newHarness(t *testing.T) (drivertest.Harness, error) { + t.Helper() + + ctx := context.Background() + conn, done := setup.NewGCPgRPCConn(ctx, t, "secretmanager.googleapis.com:443", "runtimevar") + + client, err := secretmanager.NewClient(ctx, option.WithGRPCConn(conn)) + if err != nil { + return nil, err + } + + return &harness{ + client: client, + closer: func() { + _ = client.Close() + done() + }, + }, nil +} + +func (h *harness) MakeWatcher(_ context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) { + return newWatcher(h.client, secretKey(name), decoder, nil) +} + +func (h *harness) CreateVariable(ctx context.Context, name string, val []byte) error { + _, err := h.client.CreateSecret(ctx, &secretmanagerpb.CreateSecretRequest{ + Parent: "projects/" + projectID, + SecretId: name, + Secret: &secretmanagerpb.Secret{ + Replication: &secretmanagerpb.Replication{ + Replication: &secretmanagerpb.Replication_Automatic_{ + Automatic: &secretmanagerpb.Replication_Automatic{}, + }, + }, + Labels: map[string]string{ + "project": "runtimevar", + }, + }, + }) + if err != nil { + return err + } + + // Add initial secret version. + _, err = h.client.AddSecretVersion(ctx, &secretmanagerpb.AddSecretVersionRequest{ + Parent: secretKey(name), + Payload: &secretmanagerpb.SecretPayload{Data: val}, + }) + + return err +} + +func (h *harness) UpdateVariable(ctx context.Context, name string, val []byte) error { + _, err := h.client.AddSecretVersion(ctx, &secretmanagerpb.AddSecretVersionRequest{ + Parent: secretKey(name), + Payload: &secretmanagerpb.SecretPayload{Data: val}, + }) + + return err +} + +func (h *harness) DeleteVariable(ctx context.Context, name string) error { + return h.client.DeleteSecret(ctx, &secretmanagerpb.DeleteSecretRequest{Name: secretKey(name)}) +} + +func (h *harness) Close() { + h.closer() +} + +func (h *harness) Mutable() bool { return true } + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct{} + +func (verifyAs) Name() string { + return "verify As" +} + +func (verifyAs) SnapshotCheck(s *runtimevar.Snapshot) error { + var v *secretmanagerpb.AccessSecretVersionResponse + if !s.As(&v) { + return errors.New("Snapshot.As failed") + } + return nil +} + +func (verifyAs) ErrorCheck(v *runtimevar.Variable, err error) error { + var s *status.Status + if !v.ErrorAs(err, &s) { + return errors.New("runtimevar.ErrorAs failed") + } + return nil +} + +// Secretmanager-specific tests. + +func TestEquivalentError(t *testing.T) { + tests := []struct { + Err1, Err2 error + Want bool + }{ + {Err1: errors.New("not grpc"), Err2: errors.New("not grpc"), Want: true}, + {Err1: errors.New("not grpc"), Err2: errors.New("not grpc but different")}, + {Err1: errors.New("not grpc"), Err2: status.Errorf(codes.Internal, "fail")}, + {Err1: status.Errorf(codes.Internal, "fail"), Err2: status.Errorf(codes.InvalidArgument, "fail")}, + {Err1: status.Errorf(codes.Internal, "fail"), Err2: status.Errorf(codes.Internal, "fail"), Want: true}, + } + + for _, test := range tests { + got := equivalentError(test.Err1, test.Err2) + if got != test.Want { + t.Errorf("%v vs %v: got %v want %v", test.Err1, test.Err2, got, test.Want) + } + } +} + +func TestNoConnectionError(t *testing.T) { + ctx := context.Background() + creds, err := setup.FakeGCPCredentials(ctx) + if err != nil { + t.Fatal(err) + } + + // Connect to the Secret Manager service. + client, cleanup, err := Dial(ctx, creds.TokenSource) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + key := SecretKey("gcp-project-id", "secret-name") + v, err := OpenVariable(client, key, nil, nil) + if err != nil { + t.Fatal(err) + } + defer func() { + if err := v.Close(); err != nil { + t.Error(err) + } + }() + + _, err = v.Watch(ctx) + if err == nil { + t.Error("got nil want error") + } +} + +func TestOpenVariable(t *testing.T) { + cleanup := setup.FakeGCPDefaultCredentials(t) + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"gcpsecretmanager://projects/myproject/secrets/mysecret", false}, + // OK, hierarchical key name. + {"gcpsecretmanager://projects/myproject/secrets/mysecret2", false}, + // OK, setting decoder. + {"gcpsecretmanager://projects/myproject/secrets/mysecret?decoder=string", false}, + // Missing projects prefix. + {"gcpsecretmanager://project/myproject/secrets/mysecret", true}, + // Missing project. + {"gcpsecretmanager://projects//secrets/mysecret", true}, + // Missing configs. + {"gcpsecretmanager://projects/myproject/mysecret", true}, + // Missing secretID with trailing slash. + {"gcpsecretmanager://projects/myproject/secrets/", true}, + // Missing secretID. + {"gcpsecretmanager://projects/myproject/secrets", true}, + // Invalid decoder. + {"gcpsecretmanager://projects/myproject/secrets/mysecret?decoder=notadecoder", true}, + // Invalid param. + {"gcpsecretmanager://projects/myproject/secrets/mysecret?param=value", true}, + // Setting wait. + {"gcpsecretmanager://projects/myproject/secrets/mysecret?wait=1m", false}, + // Invalid wait. + {"gcpsecretmanager://projects/myproject/secrets/mysecret?wait=xx", true}, + } + + ctx := context.Background() + for _, test := range tests { + if err := openVariable(ctx, test.URL); (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + } +} + +func openVariable(ctx context.Context, URL string) (err error) { + var v *runtimevar.Variable + v, err = runtimevar.OpenVariable(ctx, URL) + defer func() { + if v == nil { + return + } + + if closeErr := v.Close(); closeErr != nil { + if grpcErr, ok := closeErr.(*gcerr.Error); ok && grpcErr.Code != gcerr.Canceled { + err = fmt.Errorf("close failed: %v. prev error: %v", closeErr, err) + } + } + }() + + return err +} diff --git a/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestAs/verify_As.replay b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestAs/verify_As.replay new file mode 100644 index 000000000..e66e89c41 Binary files /dev/null and b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestAs/verify_As.replay differ diff --git a/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..766f32ccb Binary files /dev/null and b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay differ diff --git a/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestDelete.replay b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestDelete.replay new file mode 100644 index 000000000..8f0944ad0 Binary files /dev/null and b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestDelete.replay differ diff --git a/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestInvalidJSON.replay b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestInvalidJSON.replay new file mode 100644 index 000000000..43aa86f38 Binary files /dev/null and b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestInvalidJSON.replay differ diff --git a/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestJSON.replay b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestJSON.replay new file mode 100644 index 000000000..ccaa51797 Binary files /dev/null and b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestJSON.replay differ diff --git a/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestNonExistentVariable.replay b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestNonExistentVariable.replay new file mode 100644 index 000000000..896834c69 Binary files /dev/null and b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestNonExistentVariable.replay differ diff --git a/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestString.replay b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestString.replay new file mode 100644 index 000000000..c2b1795dc Binary files /dev/null and b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestString.replay differ diff --git a/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestUpdate.replay b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestUpdate.replay new file mode 100644 index 000000000..727d9e82a Binary files /dev/null and b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestUpdate.replay differ diff --git a/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestUpdateWithErrors.replay b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestUpdateWithErrors.replay new file mode 100644 index 000000000..48e97fbc2 Binary files /dev/null and b/go-cloud/runtimevar/gcpsecretmanager/testdata/TestConformance/TestUpdateWithErrors.replay differ diff --git a/go-cloud/runtimevar/httpvar/example_test.go b/go-cloud/runtimevar/httpvar/example_test.go new file mode 100644 index 000000000..31a1087d2 --- /dev/null +++ b/go-cloud/runtimevar/httpvar/example_test.go @@ -0,0 +1,55 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 httpvar_test + +import ( + "context" + "log" + "net/http" + + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/httpvar" +) + +func ExampleOpenVariable() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // Create an HTTP.Client + httpClient := http.DefaultClient + + // Construct a *runtimevar.Variable that watches the page. + v, err := httpvar.OpenVariable(httpClient, "http://example.com", runtimevar.StringDecoder, nil) + if err != nil { + log.Fatal(err) + } + defer v.Close() +} + +func Example_openVariableFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/runtimevar/httpvar" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // runtimevar.OpenVariable creates a *runtimevar.Variable from a URL. + // The default opener connects to an etcd server based on the environment + // variable ETCD_SERVER_URL. + + v, err := runtimevar.OpenVariable(ctx, "http://myserver.com/foo.txt?decoder=string") + if err != nil { + log.Fatal(err) + } + defer v.Close() +} diff --git a/go-cloud/runtimevar/httpvar/httpvar.go b/go-cloud/runtimevar/httpvar/httpvar.go new file mode 100644 index 000000000..6deb8666c --- /dev/null +++ b/go-cloud/runtimevar/httpvar/httpvar.go @@ -0,0 +1,311 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 httpvar provides a runtimevar implementation with variables +// backed by http endpoint. Use OpenVariable to construct a *runtimevar.Variable. +// +// # URLs +// +// For runtimevar.OpenVariable, httpvar registers for the schemes "http" and +// "https". The default URL opener will use http.DefaultClient. +// To use HTTP Basic Auth for the requests, set the environment variables +// "HTTPVAR_AUTH_USERNAME" and "HTTPVAR_AUTH_PASSWORD". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// httpvar exposes the following types for As: +// - Snapshot: *http.Response +// - Error: httpvar.RequestError, url.Error +package httpvar // import "gocloud.dev/runtimevar/httpvar" + +import ( + "bytes" + "context" + "fmt" + "io" + "net/http" + "net/url" + "os" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" +) + +func init() { + o := &URLOpener{Client: http.DefaultClient} + for _, scheme := range Schemes { + runtimevar.DefaultURLMux().RegisterVariable(scheme, o) + } +} + +// Schemes are the URL schemes httpvar registers its URLOpener under on runtimevar.DefaultMux. +var Schemes = []string{"http", "https"} + +// URLOpener opens HTTP URLs like "http://myserver.com/foo.txt". +// +// The full URL, including scheme, is used as the endpoint, except that the +// the following URL parameters are removed if present: +// - decoder: The decoder to use. Defaults to runtimevar.BytesDecoder. +// See runtimevar.DecoderByName for supported values. +// - wait: The poll interval, in time.ParseDuration formats. +// Defaults to 30s. +type URLOpener struct { + // The Client to use; required. + Client *http.Client + + // Decoder specifies the decoder to use if one is not specified in the URL. + // Defaults to runtimevar.BytesDecoder. + Decoder *runtimevar.Decoder + + // Options specifies the options to pass to OpenVariable. + Options Options +} + +// OpenVariableURL opens a httpvar Variable for u. +func (o *URLOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*runtimevar.Variable, error) { + // Clone u because we may strip some query parameters. + u2 := *u + q := u2.Query() + + decoderName := q.Get("decoder") + q.Del("decoder") + decoder, err := runtimevar.DecoderByName(ctx, decoderName, o.Decoder) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid decoder: %v", u, err) + } + opts := o.Options + if s := q.Get("wait"); s != "" { + q.Del("wait") + d, err := time.ParseDuration(s) + if err != nil { + return nil, fmt.Errorf("open variable %v: invalid wait %q: %v", u, s, err) + } + opts.WaitDuration = d + } + // See if we changed the query parameters. + if rawq := q.Encode(); rawq != u.Query().Encode() { + u2.RawQuery = rawq + } + return OpenVariable(o.Client, u2.String(), decoder, &opts) +} + +// Options sets options. +type Options struct { + // WaitDuration controls the rate at which the HTTP endpoint is called to check for changes. + // Defaults to 30 seconds. + WaitDuration time.Duration +} + +// RequestError represents an HTTP error that occurred during endpoint call. +type RequestError struct { + Response *http.Response +} + +func (e *RequestError) Error() string { + return fmt.Sprintf("httpvar: received status code %d", e.Response.StatusCode) +} + +func newRequestError(response *http.Response) *RequestError { + return &RequestError{Response: response} +} + +// OpenVariable constructs a *runtimevar.Variable that uses client +// to retrieve the variable contents from the URL urlStr. +func OpenVariable(client *http.Client, urlStr string, decoder *runtimevar.Decoder, opts *Options) (*runtimevar.Variable, error) { + endpointURL, err := url.Parse(urlStr) + if err != nil { + return nil, fmt.Errorf("httpvar: failed to parse url %q: %v", urlStr, err) + } + + return runtimevar.New(newWatcher(client, endpointURL, decoder, opts)), nil +} + +type state struct { + val any + raw *http.Response + rawBytes []byte + updateTime time.Time + err error +} + +// Value implements driver.State.Value. +func (s *state) Value() (any, error) { + return s.val, s.err +} + +// UpdateTime implements driver.State.UpdateTime. +func (s *state) UpdateTime() time.Time { + return s.updateTime +} + +// As implements driver.State.As. +func (s *state) As(i any) bool { + if s.raw == nil { + return false + } + p, ok := i.(**http.Response) + if !ok { + return false + } + *p = s.raw + return true +} + +// errorState returns a new State with err, unless prevS also represents +// the same error, in which case it returns nil. +func errorState(err error, prevS driver.State) driver.State { + s := &state{err: err} + if prevS == nil { + return s + } + prev := prevS.(*state) + if prev.err == nil { + // New error. + return s + } + if equivalentError(err, prev.err) { + // Same error, return nil to indicate no change. + return nil + } + return s +} + +// equivalentError returns true if err1 and err2 represent an equivalent error; +// i.e., we don't want to return it to the user as a different error. +func equivalentError(err1, err2 error) bool { + if err1 == err2 || err1.Error() == err2.Error() { + return true + } + var code1, code2 int + if e, ok := err1.(*RequestError); ok { + code1 = e.Response.StatusCode + } + if e, ok := err2.(*RequestError); ok { + code2 = e.Response.StatusCode + } + return code1 != 0 && code1 == code2 +} + +// watcher implements driver.Watcher for configurations provided by the Runtime Configurator +// service. +type watcher struct { + client *http.Client + endpoint *url.URL + decoder *runtimevar.Decoder + wait time.Duration +} + +// WatchVariable implements driver.WatchVariable. +func (w *watcher) WatchVariable(ctx context.Context, prev driver.State) (driver.State, time.Duration) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, w.endpoint.String(), nil) + if err != nil { + return errorState(err, prev), w.wait + } + authUsername := os.Getenv("HTTPVAR_AUTH_USERNAME") + authPassword := os.Getenv("HTTPVAR_AUTH_PASSWORD") + if authUsername != "" && authPassword != "" { + req.SetBasicAuth(authUsername, authPassword) + } + resp, err := w.client.Do(req) + if err != nil { + return errorState(err, prev), w.wait + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + err := newRequestError(resp) + return errorState(err, prev), w.wait + } + + respBodyBytes, err := io.ReadAll(resp.Body) + if err != nil { + return errorState(err, prev), w.wait + } + + // When endpoint returns the same response again, we return nil as state to not trigger variable update. + if prev != nil && bytes.Equal(respBodyBytes, prev.(*state).rawBytes) { + return nil, w.wait + } + + val, err := w.decoder.Decode(ctx, respBodyBytes) + if err != nil { + return errorState(err, prev), w.wait + } + + return &state{ + val: val, + raw: resp, + rawBytes: respBodyBytes, + updateTime: time.Now(), + }, w.wait +} + +// Close implements driver.Close. +func (w *watcher) Close() error { + return nil +} + +// ErrorAs implements driver.ErrorAs. +func (w *watcher) ErrorAs(err error, i any) bool { + switch v := err.(type) { + case *url.Error: + if p, ok := i.(*url.Error); ok { + *p = *v + return true + } + case *RequestError: + if p, ok := i.(*RequestError); ok { + *p = *v + return true + } + } + return false +} + +// ErrorCode implements driver.ErrorCode. +func (*watcher) ErrorCode(err error) gcerrors.ErrorCode { + if requestErr, ok := err.(*RequestError); ok { + switch requestErr.Response.StatusCode { + case http.StatusBadRequest: + return gcerr.InvalidArgument + case http.StatusNotFound: + return gcerr.NotFound + case http.StatusUnauthorized: + return gcerr.PermissionDenied + case http.StatusGatewayTimeout, http.StatusRequestTimeout: + return gcerr.DeadlineExceeded + case http.StatusInternalServerError, http.StatusServiceUnavailable, http.StatusBadGateway: + return gcerr.Internal + } + } + return gcerr.Unknown +} + +func newWatcher(client *http.Client, endpoint *url.URL, decoder *runtimevar.Decoder, opts *Options) driver.Watcher { + if opts == nil { + opts = &Options{} + } + return &watcher{ + client: client, + endpoint: endpoint, + decoder: decoder, + wait: driver.WaitDuration(opts.WaitDuration), + } +} diff --git a/go-cloud/runtimevar/httpvar/httpvar_test.go b/go-cloud/runtimevar/httpvar/httpvar_test.go new file mode 100644 index 000000000..99c6177bc --- /dev/null +++ b/go-cloud/runtimevar/httpvar/httpvar_test.go @@ -0,0 +1,387 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 httpvar + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "strconv" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/drivertest" +) + +type harness struct { + mockServer *mockServer +} + +func (h *harness) MakeWatcher(ctx context.Context, name string, decoder *runtimevar.Decoder) (driver.Watcher, error) { + endpointURL, err := url.Parse(h.mockServer.baseURL + "/" + name) + if err != nil { + return nil, err + } + return newWatcher(http.DefaultClient, endpointURL, decoder, nil), nil +} + +func (h *harness) CreateVariable(ctx context.Context, name string, val []byte) error { + h.mockServer.SetResponse(name, string(val)) + return nil +} + +func (h *harness) UpdateVariable(ctx context.Context, name string, val []byte) error { + h.mockServer.SetResponse(name, string(val)) + return nil +} + +func (h *harness) DeleteVariable(ctx context.Context, name string) error { + h.mockServer.DeleteResponse(name) + return nil +} + +func (h *harness) Close() { + h.mockServer.close() +} + +func (h *harness) Mutable() bool { + return true +} + +func newHarness(t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return &harness{ + mockServer: newMockServer(), + }, nil +} + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct{} + +func (verifyAs) Name() string { + return "verify As" +} + +func (verifyAs) SnapshotCheck(s *runtimevar.Snapshot) error { + var resp *http.Response + if !s.As(&resp) { + return errors.New("Snapshot.As failed") + } + + s2 := state{raw: nil} + if s2.As(nil) { + return errors.New("Snapshot.As was expected to fail") + } + return nil +} + +func (verifyAs) ErrorCheck(v *runtimevar.Variable, err error) error { + var e RequestError + if !v.ErrorAs(err, &e) { + return errors.New("ErrorAs expected to succeed with *httpvar.RequestError") + } + if !strings.Contains(e.Error(), strconv.Itoa(e.Response.StatusCode)) { + return errors.New("should contain url and status code") + } + + var e2 url.Error + urlError := &url.Error{URL: "http://example.com", Op: "GET", Err: errors.New("example error")} + if !v.ErrorAs(urlError, &e2) { + return errors.New("ErrorAs expected to succeed with *url.Error") + } + + var e3 RequestError + if v.ErrorAs(errors.New("example error"), &e3) { + return errors.New("ErrorAs was expected to fail") + } + return nil +} + +// httpvar-specific tests. + +func TestOpenVariable(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + {"http://example.com/config", false}, + {"%gh&%ij", true}, + } + + for _, test := range tests { + v, err := OpenVariable(http.DefaultClient, test.URL, runtimevar.StringDecoder, nil) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if v != nil { + v.Close() + } + } +} + +func TestEquivalentError(t *testing.T) { + notFoundErr := newRequestError(&http.Response{StatusCode: http.StatusNotFound}) + badGatewayErr := newRequestError(&http.Response{StatusCode: http.StatusBadGateway}) + tests := []struct { + Err1, Err2 error + Want bool + }{ + {Err1: errors.New("error one"), Err2: errors.New("error one"), Want: true}, + {Err1: errors.New("error one"), Err2: errors.New("error two"), Want: false}, + {Err1: errors.New("error one"), Err2: notFoundErr, Want: false}, + {Err1: notFoundErr, Err2: notFoundErr, Want: true}, + {Err1: notFoundErr, Err2: badGatewayErr, Want: false}, + } + + for _, test := range tests { + got := equivalentError(test.Err1, test.Err2) + if got != test.Want { + t.Errorf("%v vs %v: got %v want %v", test.Err1, test.Err2, got, test.Want) + } + } +} + +func TestWatcher_ErrorCode(t *testing.T) { + tests := []struct { + Err *RequestError + GCErr gcerr.ErrorCode + }{ + {Err: newRequestError(&http.Response{StatusCode: http.StatusBadRequest}), GCErr: gcerr.InvalidArgument}, + {Err: newRequestError(&http.Response{StatusCode: http.StatusNotFound}), GCErr: gcerr.NotFound}, + {Err: newRequestError(&http.Response{StatusCode: http.StatusUnauthorized}), GCErr: gcerr.PermissionDenied}, + {Err: newRequestError(&http.Response{StatusCode: http.StatusGatewayTimeout}), GCErr: gcerr.DeadlineExceeded}, + {Err: newRequestError(&http.Response{StatusCode: http.StatusRequestTimeout}), GCErr: gcerr.DeadlineExceeded}, + {Err: newRequestError(&http.Response{StatusCode: http.StatusInternalServerError}), GCErr: gcerr.Internal}, + {Err: newRequestError(&http.Response{StatusCode: http.StatusServiceUnavailable}), GCErr: gcerr.Internal}, + {Err: newRequestError(&http.Response{StatusCode: http.StatusBadGateway}), GCErr: gcerr.Internal}, + } + + endpointURL, err := url.Parse("http://example.com") + if err != nil { + t.Fatal(err) + } + + watcher := newWatcher(http.DefaultClient, endpointURL, runtimevar.StringDecoder, nil) + defer watcher.Close() + for _, test := range tests { + actualGCErr := watcher.ErrorCode(test.Err) + if test.GCErr != actualGCErr { + t.Errorf("expected gcerr.ErrorCode to be %d, got %d", test.GCErr, actualGCErr) + } + } +} + +func TestWatcher_WatchVariable(t *testing.T) { + t.Run("client returns an error", func(t *testing.T) { + endpointURL, err := url.Parse("http://example.com") + if err != nil { + t.Fatal(err) + } + + // In order to force httpClient.Get to return an error, we pass custom *http.Client + // with every short timeout, so that request will timed out and return an error. + httpClient := &http.Client{ + Timeout: time.Duration(1 * time.Millisecond), + } + watcher := newWatcher(httpClient, endpointURL, runtimevar.StringDecoder, nil) + defer watcher.Close() + state, _ := watcher.WatchVariable(context.Background(), &state{}) + + val, err := state.Value() + if err == nil { + t.Errorf("expected error got nil") + } + if val != nil { + t.Errorf("expected state value to be nil, got %v", val) + } + }) +} + +func TestWithAuth(t *testing.T) { + const ( + authUser = "test_user" + authPwd = "test_pwd" + value = "hello world" + ) + h, err := newHarness(t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + mockServer := h.(*harness).mockServer + testURL := mockServer.baseURL + "/string-var?decoder=string" + mockServer.authUser = authUser + mockServer.authPwd = authPwd + + ctx := context.Background() + if err := h.CreateVariable(ctx, "string-var", []byte(value)); err != nil { + t.Fatal(err) + } + + tests := []struct { + AuthUser string + AuthPwd string + WantErr bool + }{ + // No auth provided, fails. + {"", "", true}, + // Invalid user, fails. + {"wronguser", authPwd, true}, + // Invalid password, fails. + {authUser, "wrongpassword", true}, + // Auth good, works. + {authUser, authPwd, false}, + } + + for _, test := range tests { + name := fmt.Sprintf("user=%s,pwd=%s", test.AuthUser, test.AuthPwd) + t.Run(name, func(t *testing.T) { + t.Setenv("HTTPVAR_AUTH_USERNAME", test.AuthUser) + t.Setenv("HTTPVAR_AUTH_PASSWORD", test.AuthPwd) + + v, err := runtimevar.OpenVariable(ctx, testURL) + if err != nil { + t.Fatalf("failed OpenVariable: %v", err) + } + defer v.Close() + snapshot, err := v.Watch(ctx) + if (err != nil) != test.WantErr { + t.Errorf("got Watch error %v, want error %v", err, test.WantErr) + } + if err != nil { + return + } + if !cmp.Equal(snapshot.Value, value) { + t.Errorf("got snapshot value\n%v\n want\n%v", snapshot.Value, value) + } + }) + } +} + +func TestOpenVariableURL(t *testing.T) { + h, err := newHarness(t) + if err != nil { + t.Fatal(err) + } + defer h.Close() + baseURL := h.(*harness).mockServer.baseURL + + ctx := context.Background() + if err := h.CreateVariable(ctx, "string-var", []byte("hello world")); err != nil { + t.Fatal(err) + } + if err := h.CreateVariable(ctx, "json-var", []byte(`{"Foo": "Bar"}`)); err != nil { + t.Fatal(err) + } + + tests := []struct { + URL string + WantErr bool + WantWatchErr bool + Want any + }{ + // Nonexistentvar does not exist, so we get an error from Watch. + {baseURL + "/nonexistentvar", false, true, nil}, + // Invalid decoder arg. + {baseURL + "/string-var?decoder=notadecoder", true, false, nil}, + // Working example with string decoder. + {baseURL + "/string-var?decoder=string", false, false, "hello world"}, + // Working example with default decoder. + {baseURL + "/string-var", false, false, []byte("hello world")}, + // Working example with JSON decoder. + {baseURL + "/json-var?decoder=jsonmap", false, false, &map[string]any{"Foo": "Bar"}}, + // Setting wait. + {baseURL + "/string-var?decoder=string&wait=1m", false, false, "hello world"}, + // Invalid wait. + {baseURL + "/string-var?decoder=string&wait=xx", true, false, nil}, + } + + for _, test := range tests { + t.Run(test.URL, func(t *testing.T) { + v, err := runtimevar.OpenVariable(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if err != nil { + return + } + defer v.Close() + snapshot, err := v.Watch(ctx) + if (err != nil) != test.WantWatchErr { + t.Errorf("%s: got Watch error %v, want error %v", test.URL, err, test.WantWatchErr) + } + if err != nil { + return + } + if !cmp.Equal(snapshot.Value, test.Want) { + t.Errorf("%s: got snapshot value\n%v\n want\n%v", test.URL, snapshot.Value, test.Want) + } + }) + } +} + +type mockServer struct { + baseURL string + close func() + responses map[string]any + authUser string + authPwd string +} + +func (m *mockServer) SetResponse(name string, response any) { + m.responses[name] = response +} + +func (m *mockServer) DeleteResponse(name string) { + delete(m.responses, name) +} + +func newMockServer() *mockServer { + mock := &mockServer{responses: map[string]any{}} + + mux := http.NewServeMux() + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + if mock.authUser != "" { + user, pwd, ok := r.BasicAuth() + if !ok || user != mock.authUser || pwd != mock.authPwd { + w.WriteHeader(http.StatusUnauthorized) + return + } + } + resp := mock.responses[strings.TrimPrefix(r.URL.String(), "/")] + if resp == nil { + w.WriteHeader(http.StatusNotFound) + return + } + fmt.Fprint(w, resp) + }) + + server := httptest.NewServer(mux) + mock.baseURL = server.URL + mock.close = server.Close + return mock +} diff --git a/go-cloud/runtimevar/otel_test.go b/go-cloud/runtimevar/otel_test.go new file mode 100644 index 000000000..caddd54b5 --- /dev/null +++ b/go-cloud/runtimevar/otel_test.go @@ -0,0 +1,54 @@ +// Copyright 2019-2025 The Go Cloud Development Kit 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 +// +// https://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 runtimevar_test + +import ( + "context" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/oteltest" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/constantvar" + "testing" +) + +const ( + pkgName = "gocloud.dev/runtimevar" + driver = "gocloud.dev/runtimevar/constantvar" +) + +func TestOpenTelemetry(t *testing.T) { + ctx := context.Background() + te := oteltest.NewTestExporter(t, runtimevar.OpenTelemetryViews) + defer te.Shutdown(ctx) + + v := constantvar.New(1) + defer v.Close() + if _, err := v.Watch(ctx); err != nil { + t.Fatal(err) + } + cctx, cancel := context.WithCancel(ctx) + cancel() + _, _ = v.Watch(cctx) + + // Check metrics - during migration, we may need to look for different metric names. + metrics := te.GetMetrics(ctx) + + diff := oteltest.DiffMetrics(metrics, pkgName, driver, []oteltest.Call{ + {Method: "", Code: gcerrors.OK}, + }) + if diff != "" { + t.Error(diff) + } +} diff --git a/go-cloud/runtimevar/runtimevar.go b/go-cloud/runtimevar/runtimevar.go new file mode 100644 index 000000000..fbfe2a197 --- /dev/null +++ b/go-cloud/runtimevar/runtimevar.go @@ -0,0 +1,558 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 runtimevar provides an easy and portable way to watch runtime +// configuration variables. Subpackages contain driver implementations of +// runtimevar for supported services. +// +// See https://gocloud.dev/howto/runtimevar/ for a detailed how-to guide. +// +// # OpenTelemetry Integration +// +// OpenTelemetry supports tracing and metric collection for multiple languages and +// backend providers. See https://opentelemetry.io. +// +// This API collects an OpenTelemetry metric "gocloud.dev/runtimevar/value_changes", +// a count of the number of times all variables have changed values, by driver. +// +// To enable metric collection in your application, see the OpenTelemetry documentation at +// https://opentelemetry.io/docs/instrumentation/go/getting-started/ +package runtimevar // import "gocloud.dev/runtimevar" + +import ( + "bytes" + "context" + "encoding/gob" + "encoding/json" + "errors" + "fmt" + "net/url" + "os" + "reflect" + "strings" + "sync" + "time" + + "go.opentelemetry.io/otel/metric" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/openurl" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + + gcdkotel "github.com/DataDog/iceberg-go/go-cloud/internal/otel" +) + +// Snapshot contains a snapshot of a variable's value and metadata about it. +// It is intended to be read-only for users. +type Snapshot struct { + // Value contains the value of the variable. + // The type for Value depends on the decoder used when creating the Variable. + Value any + + // UpdateTime is the time when the last change was detected. + UpdateTime time.Time + + asFunc func(any) bool +} + +// As converts i to driver-specific types. +// See https://gocloud.dev/concepts/as/ for background information, the "As" +// examples in this package for examples, and the driver package +// documentation for the specific types supported for that driver. +func (s *Snapshot) As(i any) bool { + if s.asFunc == nil { + return false + } + return s.asFunc(i) +} + +const pkgName = "gocloud.dev/runtimevar" + +var ( + OpenTelemetryViews = gcdkotel.CounterView(pkgName, "/value_changes", + "Count of variable value changes by driver.") +) + +// Variable provides an easy and portable way to watch runtime configuration +// variables. To create a Variable, use constructors found in driver subpackages. +type Variable struct { + dw driver.Watcher + changeMeasure metric.Int64Counter + + // For cancelling the background goroutine, and noticing when it has exited. + backgroundCancel context.CancelFunc + backgroundDone chan struct{} + + // haveGoodCh is closed when we get the first good value for the variable. + haveGoodCh chan struct{} + // A reference to changed at the last time Watch was called. + // Not protected by mu because it's only referenced in Watch, which is not + // supposed to be called from multiple goroutines. + lastWatch <-chan struct{} + + mu sync.RWMutex + changed chan struct{} // closed when changing any of the other variables and replaced with a new channel + last Snapshot + lastErr error + lastGood Snapshot +} + +// New is intended for use by drivers only. Do not use in application code. +var New = newVar + +// newVar creates a new *Variable based on a specific driver implementation. +func newVar(w driver.Watcher) *Variable { + ctx, cancel := context.WithCancel(context.Background()) + changed := make(chan struct{}) + + providerName := gcdkotel.ProviderName(w) + + v := &Variable{ + dw: w, + changeMeasure: gcdkotel.DimensionlessMeasure(pkgName, providerName, "/value_changes", + "Count of variable value changes by driver"), + backgroundCancel: cancel, + backgroundDone: make(chan struct{}), + haveGoodCh: make(chan struct{}), + changed: changed, + lastWatch: changed, + lastErr: gcerr.Newf(gcerr.FailedPrecondition, nil, "no value yet"), + } + go v.background(ctx) + return v +} + +// ErrClosed is returned from Watch when the Variable has been Closed. +var ErrClosed = gcerr.Newf(gcerr.FailedPrecondition, nil, "Variable has been Closed") + +// Watch returns when there is a new Snapshot of the current value of the +// variable. +// +// The first call to Watch will block while reading the variable from the +// driver, and will return the resulting Snapshot or error. If an error is +// returned, the returned Snapshot is a zero value and should be ignored. +// Subsequent calls will block until the variable's value changes or a different +// error occurs. +// +// Watch returns an ErrClosed error if the Variable has been closed. +// +// Watch should not be called on the same variable from multiple goroutines +// concurrently. The typical use case is to call it in a single goroutine in a +// loop. +// +// If the variable does not exist, Watch returns an error for which +// gcerrors.Code will return gcerrors.NotFound. +// +// Alternatively, use Latest to retrieve the latest good value. +func (c *Variable) Watch(ctx context.Context) (Snapshot, error) { + // Block until there's a change since the last Watch call, signaled + // by lastWatch being closed by the background goroutine. + var ctxErr error + select { + case <-c.lastWatch: + case <-ctx.Done(): + ctxErr = ctx.Err() + } + c.mu.Lock() + defer c.mu.Unlock() + if errors.Is(c.lastErr, ErrClosed) { + return Snapshot{}, ErrClosed + } else if ctxErr != nil { + return Snapshot{}, ctxErr + } + c.lastWatch = c.changed + return c.last, c.lastErr +} + +func (c *Variable) background(ctx context.Context) { + var curState, prevState driver.State + var wait time.Duration + for { + select { + case <-ctx.Done(): + // We're shutting down; exit the goroutine. + close(c.backgroundDone) + return + case <-time.After(wait): + // Continue. + } + + curState, wait = c.dw.WatchVariable(ctx, prevState) + if curState == nil { + // No change. + continue + } + + // There's something new to return! + prevState = curState + c.changeMeasure.Add(ctx, 1) + // Error from RecordWithTags is not possible. + + // Updates under the lock. + c.mu.Lock() + if errors.Is(c.lastErr, ErrClosed) { + close(c.backgroundDone) + c.mu.Unlock() + return + } + if val, err := curState.Value(); err == nil { + // We got a good value! + c.last = Snapshot{ + Value: val, + UpdateTime: curState.UpdateTime(), + asFunc: curState.As, + } + c.lastErr = nil + c.lastGood = c.last + // Close c.haveGoodCh if it's not already closed. + select { + case <-c.haveGoodCh: + default: + close(c.haveGoodCh) + } + } else { + // We got an error value. + c.last = Snapshot{} + c.lastErr = wrapError(c.dw, err) + } + close(c.changed) + c.changed = make(chan struct{}) + c.mu.Unlock() + } +} + +func (c *Variable) haveGood() bool { + select { + case <-c.haveGoodCh: + return true + default: + return false + } +} + +// Latest is intended to be called per request, with the request context. +// It returns the latest good Snapshot of the variable value, blocking if no +// good value has ever been received. If ctx is Done, it returns the latest +// error indicating why no good value is available (not the ctx.Err()). +// You can pass an already-Done ctx to make Latest not block. +// +// Latest returns ErrClosed if the Variable has been closed. +func (c *Variable) Latest(ctx context.Context) (Snapshot, error) { + haveGood := c.haveGood() + if !haveGood { + select { + case <-c.haveGoodCh: + haveGood = true + case <-ctx.Done(): + // We don't return ctx.Err(). + } + } + c.mu.RLock() + defer c.mu.RUnlock() + if haveGood && !errors.Is(c.lastErr, ErrClosed) { + return c.lastGood, nil + } + return Snapshot{}, c.lastErr +} + +// CheckHealth returns an error unless Latest will return a good value +// without blocking. +func (c *Variable) CheckHealth() error { + haveGood := c.haveGood() + c.mu.RLock() + defer c.mu.RUnlock() + if haveGood && !errors.Is(c.lastErr, ErrClosed) { + return nil + } + return c.lastErr +} + +// Close closes the Variable. The Variable is unusable after Close returns. +func (c *Variable) Close() error { + // Record that we're closing. Subsequent calls to Watch/Latest will return ErrClosed. + c.mu.Lock() + if errors.Is(c.lastErr, ErrClosed) { + c.mu.Unlock() + return ErrClosed + } + c.last = Snapshot{} + c.lastErr = ErrClosed + + // Close any remaining channels to wake up any callers that are waiting on them. + close(c.changed) + // If it's the first good value, close haveGoodCh so that Latest doesn't block. + select { + case <-c.haveGoodCh: + default: + close(c.haveGoodCh) + } + c.mu.Unlock() + + // Shut down the background goroutine. + c.backgroundCancel() + <-c.backgroundDone + + // Close the driver. + err := c.dw.Close() + return wrapError(c.dw, err) +} + +func wrapError(w driver.Watcher, err error) error { + if err == nil { + return nil + } + if gcerr.DoNotWrap(err) { + return err + } + return gcerr.New(w.ErrorCode(err), err, 2, "runtimevar") +} + +// ErrorAs converts err to driver-specific types. +// ErrorAs panics if i is nil or not a pointer. +// ErrorAs returns false if err == nil. +// See https://gocloud.dev/concepts/as/ for background information. +func (c *Variable) ErrorAs(err error, i any) bool { + return gcerr.ErrorAs(err, i, c.dw.ErrorAs) +} + +// VariableURLOpener represents types than can open Variables based on a URL. +// The opener must not modify the URL argument. OpenVariableURL must be safe to +// call from multiple goroutines. +// +// This interface is generally implemented by types in driver packages. +type VariableURLOpener interface { + OpenVariableURL(ctx context.Context, u *url.URL) (*Variable, error) +} + +// URLMux is a URL opener multiplexer. It matches the scheme of the URLs +// against a set of registered schemes and calls the opener that matches the +// URL's scheme. +// See https://gocloud.dev/concepts/urls/ for more information. +// +// The zero value is a multiplexer with no registered schemes. +type URLMux struct { + schemes openurl.SchemeMap +} + +// VariableSchemes returns a sorted slice of the registered Variable schemes. +func (mux *URLMux) VariableSchemes() []string { return mux.schemes.Schemes() } + +// ValidVariableScheme returns true iff scheme has been registered for Variables. +func (mux *URLMux) ValidVariableScheme(scheme string) bool { return mux.schemes.ValidScheme(scheme) } + +// RegisterVariable registers the opener with the given scheme. If an opener +// already exists for the scheme, RegisterVariable panics. +func (mux *URLMux) RegisterVariable(scheme string, opener VariableURLOpener) { + mux.schemes.Register("runtimevar", "Variable", scheme, opener) +} + +// OpenVariable calls OpenVariableURL with the URL parsed from urlstr. +// OpenVariable is safe to call from multiple goroutines. +func (mux *URLMux) OpenVariable(ctx context.Context, urlstr string) (*Variable, error) { + opener, u, err := mux.schemes.FromString("Variable", urlstr) + if err != nil { + return nil, err + } + return opener.(VariableURLOpener).OpenVariableURL(ctx, u) +} + +// OpenVariableURL dispatches the URL to the opener that is registered with the +// URL's scheme. OpenVariableURL is safe to call from multiple goroutines. +func (mux *URLMux) OpenVariableURL(ctx context.Context, u *url.URL) (*Variable, error) { + opener, err := mux.schemes.FromURL("Variable", u) + if err != nil { + return nil, err + } + return opener.(VariableURLOpener).OpenVariableURL(ctx, u) +} + +var defaultURLMux = new(URLMux) + +// DefaultURLMux returns the URLMux used by OpenVariable. +// +// Driver packages can use this to register their VariableURLOpener on the mux. +func DefaultURLMux() *URLMux { + return defaultURLMux +} + +// OpenVariable opens the variable identified by the URL given. +// See the URLOpener documentation in driver subpackages for +// details on supported URL formats, and https://gocloud.dev/concepts/urls +// for more information. +func OpenVariable(ctx context.Context, urlstr string) (*Variable, error) { + return defaultURLMux.OpenVariable(ctx, urlstr) +} + +// Decode is a function type for unmarshaling/decoding a slice of bytes into +// an arbitrary type. Decode functions are used when creating a Decoder via +// NewDecoder. This package provides common Decode functions including +// GobDecode and JSONDecode. +type Decode func(context.Context, []byte, any) error + +// Decoder decodes a slice of bytes into a particular Go object. +// +// This package provides some common Decoders that you can use directly, +// including StringDecoder and BytesDecoder. You can also NewDecoder to +// construct other Decoders. +type Decoder struct { + typ reflect.Type + fn Decode +} + +// NewDecoder returns a Decoder that uses fn to decode a slice of bytes into +// an object of type obj. +// +// This package provides some common Decode functions, including JSONDecode +// and GobDecode, which can be passed to this function to create Decoders for +// JSON and gob values. +func NewDecoder(obj any, fn Decode) *Decoder { + return &Decoder{ + typ: reflect.TypeOf(obj), + fn: fn, + } +} + +// Decode decodes b into a new instance of the target type. +func (d *Decoder) Decode(ctx context.Context, b []byte) (any, error) { + nv := reflect.New(d.typ).Interface() + if err := d.fn(ctx, b, nv); err != nil { + return nil, err + } + ptr := reflect.ValueOf(nv) + return ptr.Elem().Interface(), nil +} + +var ( + // StringDecoder decodes into strings. + StringDecoder = NewDecoder("", StringDecode) + + // BytesDecoder copies the slice of bytes. + BytesDecoder = NewDecoder([]byte{}, BytesDecode) +) + +// JSONDecode can be passed to NewDecoder when decoding JSON (https://golang.org/pkg/encoding/json/). +func JSONDecode(ctx context.Context, data []byte, obj any) error { + return json.Unmarshal(data, obj) +} + +// GobDecode can be passed to NewDecoder when decoding gobs (https://golang.org/pkg/encoding/gob/). +func GobDecode(ctx context.Context, data []byte, obj any) error { + return gob.NewDecoder(bytes.NewBuffer(data)).Decode(obj) +} + +// StringDecode decodes raw bytes b into a string. +func StringDecode(ctx context.Context, b []byte, obj any) error { + v := obj.(*string) + *v = string(b) + return nil +} + +// BytesDecode copies the slice of bytes b into obj. +func BytesDecode(ctx context.Context, b []byte, obj any) error { + v := obj.(*[]byte) + *v = b[:] + return nil +} + +// DecryptDecode returns a decode function that can be passed to NewDecoder when +// decoding an encrypted message (https://godoc.org/gocloud.dev/secrets). +// +// post defaults to BytesDecode. An optional decoder can be passed in to do +// further decode operation based on the decrypted message. +func DecryptDecode(k *secrets.Keeper, post Decode) Decode { + return func(ctx context.Context, b []byte, obj any) error { + decrypted, err := k.Decrypt(ctx, b) + if err != nil { + return err + } + if post == nil { + return BytesDecode(ctx, decrypted, obj) + } + return post(ctx, decrypted, obj) + } +} + +// DecoderByName returns a *Decoder based on decoderName. +// +// It is intended to be used by URL openers in driver packages. +// +// Supported values include: +// - empty string: Returns the default from the URLOpener.Decoder, or +// BytesDecoder if URLOpener.Decoder is nil (which is true if you're +// using the default URLOpener). +// - "bytes": Returns a BytesDecoder; Snapshot.Value will be of type []byte. +// - "jsonmap": Returns a JSON decoder for a map[string]any; +// Snapshot.Value will be of type *map[string]any. +// - "string": Returns StringDecoder; Snapshot.Value will be of type string. +// +// It also supports using "decrypt+" (or "decrypt" for default +// decoder) to decrypt the data before decoding. It uses the secrets package to +// open a keeper by the URL string stored in a environment variable +// "RUNTIMEVAR_KEEPER_URL". See https://godoc.org/gocloud.dev/secrets#OpenKeeper +// for more details. +func DecoderByName(ctx context.Context, decoderName string, dflt *Decoder) (*Decoder, error) { + // Open a *secrets.Keeper if the decoderName contains "decrypt". + k, decoderName, err := decryptByName(ctx, decoderName) + if err != nil { + return nil, err + } + + if dflt == nil { + dflt = BytesDecoder + } + switch decoderName { + case "": + return maybeDecrypt(ctx, k, dflt), nil + case "bytes": + return maybeDecrypt(ctx, k, BytesDecoder), nil + case "jsonmap": + var m map[string]any + return maybeDecrypt(ctx, k, NewDecoder(&m, JSONDecode)), nil + case "string": + return maybeDecrypt(ctx, k, StringDecoder), nil + default: + return nil, fmt.Errorf("unsupported decoder %q", decoderName) + } +} + +// decryptByName returns a *secrets.Keeper for decryption when decoderName +// contains "decrypt". +func decryptByName(ctx context.Context, decoderName string) (*secrets.Keeper, string, error) { + if !strings.HasPrefix(decoderName, "decrypt") { + return nil, decoderName, nil + } + keeperURL := os.Getenv("RUNTIMEVAR_KEEPER_URL") + if keeperURL == "" { + return nil, "", errors.New("environment variable RUNTIMEVAR_KEEPER_URL needed to open a *secrets.Keeper for decryption") + } + k, err := secrets.OpenKeeper(ctx, keeperURL) + if err != nil { + return nil, "", err + } + decoderName = strings.TrimPrefix(decoderName, "decrypt") + if decoderName != "" { + decoderName = strings.TrimLeftFunc(decoderName, func(r rune) bool { + return r == ' ' || r == '+' + }) + } + // The parsed value is "decrypt ". + return k, decoderName, nil +} + +func maybeDecrypt(ctx context.Context, k *secrets.Keeper, dec *Decoder) *Decoder { + if k == nil { + return dec + } + return NewDecoder(reflect.New(dec.typ).Elem().Interface(), DecryptDecode(k, dec.fn)) +} diff --git a/go-cloud/runtimevar/runtimevar_test.go b/go-cloud/runtimevar/runtimevar_test.go new file mode 100644 index 000000000..2be734110 --- /dev/null +++ b/go-cloud/runtimevar/runtimevar_test.go @@ -0,0 +1,698 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 runtimevar contains tests that exercises the runtimevar APIs. It does not test +// driver implementations. +package runtimevar + +import ( + "bytes" + "context" + "encoding/gob" + "encoding/json" + "errors" + "fmt" + "net/url" + "reflect" + "sync" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/driver" + "github.com/DataDog/iceberg-go/go-cloud/secrets/localsecrets" +) + +// How long we wait on a call that is expected to block forever before cancelling it. +const blockingCheckDelay = 25 * time.Millisecond + +// state implements driver.State. +type state struct { + val string + updateTime time.Time + err error +} + +func (s *state) Value() (any, error) { return s.val, s.err } +func (s *state) UpdateTime() time.Time { return s.updateTime } +func (s *state) As(i any) bool { return false } + +// fakeWatcher is a fake implementation of driver.Watcher that returns a set *state. +type fakeWatcher struct { + driver.Watcher + + mu sync.Mutex + state *state + newval bool // true iff WatchVariable should return state +} + +func (w *fakeWatcher) Set(s *state) { + w.mu.Lock() + defer w.mu.Unlock() + w.state = s + w.newval = true +} + +func (w *fakeWatcher) WatchVariable(ctx context.Context, prev driver.State) (driver.State, time.Duration) { + if err := ctx.Err(); err != nil { + w.Set(&state{err: err}) + } + w.mu.Lock() + defer w.mu.Unlock() + if !w.newval { + return nil, 1 * time.Millisecond // to avoid spinning + } + w.newval = false + return w.state, 0 +} + +func (*fakeWatcher) Close() error { return nil } +func (*fakeWatcher) ErrorCode(error) gcerrors.ErrorCode { return gcerrors.Internal } + +func TestVariable_Watch(t *testing.T) { + fake := &fakeWatcher{} + v := New(fake) + + ctx := context.Background() + + // Watch should block when there's no value yet. + ctx2, cancel := context.WithTimeout(ctx, blockingCheckDelay) + defer cancel() + if _, err := v.Watch(ctx2); err == nil { + t.Errorf("Watch with no value yet should block: got nil err, want err") + } + if ctx2.Err() == nil { + t.Error("Watch with no value yet should block") + } + + // Setting an error value makes Watch return an error. + fake.Set(&state{err: errFake}) + if _, err := v.Watch(ctx); err == nil { + t.Fatal("Watch returned non-nil error, want error") + } + // But calling Watch again blocks. + ctx2, cancel = context.WithTimeout(ctx, blockingCheckDelay) + defer cancel() + if _, err := v.Watch(ctx2); err == nil { + t.Errorf("Watch called again with error value should block: got nil err, want err") + } + if ctx2.Err() == nil { + t.Error("Watch called again with error value should block") + } + + // Setting a different error makes Watch return again. + fake.Set(&state{err: errors.New("another fake error")}) + if _, err := v.Watch(ctx); err == nil { + t.Fatal("Watch returned non-nil error, want error") + } + + // Setting a value makes Watch return again. + fake.Set(&state{val: "hello"}) + if _, err := v.Watch(ctx); err != nil { + t.Fatalf("Watch returned error %v, want nil", err) + } + + // Make a few updates. Each of these will try to write to the nextWatchCh, + // but we should only keep the latest one. + fake.Set(&state{val: "hello1"}) + fake.Set(&state{val: "hello2"}) + fake.Set(&state{val: "hello3"}) + fake.Set(&state{val: "hello4"}) + fake.Set(&state{val: "hello5"}) + // Wait until we're sure the last one has been received. + for { + snap, err := v.Latest(ctx) + if err != nil { + t.Errorf("got unexpected error from Latest: %v", err) + } + if snap.Value == "hello5" { + break + } + } + + // Watch should get the last one, hello5. + if snap, err := v.Watch(ctx); err != nil { + t.Fatalf("Watch returned error %v, want nil", err) + } else if snap.Value != "hello5" { + t.Errorf("Watch got %v, want hello5", snap.Value) + } + + // And the next call should block. + ctx2, cancel = context.WithTimeout(ctx, blockingCheckDelay) + defer cancel() + if _, err := v.Watch(ctx2); err == nil { + t.Errorf("Watch after no change in good value should block: got nil err, want err") + } + if ctx2.Err() == nil { + t.Error("Watch after no change in good value should block") + } + + // Ensure a blocking Watch returns when a new value arrives. + // Wait blockingCheckDelay to give some time to be blocking in Watch. + // There's no guarantee it will get there, but if Watch doesn't handle + // cancelation properly, then the test will fail whenever it does get there, + // so at least we'll observe a flaky test. + time.AfterFunc(blockingCheckDelay, func() { fake.Set(&state{val: "hello6"}) }) + if snap, err := v.Watch(ctx); err != nil { + t.Errorf("Watch interrupted by new value returned %v, want nil", err) + } else if snap.Value != "hello6" { + t.Errorf("Watch got %v, want hello6", snap.Value) + } + + // Similarly, ensure a blocking Watch is interrupted by Close. + time.AfterFunc(blockingCheckDelay, func() { + if err := v.Close(); err != nil { + t.Error(err) + } + }) + if _, err := v.Watch(ctx); err != ErrClosed { + t.Errorf("Watch interrupted by Close returned %v, want ErrClosed", err) + } + + // Watch should now return ErrClosed. + if _, err := v.Watch(ctx); err != ErrClosed { + t.Errorf("Watch after Close returned %v, want ErrClosed", err) + } +} + +func TestVariable_Latest(t *testing.T) { + const content1, content2 = "foo", "bar" + const numGoroutines = 10 + ctx := context.Background() + + fake := &fakeWatcher{} + v := New(fake) + + // Not healthy at startup. + if v.CheckHealth() == nil { + t.Error("got nil from CheckHealth, want error") + } + + // Latest should block until the context is done, as there's no value. + ctx2, cancel := context.WithTimeout(ctx, blockingCheckDelay) + defer cancel() + if _, err := v.Latest(ctx2); err == nil { + t.Errorf("Latest with no value yet should block: got nil err, want err") + } + if ctx2.Err() == nil { + t.Error("Latest with no value yet should block") + } + // And we're not healthy. + if v.CheckHealth() == nil { + t.Error("got nil from CheckHealth, want error") + } + + // Call Latest concurrently. There's still no value. + var wg sync.WaitGroup + wg.Add(numGoroutines) + for i := 0; i < numGoroutines; i++ { + go func() { + ctx2, cancel := context.WithTimeout(ctx, blockingCheckDelay) + cancel() + if _, err := v.Latest(ctx2); err == nil { + t.Errorf("Latest with no value yet: got nil err, want err") + } + wg.Done() + }() + } + wg.Wait() + + // Set an error value. Latest should still block. + fake.Set(&state{err: errFake}) + ctx2, cancel = context.WithTimeout(ctx, blockingCheckDelay) + defer cancel() + if _, err := v.Latest(ctx2); err == nil { + t.Errorf("Latest with error value should block: got nil err, want err") + } + if ctx2.Err() == nil { + t.Error("Latest with error value should block") + } + // And we're still not healthy. + if v.CheckHealth() == nil { + t.Error("got nil from CheckHealth, want error") + } + + // Call Latest concurrently, only exiting each goroutine when they + // see the content1 value. + wg.Add(numGoroutines) + for i := 0; i < numGoroutines; i++ { + go func() { + for { + val, err := v.Latest(ctx) + if err != nil { + continue + } + if val.Value != content1 { + t.Errorf("got %v want %s", val, content1) + } + wg.Done() + return + } + }() + } + // Set a good value, after a small delay to give the goroutines a chance + // to get into Latest. + time.Sleep(blockingCheckDelay) + fake.Set(&state{val: content1}) + wg.Wait() + // And now we're healthy. + if err := v.CheckHealth(); err != nil { + t.Errorf("got %v from CheckHealth, want nil", err) + } + + // Set a different value. At some point after this, Latest should start + // returning a Snapshot with Value set to content2. + fake.Set(&state{val: content2}) + + // Call Latest concurrently, only exiting each goroutine when they + // see the content2 value. + wg.Add(numGoroutines) + for i := 0; i < numGoroutines; i++ { + go func() { + for { + val, err := v.Latest(ctx) + if err != nil { + // Errors are unexpected at this point. + t.Error(err) + } + if val.Value == content1 { + // Still seeing the old value. + continue + } + if val.Value != content2 { + t.Errorf("got %v want %s", val, content2) + } + wg.Done() + return + } + }() + } + wg.Wait() + + // Set an error value. Latest should still return content2. + fake.Set(&state{err: errFake}) + + // Call Latest concurrently. The test will be flaky if some of them + // start getting errors. + wg.Add(numGoroutines) + for i := 0; i < numGoroutines; i++ { + go func() { + val, err := v.Latest(ctx) + if err != nil { + // Errors are unexpected at this point. + t.Error(err) + } else if val.Value != content2 { + t.Errorf("got %v want %s", val.Value, content2) + } + wg.Done() + return + }() + } + wg.Wait() + + // Still healthy. + if err := v.CheckHealth(); err != nil { + t.Errorf("got %v from CheckHealth, want nil", err) + } + + // Close the variable. + if err := v.Close(); err != nil { + t.Error(err) + } + + // Latest should now return ErrClosed. + if _, err := v.Latest(ctx); err != ErrClosed { + t.Errorf("Latest after close returned %v, want ErrClosed", err) + } + // Unhealthy now. + if err := v.CheckHealth(); err != ErrClosed { + t.Errorf("got %v from CheckHealth, want ErrClosed", err) + } +} + +// Tests that Latest is interrupted by Close. +func TestVariable_LatestBlockedDuringClose(t *testing.T) { + fake := &fakeWatcher{} + v := New(fake) + + ctx := context.Background() + + // Wait blockingCheckDelay to give some time to be blocking in Latest. + // There's no guarantee it will get there, but if Latest doesn't handle + // cancelation properly, then the test will fail whenever it does get there, + // so at least we'll observe a flaky test. + time.AfterFunc(blockingCheckDelay, func() { + if err := v.Close(); err != nil { + t.Error(err) + } + }) + if _, err := v.Latest(ctx); err != ErrClosed { + t.Errorf("Latest interrupted by Close got %v, want ErrClosed", err) + } + + // Calling Close again should return ErrClosed. + if err := v.Close(); err != ErrClosed { + t.Errorf("calling Close 2x returned %v, want ErrClosed", err) + } +} + +var errFake = errors.New("fake") + +// erroringWatcher implements driver.Watcher. +// WatchVariable always returns a state with errFake, and Close +// always returns errFake. +type erroringWatcher struct { + driver.Watcher +} + +func (b *erroringWatcher) WatchVariable(ctx context.Context, prev driver.State) (driver.State, time.Duration) { + return &state{err: errFake}, 0 +} + +func (b *erroringWatcher) Close() error { + return errFake +} + +func (b *erroringWatcher) ErrorCode(err error) gcerrors.ErrorCode { + return gcerrors.Internal +} + +// TestErrorsAreWrapped tests that all errors returned from the driver are +// wrapped exactly once by the portable type. +func TestErrorsAreWrapped(t *testing.T) { + ctx := context.Background() + v := New(&erroringWatcher{}) + + // verifyWrap ensures that err is wrapped exactly once. + verifyWrap := func(description string, err error) { + if unwrapped, ok := err.(*gcerr.Error); !ok { + t.Errorf("%s: not wrapped: %v", description, err) + } else if du, ok := unwrapped.Unwrap().(*gcerr.Error); ok { + t.Errorf("%s: double wrapped: %v", description, du) + } + } + + _, err := v.Watch(ctx) + verifyWrap("Watch", err) + + err = v.Close() + verifyWrap("Close", err) +} + +var ( + testOpenOnce sync.Once + testOpenGot *url.URL +) + +func TestURLMux(t *testing.T) { + ctx := context.Background() + + mux := new(URLMux) + fake := &fakeOpener{} + mux.RegisterVariable("foo", fake) + mux.RegisterVariable("err", fake) + + if diff := cmp.Diff(mux.VariableSchemes(), []string{"err", "foo"}); diff != "" { + t.Errorf("Schemes: %s", diff) + } + if !mux.ValidVariableScheme("foo") || !mux.ValidVariableScheme("err") { + t.Errorf("ValidVariableScheme didn't return true for valid scheme") + } + if mux.ValidVariableScheme("foo2") || mux.ValidVariableScheme("http") { + t.Errorf("ValidVariableScheme didn't return false for invalid scheme") + } + + for _, tc := range []struct { + name string + url string + wantErr bool + }{ + { + name: "empty URL", + wantErr: true, + }, + { + name: "invalid URL", + url: ":foo", + wantErr: true, + }, + { + name: "invalid URL no scheme", + url: "foo", + wantErr: true, + }, + { + name: "unregistered scheme", + url: "bar://myvar", + wantErr: true, + }, + { + name: "func returns error", + url: "err://myvar", + wantErr: true, + }, + { + name: "no query options", + url: "foo://myvar", + }, + { + name: "empty query options", + url: "foo://myvar?", + }, + { + name: "query options", + url: "foo://myvar?aAa=bBb&cCc=dDd", + }, + { + name: "multiple query options", + url: "foo://myvar?x=a&x=b&x=c", + }, + { + name: "fancy var name", + url: "foo:///foo/bar/baz", + }, + { + name: "using api scheme prefix", + url: "runtimevar+foo:///foo/bar/baz", + }, + { + name: "using api+type scheme prefix", + url: "runtimevar+variable+foo:///foo/bar/baz", + }, + } { + t.Run(tc.name, func(t *testing.T) { + _, gotErr := mux.OpenVariable(ctx, tc.url) + if (gotErr != nil) != tc.wantErr { + t.Fatalf("got err %v, want error %v", gotErr, tc.wantErr) + } + if gotErr != nil { + return + } + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + // Repeat with OpenVariableURL. + parsed, err := url.Parse(tc.url) + if err != nil { + t.Fatal(err) + } + _, gotErr = mux.OpenVariableURL(ctx, parsed) + if gotErr != nil { + t.Fatalf("got err %v, want nil", gotErr) + } + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + }) + } +} + +type fakeOpener struct { + u *url.URL // last url passed to OpenVariableURL +} + +func (o *fakeOpener) OpenVariableURL(ctx context.Context, u *url.URL) (*Variable, error) { + if u.Scheme == "err" { + return nil, errors.New("fail") + } + o.u = u + return nil, nil +} + +func TestDecoder(t *testing.T) { + type Struct struct { + FieldA string + FieldB map[string]any + } + + num := 4321 + numptr := &num + str := "boring string" + strptr := &str + + inputs := []any{ + str, + strptr, + num, + numptr, + 100.1, + Struct{ + FieldA: "hello", + FieldB: map[string]any{ + "hello": "world", + }, + }, + &Struct{ + FieldA: "world", + }, + map[string]string{ + "slice": "pizza", + }, + &map[string]any{}, + []string{"hello", "world"}, + &[]int{1, 0, 1}, + [...]float64{3.1415}, + &[...]int64{4, 5, 6}, + } + + for _, tc := range []struct { + desc string + encodeFn func(any) ([]byte, error) + decodeFn Decode + }{ + { + desc: "JSON", + encodeFn: json.Marshal, + decodeFn: JSONDecode, + }, + { + desc: "Gob", + encodeFn: gobMarshal, + decodeFn: GobDecode, + }, + } { + for i, input := range inputs { + t.Run(fmt.Sprintf("%s_%d", tc.desc, i), func(t *testing.T) { + decoder := NewDecoder(input, tc.decodeFn) + b, err := tc.encodeFn(input) + if err != nil { + t.Fatalf("marshal error %v", err) + } + got, err := decoder.Decode(context.Background(), b) + if err != nil { + t.Fatalf("parse input\n%s\nerror: %v", string(b), err) + } + if reflect.TypeOf(got) != reflect.TypeOf(input) { + t.Errorf("type mismatch got %T, want %T", got, input) + } + if diff := cmp.Diff(got, input); diff != "" { + t.Errorf("value diff:\n%v", diff) + } + }) + } + } +} + +func gobMarshal(v any) ([]byte, error) { + var buf bytes.Buffer + if err := gob.NewEncoder(&buf).Encode(v); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func TestStringDecoder(t *testing.T) { + input := "hello world" + got, err := StringDecoder.Decode(context.Background(), []byte(input)) + if err != nil { + t.Fatalf("error: %v", err) + } + if input != got.(string) { + t.Errorf("output got %v, want %q", got, input) + } +} + +func TestBytesDecoder(t *testing.T) { + input := []byte("hello world") + got, err := BytesDecoder.Decode(context.Background(), input) + if err != nil { + t.Fatalf("error: %v", err) + } + if diff := cmp.Diff(got, input); diff != "" { + t.Errorf("output got %v, want %q", got, input) + } +} + +func TestDecryptDecoder(t *testing.T) { + ctx := context.Background() + secretKey, err := localsecrets.NewRandomKey() + if err != nil { + t.Fatal(err) + } + keeper := localsecrets.NewKeeper(secretKey) + + tests := []struct { + desc string + in any + encodeFn func(any) ([]byte, error) + postDecFn Decode + }{ + { + desc: "Bytes", + in: []byte("hello world"), + encodeFn: func(obj any) ([]byte, error) { return obj.([]byte), nil }, + }, + { + desc: "String", + in: "hello world", + encodeFn: func(obj any) ([]byte, error) { return []byte(obj.(string)), nil }, + postDecFn: StringDecode, + }, + { + desc: "JSON", + in: map[string]string{ + "slice": "pizza", + }, + encodeFn: json.Marshal, + postDecFn: JSONDecode, + }, + } + for _, tc := range tests { + t.Run(tc.desc, func(t *testing.T) { + decoder := NewDecoder(tc.in, DecryptDecode(keeper, tc.postDecFn)) + + b, err := tc.encodeFn(tc.in) + if err != nil { + t.Fatalf("encode error %v", err) + } + encrypted, err := keeper.Encrypt(ctx, b) + if err != nil { + t.Fatalf("encrypt error: %v", err) + } + + got, err := decoder.Decode(ctx, encrypted) + if err != nil { + t.Fatalf("parse input\n%s\nerror: %v", string(b), err) + } + if reflect.TypeOf(got) != reflect.TypeOf(tc.in) { + t.Errorf("type mismatch got %T, want %T", got, tc.in) + } + if diff := cmp.Diff(got, tc.in); diff != "" { + t.Errorf("value diff:\n%v", diff) + } + }) + } +} diff --git a/go-cloud/samples/appengine/.gcloudignore b/go-cloud/samples/appengine/.gcloudignore new file mode 100644 index 000000000..199e6d9f2 --- /dev/null +++ b/go-cloud/samples/appengine/.gcloudignore @@ -0,0 +1,25 @@ +# This file specifies files that are *not* uploaded to Google Cloud Platform +# using gcloud. It follows the same syntax as .gitignore, with the addition of +# "#!include" directives (which insert the entries of the given .gitignore-style +# file at that point). +# +# For more information, run: +# $ gcloud topic gcloudignore +# +.gcloudignore +# If you would like to upload your .git directory, .gitignore file or files +# from your .gitignore file, remove the corresponding line +# below: +.git +.gitignore + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +# Test binary, build with `go test -c` +*.test +# Output of the go coverage tool, specifically when used with LiteIDE +*.out \ No newline at end of file diff --git a/go-cloud/samples/appengine/.vscode/tasks.json b/go-cloud/samples/appengine/.vscode/tasks.json new file mode 100644 index 000000000..0f470cf71 --- /dev/null +++ b/go-cloud/samples/appengine/.vscode/tasks.json @@ -0,0 +1,16 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Test", + "type": "shell", + "command": "go test ./...", + "group": { + "kind": "test", + "isDefault": true + } + } + ] +} diff --git a/go-cloud/samples/appengine/README.md b/go-cloud/samples/appengine/README.md new file mode 100644 index 000000000..e5d91949e --- /dev/null +++ b/go-cloud/samples/appengine/README.md @@ -0,0 +1,27 @@ +# AppEngine Sample + +This directory holds a simple "Hello world!" AppEngine app that uses +[server.Server](https://github.com/google/go-cloud/blob/master/server/server.go). + +## Prerequisites + +You will need to install the following software to run this sample: + +- [Go](https://golang.org/doc/install) +- [gcloud CLI](https://cloud.google.com/sdk/downloads) + +## Deploying + +Run the following in this `samples/appengine` directory: + +```shell +# Build the binary. +go build +# Deploy it to AppEngine. +gcloud app deploy +# Open a browser to the app. +gcloud app browse +``` + +Try browsing to the `/healthz/readiness` page that `server.Server` adds a +handler for. diff --git a/go-cloud/samples/appengine/app.yaml b/go-cloud/samples/appengine/app.yaml new file mode 100644 index 000000000..f3809f139 --- /dev/null +++ b/go-cloud/samples/appengine/app.yaml @@ -0,0 +1 @@ +runtime: go111 diff --git a/go-cloud/samples/appengine/helloworld.go b/go-cloud/samples/appengine/helloworld.go new file mode 100644 index 000000000..8da9f8ca0 --- /dev/null +++ b/go-cloud/samples/appengine/helloworld.go @@ -0,0 +1,48 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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. + +// A simple "hello world" application using server.Server, to be run on +// Google App Engine (GAE). +package main + +import ( + "fmt" + "log" + "net/http" + "os" + + "github.com/gorilla/mux" + "github.com/DataDog/iceberg-go/go-cloud/server" +) + +func main() { + r := mux.NewRouter() + r.HandleFunc("/", handle) + + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + srv := server.New(r, nil) + log.Printf("Listening on port %s", port) + log.Fatal(srv.ListenAndServe(fmt.Sprintf(":%s", port))) +} + +func handle(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/" { + http.NotFound(w, r) + return + } + fmt.Fprint(w, "Hello world!") +} diff --git a/go-cloud/samples/go.mod b/go-cloud/samples/go.mod new file mode 100644 index 000000000..16e58e231 --- /dev/null +++ b/go-cloud/samples/go.mod @@ -0,0 +1,212 @@ +// Copyright 2018-2019 The Go Cloud Development Kit 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 +// +// https://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. + +module gocloud.dev/samples + +go 1.25.0 + +require ( + github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.1 + github.com/aws/aws-sdk-go-v2/service/s3 v1.103.3 + github.com/aws/aws-sdk-go-v2/service/ssm v1.60.1 + github.com/go-sql-driver/mysql v1.9.3 + github.com/google/go-cmdtest v0.3.0 + github.com/google/go-cmp v0.7.0 + github.com/google/subcommands v1.2.0 + github.com/google/uuid v1.6.0 + github.com/google/wire v0.6.0 + github.com/gorilla/mux v1.8.1 + github.com/streadway/amqp v1.0.0 + go.opentelemetry.io/contrib/exporters/autoexport v0.62.0 + go.opentelemetry.io/contrib/propagators/autoprop v0.62.0 + go.opentelemetry.io/otel v1.44.0 + go.opentelemetry.io/otel/log v0.13.0 + go.opentelemetry.io/otel/metric v1.44.0 + go.opentelemetry.io/otel/sdk v1.44.0 + go.opentelemetry.io/otel/sdk/log v0.13.0 + go.opentelemetry.io/otel/sdk/metric v1.44.0 + go.opentelemetry.io/otel/trace v1.44.0 + gocloud.dev v0.43.0 + gocloud.dev/docstore/mongodocstore v0.43.0 + gocloud.dev/pubsub/kafkapubsub v0.43.0 + gocloud.dev/pubsub/natspubsub v0.43.0 + gocloud.dev/pubsub/rabbitpubsub v0.43.0 + gocloud.dev/secrets/hashivault v0.43.0 + google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 + gopkg.in/pipe.v2 v2.0.0-20140414041502-3c2ca4d52544 +) + +require ( + cel.dev/expr v0.25.1 // indirect + cloud.google.com/go v0.121.4 // indirect + cloud.google.com/go/auth v0.16.3 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + cloud.google.com/go/compute/metadata v0.9.0 // indirect + cloud.google.com/go/firestore v1.18.0 // indirect + cloud.google.com/go/iam v1.5.2 // indirect + cloud.google.com/go/kms v1.22.0 // indirect + cloud.google.com/go/longrunning v0.6.7 // indirect + cloud.google.com/go/monitoring v1.24.2 // indirect + cloud.google.com/go/pubsub v1.49.0 // indirect + cloud.google.com/go/storage v1.55.0 // indirect + cloud.google.com/go/trace v1.11.6 // indirect + filippo.io/edwards25519 v1.1.1 // indirect + github.com/Azure/azure-amqp-common-go/v3 v3.2.3 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.9.1 // indirect + github.com/Azure/go-amqp v1.4.0 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest/to v0.4.1 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect + github.com/GoogleCloudPlatform/cloudsql-proxy v1.37.8 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.29.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator v0.53.0 // indirect + github.com/IBM/sarama v1.45.2 // indirect + github.com/XSAM/otelsql v0.39.0 // indirect + github.com/aws/aws-sdk-go v1.55.8 // indirect + github.com/aws/aws-sdk-go-v2 v1.42.0 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.13 // indirect + github.com/aws/aws-sdk-go-v2/config v1.29.17 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.70 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.84 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.30 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.12 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.22 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.29 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.29 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.41.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sns v1.34.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sqs v1.38.8 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 // indirect + github.com/aws/smithy-go v1.27.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/eapache/go-resiliency v1.7.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect + github.com/eapache/queue v1.1.0 // indirect + github.com/envoyproxy/go-control-plane/envoy v1.37.0 // indirect + github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/go-jose/go-jose/v4 v4.1.4 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang-jwt/jwt/v5 v5.2.3 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/google/go-replayers/grpcreplay v1.3.0 // indirect + github.com/google/go-replayers/httpreplay v1.2.0 // indirect + github.com/google/martian/v3 v3.3.3 // indirect + github.com/google/renameio v0.1.0 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.8 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.7 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/hashicorp/hcl v1.0.1-vault-7 // indirect + github.com/hashicorp/vault/api v1.20.0 // indirect + github.com/jcmturner/aescts/v2 v2.0.0 // indirect + github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect + github.com/jcmturner/gofork v1.7.6 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect + github.com/jcmturner/rpc/v2 v2.0.3 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/montanaflynn/stats v0.7.1 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/nats-io/nats.go v1.43.0 // indirect + github.com/nats-io/nkeys v0.4.11 // indirect + github.com/nats-io/nuid v1.0.1 // indirect + github.com/pierrec/lz4/v4 v4.1.22 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect + github.com/prometheus/client_golang v1.22.0 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.65.0 // indirect + github.com/prometheus/procfs v0.17.0 // indirect + github.com/rabbitmq/amqp091-go v1.10.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect + github.com/zeebo/errs v1.4.0 // indirect + go.mongodb.org/mongo-driver v1.17.4 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/bridges/prometheus v0.62.0 // indirect + go.opentelemetry.io/contrib/detectors/aws/ec2 v1.37.0 // indirect + go.opentelemetry.io/contrib/detectors/gcp v1.42.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect + go.opentelemetry.io/contrib/propagators/aws v1.37.0 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.37.0 // indirect + go.opentelemetry.io/contrib/propagators/jaeger v1.37.0 // indirect + go.opentelemetry.io/contrib/propagators/ot v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.13.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.13.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.59.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.53.0 // indirect + golang.org/x/net v0.56.0 // indirect + golang.org/x/oauth2 v0.36.0 // indirect + golang.org/x/sync v0.21.0 // indirect + golang.org/x/sys v0.46.0 // indirect + golang.org/x/text v0.38.0 // indirect + golang.org/x/time v0.12.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + google.golang.org/api v0.242.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/grpc v1.81.1 // indirect + google.golang.org/protobuf v1.36.11 // indirect +) diff --git a/go-cloud/samples/go.sum b/go-cloud/samples/go.sum new file mode 100644 index 000000000..dc2d598fe --- /dev/null +++ b/go-cloud/samples/go.sum @@ -0,0 +1,1068 @@ +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +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.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= +cloud.google.com/go v0.121.4 h1:cVvUiY0sX0xwyxPwdSU2KsF9knOVmtRyAMt8xou0iTs= +cloud.google.com/go v0.121.4/go.mod h1:XEBchUiHFJbz4lKBZwYBDHV/rSyfFktk737TLDU089s= +cloud.google.com/go/auth v0.16.3 h1:kabzoQ9/bobUmnseYnBO6qQG7q4a/CffFRlJSxv2wCc= +cloud.google.com/go/auth v0.16.3/go.mod h1:NucRGjaXfzP1ltpcQ7On/VTZ0H4kWB5Jy+Y9Dnm76fA= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/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/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= +cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +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.18.0 h1:cuydCaLS7Vl2SatAeivXyhbhDEIR8BDmtn4egDhIn2s= +cloud.google.com/go/firestore v1.18.0/go.mod h1:5ye0v48PhseZBdcl0qbl3uttu7FIEwEYVaWm0UIEOEU= +cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= +cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk= +cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8= +cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc= +cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA= +cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= +cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= +cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM= +cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U= +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= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.49.0 h1:5054IkbslnrMCgA2MAEPcsN3Ky+AyMpEZcii/DoySPo= +cloud.google.com/go/pubsub v1.49.0/go.mod h1:K1FswTWP+C1tI/nfi3HQecoVeFvL4HUOB1tdaNXKhUY= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.55.0 h1:NESjdAToN9u1tmhVqhXCaCwYBuvEhZLLv0gBr+2znf0= +cloud.google.com/go/storage v1.55.0/go.mod h1:ztSmTTwzsdXe5syLVS0YsbFxXuvEmEyZj7v7zChEmuY= +cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4= +cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw= +filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/Azure/azure-amqp-common-go/v3 v3.2.3 h1:uDF62mbd9bypXWi19V1bN5NZEO84JqgmI5G73ibAmrk= +github.com/Azure/azure-amqp-common-go/v3 v3.2.3/go.mod h1:7rPmbSfszeovxGfc5fSAXE4ehlXQZHpMja2OtxC2Tas= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 h1:Wc1ml6QlJs2BHQ/9Bqu1jiyggbsSjramq2oUmp5WeIo= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 h1:m/sWOGCREuSBqg2htVQTBY8nOZpyajYztF0vUvSZTuM= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0/go.mod h1:Pu5Zksi2KrU7LPbZbNINx6fuVrUp/ffvpxdDj+i8LeE= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 h1:FbH3BbSb4bvGluTesZZ+ttN/MDsnMmQP36OSnDuSXqw= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1/go.mod h1:9V2j0jn9jDEkCkv8w/bKTNppX/d0FVA1ud77xCIP4KA= +github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.9.1 h1:CRZwf68N55u7ZZo3Xx2ynuqEA6k5GZfwsEUkU8qsAPk= +github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.9.1/go.mod h1:NydgUaroiShkgOcb+X6OUdS3RalWBrvDNtOyFHJtsZY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.8.0 h1:LR0kAX9ykz8G4YgLCaRDVJ3+n43R8MneB5dTy2konZo= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.8.0/go.mod h1:DWAciXemNf++PQJLeXUB4HHH5OpsAh12HZnu2wXE1jA= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.1 h1:lhZdRq7TIx0GJQvSyX2Si406vrYsov2FXGp/RnSEtcs= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.1/go.mod h1:8cl44BDmi+effbARHMQjgOKA2AYvcohNm7KEt42mSV8= +github.com/Azure/go-amqp v0.17.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= +github.com/Azure/go-amqp v1.4.0 h1:Xj3caqi4comOF/L1Uc5iuBxR/pB6KumejC01YQOqOR4= +github.com/Azure/go-amqp v1.4.0/go.mod h1:vZAogwdrkbyK3Mla8m/CxSc/aKdnTZ4IbPxl51Y5WZE= +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.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.4.1 h1:CxNHBqdzTr7rLtdrtb5CMjJcDut+WNGCVv7OmS5+lTc= +github.com/Azure/go-autorest/autorest/to v0.4.1/go.mod h1:EtaofgU4zmtvn1zT2ARsjRFdq9vXx0YWtmElwL+GZ9M= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= +github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= +github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.37.8 h1:9aTh5GPncdE8BjUn+xanuF/BT3m2BJiyvS50Mmws/fw= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.37.8/go.mod h1:exon/I6I+5u/ab7AHmGh0eCXGoYZO5cjqA3wHJlYFFQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.29.0 h1:YVtMlmfRUTaWs3+1acwMBp7rBUo6zrxl6Kn13/R9YW4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.29.0/go.mod h1:rKOFVIPbNs2wZeh7ZeQ0D9p/XLgbNiTr5m7x6KuAshk= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.53.0 h1:4LP6hvB4I5ouTbGgWtixJhgED6xdf67twf9PoY96Tbg= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.53.0/go.mod h1:jUZ5LYlw40WMd07qxcQJD5M40aUxrfwqQX1g7zxYnrQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator v0.53.0 h1:RAHqDHJmNMLe6JvDoRIlXmb72w+62Ue/k5p/qP9yfAg= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator v0.53.0/go.mod h1:dtCRwgvytbGKWdlrjMOg9geBoRwRpCYWIOM/JhVsDIc= +github.com/IBM/sarama v1.45.2 h1:8m8LcMCu3REcwpa7fCP6v2fuPuzVwXDAM2DOv3CBrKw= +github.com/IBM/sarama v1.45.2/go.mod h1:ppaoTcVdGv186/z6MEKsMm70A5fwJfRTpstI37kVn3Y= +github.com/XSAM/otelsql v0.39.0 h1:4o374mEIMweaeevL7fd8Q3C710Xi2Jh/c8G4Qy9bvCY= +github.com/XSAM/otelsql v0.39.0/go.mod h1:uMOXLUX+wkuAuP0AR3B45NXX7E9lJS2mERa8gqdU8R0= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ= +github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk= +github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0= +github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2 v1.42.0 h1:XvXMJTkFQtpBKIWZnmr9ZEOc2InWM2yldjXEJ/bymhA= +github.com/aws/aws-sdk-go-v2 v1.42.0/go.mod h1:27+ACypSLljLAEKsCYOmrjKh83vuTRkuAe9Uv/3A4bg= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 h1:12SpdwU8Djs+YGklkinSSlcrPyj3H4VifVsKf78KbwA= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11/go.mod h1:dd+Lkp6YmMryke+qxW/VnKyhMBDTYP41Q2Bb+6gNZgY= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.13 h1:p1BBrg/Hhp6uK7zpejeI8QFXHJeC/mynzi04Sl03k9g= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.13/go.mod h1:8cIfkE9MDhkRZGpQ22aV6/lkYeYSozpz16Smrs5x4Ls= +github.com/aws/aws-sdk-go-v2/config v1.29.17 h1:jSuiQ5jEe4SAMH6lLRMY9OVC+TqJLP5655pBGjmnjr0= +github.com/aws/aws-sdk-go-v2/config v1.29.17/go.mod h1:9P4wwACpbeXs9Pm9w1QTh6BwWwJjwYvJ1iCt5QbCXh8= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70 h1:ONnH5CM16RTXRkS8Z1qg7/s2eDOhHhaXVd72mmyv4/0= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70/go.mod h1:M+lWhhmomVGgtuPOhO85u4pEa3SmssPTdcYpP/5J/xc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 h1:KAXP9JSHO1vKGCr5f4O6WmlVKLFFXgWYAGoJosorxzU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32/go.mod h1:h4Sg6FQdexC1yYG9RDnOvLbW1a/P986++/Y/a+GyEM8= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.84 h1:cTXRdLkpBanlDwISl+5chq5ui1d1YWg4PWMR9c3kXyw= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.84/go.mod h1:kwSy5X7tfIHN39uucmjQVs2LvDdXEjQucgQQEqCggEo= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29 h1:f3vKqSo13fhTYb+JEcXwXefZQE26I1FB5eTSniU67ko= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.29/go.mod h1:MzoLFUArKGpGD+ukmPiTPG1X5x4o6M2kq4v2dr1FiEc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29 h1:RdwIf/CuUsvJX3RgJagbOyotl/cxoLY4xviKuE7p2GY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.29/go.mod h1:71wt8W2EgswdZy9Mf9KNnzxZ3TiZlv4caKghPktDOkA= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36 h1:GMYy2EOWfzdP3wfVAGXBNKY5vK4K8vMET4sYOYltmqs= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36/go.mod h1:gDhdAV6wL3PmPqBhiPbnlS447GoWs8HTTOYef9/9Inw= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.30 h1:VTGy885W5DKBxWRUJbym9hytNaYzsyaPkCHGRRMAOhU= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.30/go.mod h1:AS0HycUvJRFvTt613AYDOgO2jzw+00cVSMny8XB3yMY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.12 h1:ZD2+BSw9vFsNlKYIasSNt3uDbjqqXIBcM13UJv/Lx2k= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.12/go.mod h1:Ms4zlcVBbXbiP7EVLhl+lgjvA/a7YphqQ3Ih3174EmI= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4 h1:nAP2GYbfh8dd2zGZqFRSMlq+/F6cMPBUuCsGAMkN074= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4/go.mod h1:LT10DsiGjLWh4GbjInf9LQejkYEhBgBCjLG5+lvk4EE= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.22 h1:V51LGlOq/1VsDsHUdoklAQi7rMmx4qQubvFYAlP2254= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.22/go.mod h1:4Pzhyz8hJOm2bepgl+NjvRx8vlUFAIIvJnZ/MkcNPpU= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 h1:t0E6FzREdtCsiLIoLCWsYliNsRBgyGD/MCK571qk4MI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17/go.mod h1:ygpklyoaypuyDvOM5ujWGrYWpAK3h7ugnmKCU/76Ys4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.29 h1:DRebniUGZ2MqiiIVmQJ04vIXr918hubdHMnarSLEWyU= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.29/go.mod h1:LfRkPCD8YHDM2E5eTkos2UpwYeZnBcVarTa8L59bJHA= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17 h1:qcLWgdhq45sDM9na4cvXax9dyLitn8EYBRl8Ak4XtG4= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17/go.mod h1:M+jkjBFZ2J6DJrjMv2+vkBbuht6kxJYtJiwoVgX4p4U= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.29 h1:hiME6pBzC7OTl9LMtlyTWBuEl1f4QBcUmFDKC7MLXtc= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.29/go.mod h1:G7RP+uhagpKtKhd1BM9N6JQqjCcGEU47K5lBVZQyRQw= +github.com/aws/aws-sdk-go-v2/service/kms v1.41.2 h1:zJeUxFP7+XP52u23vrp4zMcVhShTWbNO8dHV6xCSvFo= +github.com/aws/aws-sdk-go-v2/service/kms v1.41.2/go.mod h1:Pqd9k4TuespkireN206cK2QBsaBTL6X+VPAez5Qcijk= +github.com/aws/aws-sdk-go-v2/service/s3 v1.84.0 h1:0reDqfEN+tB+sozj2r92Bep8MEwBZgtAXTND1Kk9OXg= +github.com/aws/aws-sdk-go-v2/service/s3 v1.84.0/go.mod h1:kUklwasNoCn5YpyAqC/97r6dzTA1SRKJfKq16SXeoDU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.103.3 h1:JRseEu/vIDMaWis4bSw0QbXL+cvIGc1XnX076H5ZXLE= +github.com/aws/aws-sdk-go-v2/service/s3 v1.103.3/go.mod h1:77ZAgynvx1txMvDG8gGWoWkO1augYDxkp9JElWFgjQU= +github.com/aws/aws-sdk-go-v2/service/sns v1.34.7 h1:OBuZE9Wt8h2imuRktu+WfjiTGrnYdCIJg8IX92aalHE= +github.com/aws/aws-sdk-go-v2/service/sns v1.34.7/go.mod h1:4WYoZAhHt+dWYpoOQUgkUKfuQbE6Gg/hW4oXE0pKS9U= +github.com/aws/aws-sdk-go-v2/service/sqs v1.38.8 h1:80dpSqWMwx2dAm30Ib7J6ucz1ZHfiv5OCRwN/EnCOXQ= +github.com/aws/aws-sdk-go-v2/service/sqs v1.38.8/go.mod h1:IzNt/udsXlETCdvBOL0nmyMe2t9cGmXmZgsdoZGYYhI= +github.com/aws/aws-sdk-go-v2/service/ssm v1.60.1 h1:OwMzNDe5VVTXD4kGmeK/FtqAITiV8Mw4TCa8IyNO0as= +github.com/aws/aws-sdk-go-v2/service/ssm v1.60.1/go.mod h1:IyVabkWrs8SNdOEZLyFFcW9bUltV4G6OQS0s6H20PHg= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 h1:AIRJ3lfb2w/1/8wOOSqYb9fUKGwQbtysJ2H1MofRUPg= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5/go.mod h1:b7SiVprpU+iGazDUqvRSLf5XmCdn+JtT1on7uNL6Ipc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 h1:BpOxT3yhLwSJ77qIY3DoHAQjZsc4HEGfMCE4NGy3uFg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3/go.mod h1:vq/GQR1gOFLquZMSrxUK/cpvKCNVYibNyJ1m7JrU88E= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 h1:NFOJ/NXEGV4Rq//71Hs1jC/NvPs1ezajK+yQmkwnPV0= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0/go.mod h1:7ph2tGpfQvwzgistp2+zga9f+bCjlQJPkPUmMgDSD7w= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/smithy-go v1.27.1 h1:4T340VFndXtADGF52gYa1POyL7s9E4Z1OeZ1hCscIw8= +github.com/aws/smithy-go v1.27.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= +github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +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= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= +github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE= +github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA= +github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= +github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= +github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +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= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= +github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= +github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= +github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= +github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0= +github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +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/go-cmdtest v0.3.0 h1:382oNMtKBpvJjOm5c5ONU3pzwh2ZK/eNA4/h2v9PnXM= +github.com/google/go-cmdtest v0.3.0/go.mod h1:apVn/GCasLZUVpAJ6oWAuyP7Ne7CEsQbTnc0plM3m+o= +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= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-replayers/grpcreplay v1.3.0 h1:1Keyy0m1sIpqstQmgz307zhiJ1pV4uIlFds5weTmxbo= +github.com/google/go-replayers/grpcreplay v1.3.0/go.mod h1:v6NgKtkijC0d3e3RW8il6Sy5sqRVUwoQa4mHOGEy8DI= +github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk= +github.com/google/go-replayers/httpreplay v1.2.0/go.mod h1:WahEFFZZ7a1P4VM1qEeHy+tME4bwyqPcwWbNlUI1Mcg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= +github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +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.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +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 v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +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.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= +github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw= +github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +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/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I= +github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/hashicorp/vault/api v1.20.0 h1:KQMHElgudOsr+IbJgmbjHnCTxEpKs9LnozA1D3nozU4= +github.com/hashicorp/vault/api v1.20.0/go.mod h1:GZ4pcjfzoOWpkJ3ijHNpEoAxKEsBJnVljyTe3jM2Sms= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +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/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= +github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= +github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/nats-io/jwt/v2 v2.5.0 h1:WQQ40AAlqqfx+f6ku+i0pOVm+ASirD4fUh+oQsiE9Ak= +github.com/nats-io/jwt/v2 v2.5.0/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI= +github.com/nats-io/nats-server/v2 v2.9.23 h1:6Wj6H6QpP9FMlpCyWUaNu2yeZ/qGj+mdRkZ1wbikExU= +github.com/nats-io/nats-server/v2 v2.9.23/go.mod h1:wEjrEy9vnqIGE4Pqz4/c75v9Pmaq7My2IgFmnykc4C0= +github.com/nats-io/nats.go v1.43.0 h1:uRFZ2FEoRvP64+UUhaTokyS18XBCR/xM2vQZKO4i8ug= +github.com/nats-io/nats.go v1.43.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= +github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0= +github.com/nats-io/nkeys v0.4.11/go.mod h1:szDimtgmfOi9n25JpfIdGw12tZFYXqhGxjhVxsatHVE= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= +github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= +github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= +github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= +github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= +github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= +github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= +github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 h1:bsUq1dX0N8AOIL7EB/X911+m4EHsnWEHeJ0c+3TTBrg= +github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI= +github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs= +github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= +github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw= +go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/bridges/prometheus v0.62.0 h1:0mfk3D3068LMGpIhxwc0BqRlBOBHVgTP9CygmnJM/TI= +go.opentelemetry.io/contrib/bridges/prometheus v0.62.0/go.mod h1:hStk98NJy1wvlrXIqWsli+uELxRRseBMld+gfm2xPR4= +go.opentelemetry.io/contrib/detectors/aws/ec2 v1.37.0 h1:BJnWw8+FULhuuF/6R6B/JYqAlCTCy9E4J8qmLpo/7KU= +go.opentelemetry.io/contrib/detectors/aws/ec2 v1.37.0/go.mod h1:gs3y8jvJscW5D+FzrZvJZEsGj+xlMCF0S1x4R6ktiNo= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0 h1:B+WbN9RPsvobe6q4vP6KgM8/9plR/HNjgGBrfcOlweA= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0/go.mod h1:K5zQ3TT7p2ru9Qkzk0bKtCql0RGkPj9pRjpXgZJZ+rU= +go.opentelemetry.io/contrib/detectors/gcp v1.42.0/go.mod h1:W9zQ439utxymRrXsUOzZbFX4JhLxXU4+ZnCt8GG7yA8= +go.opentelemetry.io/contrib/exporters/autoexport v0.62.0 h1:aCpZ6vvmOj5GHg1eUygjS/05mlQaEBsQDdTw5yT8EsE= +go.opentelemetry.io/contrib/exporters/autoexport v0.62.0/go.mod h1:1xHkmmL3bQm8m86HVoZTdgK/LIY5JpxdAWjog6cdtUs= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 h1:rbRJ8BBoVMsQShESYZ0FkvcITu8X8QNwJogcLUmDNNw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0/go.mod h1:ru6KHrNtNHxM4nD/vd6QrLVWgKhxPYgblq4VAtNawTQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= +go.opentelemetry.io/contrib/propagators/autoprop v0.62.0 h1:1+EHlhAe/tukctfePZRrDruB9vn7MdwyC+rf36nUSPM= +go.opentelemetry.io/contrib/propagators/autoprop v0.62.0/go.mod h1:skzESZBY3IYcqJgImc+fwXQWflvVe+jZxoA/uw60NaI= +go.opentelemetry.io/contrib/propagators/aws v1.37.0 h1:cp8AFiM/qjBm10C/ATIRnEDXpD5MBknrA0ANw4T2/ss= +go.opentelemetry.io/contrib/propagators/aws v1.37.0/go.mod h1:Cy8Hk2E2iSGEbsLnPUdeigrexaAOAGIAmBFK919EQs0= +go.opentelemetry.io/contrib/propagators/b3 v1.37.0 h1:0aGKdIuVhy5l4GClAjl72ntkZJhijf2wg1S7b5oLoYA= +go.opentelemetry.io/contrib/propagators/b3 v1.37.0/go.mod h1:nhyrxEJEOQdwR15zXrCKI6+cJK60PXAkJ/jRyfhr2mg= +go.opentelemetry.io/contrib/propagators/jaeger v1.37.0 h1:pW+qDVo0jB0rLsNeaP85xLuz20cvsECUcN7TE+D8YTM= +go.opentelemetry.io/contrib/propagators/jaeger v1.37.0/go.mod h1:x7bd+t034hxLTve1hF9Yn9qQJlO/pP8H5pWIt7+gsFM= +go.opentelemetry.io/contrib/propagators/ot v1.37.0 h1:tVjnBF6EiTDMXoq2Xuc2vK0I7MTbEs05II/0j9mMK+E= +go.opentelemetry.io/contrib/propagators/ot v1.37.0/go.mod h1:MQjyNXtxAC8PGN9gzPtO4GY5zuP+RI3XX53uWbCTvEQ= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.13.0 h1:z6lNIajgEBVtQZHjfw2hAccPEBDs+nx58VemmXWa2ec= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.13.0/go.mod h1:+kyc3bRx/Qkq05P6OCu3mTEIOxYRYzoIg+JsUp5X+PM= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.13.0 h1:zUfYw8cscHHLwaY8Xz3fiJu+R59xBnkgq2Zr1lwmK/0= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.13.0/go.mod h1:514JLMCcFLQFS8cnTepOk6I09cKWJ5nGHBxHrMJ8Yfg= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8GlgXCJQd5BU98C0hZnBbElszTmUgCNCfYneaDL0A= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 h1:9PgnL3QNlj10uGxExowIDIZu66aVBwWhXmbOp1pa6RA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0/go.mod h1:0ineDcLELf6JmKfuo0wvvhAVMuxWFYvkTin2iV4ydPQ= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0 h1:RuynHbfU8JUEw7DyONgkVYg2SVtsoF28y0LGIr69jgA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0/go.mod h1:qZF+/lBs71APw8mlnEZcqZHMzqrYrsFiJOv83lX1OGo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 h1:lgh3PiVrRUWMLOVSkQicxzZll5NjF1r+AtsX1XRIHw0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0/go.mod h1:5Cnhth3m/AgOeTgE3ex12pPmiu/gGtZit03kSzx9X7s= +go.opentelemetry.io/otel/exporters/prometheus v0.59.0 h1:HHf+wKS6o5++XZhS98wvILrLVgHxjA/AMjqHKes+uzo= +go.opentelemetry.io/otel/exporters/prometheus v0.59.0/go.mod h1:R8GpRXTZrqvXHDEGVH5bF6+JqAZcK8PjJcZ5nGhEWiE= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKECHbOlr5GLwH6KTjLJ1sBSkkxkc= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0/go.mod h1:/GXR0tBmmkxDaCUGahvksvp66mx4yh5+cFXgSlhg0vQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.37.0 h1:6VjV6Et+1Hd2iLZEPtdV7vie80Yyqf7oikJLjQ/myi0= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.37.0/go.mod h1:u8hcp8ji5gaM/RfcOo8z9NMnf1pVLfVY7lBY2VOGuUU= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0 h1:SNhVp/9q4Go/XHBkQ1/d5u9P/U+L1yaGPoi0x+mStaI= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.37.0/go.mod h1:tx8OOlGH6R4kLV67YaYO44GFXloEjGPZuMjEkaaqIp4= +go.opentelemetry.io/otel/log v0.13.0 h1:yoxRoIZcohB6Xf0lNv9QIyCzQvrtGZklVbdCoyb7dls= +go.opentelemetry.io/otel/log v0.13.0/go.mod h1:INKfG4k1O9CL25BaM1qLe0zIedOpvlS5Z7XgSbmN83E= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/log v0.13.0 h1:I3CGUszjM926OphK8ZdzF+kLqFvfRY/IIoFq/TjwfaQ= +go.opentelemetry.io/otel/sdk/log v0.13.0/go.mod h1:lOrQyCCXmpZdN7NchXb6DOZZa1N5G1R2tm5GMMTpDBw= +go.opentelemetry.io/otel/sdk/log/logtest v0.13.0 h1:9yio6AFZ3QD9j9oqshV1Ibm9gPLlHNxurno5BreMtIA= +go.opentelemetry.io/otel/sdk/log/logtest v0.13.0/go.mod h1:QOGiAJHl+fob8Nu85ifXfuQYmJTFAvcrxL6w5/tu168= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= +go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/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.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +gocloud.dev v0.43.0/go.mod h1:eD8rkg7LhKUHrzkEdLTZ+Ty/vgPHPCd+yMQdfelQVu4= +gocloud.dev/docstore/mongodocstore v0.43.0/go.mod h1:vNd1bxEOoEfhND8rViEXz+lB3zD56PAiiZThuKtSDW8= +gocloud.dev/pubsub/kafkapubsub v0.43.0/go.mod h1:uKI0CXuj7HJ/YnnOLQ3VkDnuUnkz+q/d+tRzmfhmOOU= +gocloud.dev/pubsub/natspubsub v0.43.0/go.mod h1:xJn8TO8pGYieDn6AsRFsYfhQW8cnC+xGmG9APGNxkpQ= +gocloud.dev/pubsub/rabbitpubsub v0.43.0/go.mod h1:sEaueAGat+OASRoB3QDkghCtibKttgg7X6zsPTm1pl0= +gocloud.dev/secrets/hashivault v0.43.0/go.mod h1:KdWKL+TXDi0cXgEd/MTeaidKlotvyJtnTDi71B3rR9U= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= +golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= +golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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/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= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +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-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= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/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.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-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/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +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.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= +golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE= +golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +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-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +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.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.242.0 h1:7Lnb1nfnpvbkCiZek6IXKdJ0MFuAZNAJKQfA1ws62xg= +google.golang.org/api v0.242.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= +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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +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= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 h1:Nt6z9UHqSlIdIGJdz6KhTIs2VRx/iOsA5iE8bmQNcxs= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79/go.mod h1:kTmlBHMPqR5uCZPBvwa2B18mvubkjyY3CRLI0c6fj0s= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79 h1:iOye66xuaAK0WnkPuhQPUFy8eJcmwUXqGGP3om6IxX8= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79/go.mod h1:HKJDgKsFUnv5VAGeQjz8kxcgDP0HoE0iZNp0OdZNlhE= +google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= +google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 h1:1ZwqphdOdWYXsUHgMpU/101nCtf/kSp9hOrcvFsnl10= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ= +google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +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.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/pipe.v2 v2.0.0-20140414041502-3c2ca4d52544 h1:WJH1qsOB4/zb/li+zLMn0vaAUJ5FqPv6HYLI3aQVg1k= +gopkg.in/pipe.v2 v2.0.0-20140414041502-3c2ca4d52544/go.mod h1:UhTeH/yXCK/KY7TX24mqPkaQ7gZeqmWd/8SSS8B3aHw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/go-cloud/samples/gocdk-blob/blob.ct b/go-cloud/samples/gocdk-blob/blob.ct new file mode 100644 index 000000000..35a88d427 --- /dev/null +++ b/go-cloud/samples/gocdk-blob/blob.ct @@ -0,0 +1,39 @@ +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Tests of the gocdk-blob program. + +# ROOTDIR_URL is a platform-specific environment variable set +# in main_test.go. + +# Create a subdirectory so we can use fileblob. +$ mkdir bucket + +# List an empty bucket: valid, but no output. +$ gocdk-blob ls ${ROOTDIR_URL}/bucket + +$ fecho hello.txt hello world +$ gocdk-blob upload ${ROOTDIR_URL}/bucket hw < hello.txt + +$ gocdk-blob ls ${ROOTDIR_URL}/bucket +hw + +$ gocdk-blob download ${ROOTDIR_URL}/bucket hw +hello world + +# Error downloading a bucket that doesn't exist. +# For now we can't use this test case, because the output won't be the same across operating systems. +#$ gocdk-blob download ${ROOTDIR_URL}/bucket noexist --> FAIL +#gocdk-blob: Failed to read "noexist": blob (code=NotFound): stat ${SLASHDIR}/bucket/noexist: no such file or directory + diff --git a/go-cloud/samples/gocdk-blob/main.go b/go-cloud/samples/gocdk-blob/main.go new file mode 100644 index 000000000..2b2606c5d --- /dev/null +++ b/go-cloud/samples/gocdk-blob/main.go @@ -0,0 +1,214 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// gocdk-blob demonstrates the use of the Go CDK blob package in a +// simple command-line application. +package main + +import ( + "context" + "flag" + "fmt" + "io" + "log" + "os" + + "github.com/google/subcommands" + "github.com/DataDog/iceberg-go/go-cloud/blob" + + // Import the blob driver packages we want to be able to open. + _ "github.com/DataDog/iceberg-go/go-cloud/blob/azureblob" + _ "github.com/DataDog/iceberg-go/go-cloud/blob/fileblob" + _ "github.com/DataDog/iceberg-go/go-cloud/blob/gcsblob" + _ "github.com/DataDog/iceberg-go/go-cloud/blob/s3blob" +) + +const helpSuffix = ` + + See https://gocloud.dev/concepts/urls/ for more background on + Go CDK URLs, and sub-packages under gocloud.dev/blob + (https://godoc.org/gocloud.dev/blob#pkg-subdirectories) + for details on the blob.Bucket URL format. +` + +func main() { + os.Exit(run()) +} + +func run() int { + subcommands.Register(subcommands.HelpCommand(), "") + subcommands.Register(&downloadCmd{}, "") + subcommands.Register(&listCmd{}, "") + subcommands.Register(&uploadCmd{}, "") + log.SetFlags(0) + log.SetPrefix("gocdk-blob: ") + flag.Parse() + return int(subcommands.Execute(context.Background())) +} + +type downloadCmd struct{} + +func (*downloadCmd) Name() string { return "download" } +func (*downloadCmd) Synopsis() string { return "Output a blob to stdout" } +func (*downloadCmd) Usage() string { + return `download + + Read the blob from and write it to stdout. + + Example: + gocdk-blob download gs://mybucket my/gcs/file > foo.txt` + helpSuffix +} + +func (*downloadCmd) SetFlags(_ *flag.FlagSet) {} + +func (*downloadCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 2 { + f.Usage() + return subcommands.ExitUsageError + } + bucketURL := f.Arg(0) + blobKey := f.Arg(1) + + // Open a *blob.Bucket using the bucketURL. + bucket, err := blob.OpenBucket(ctx, bucketURL) + if err != nil { + log.Printf("Failed to open bucket: %v\n", err) + return subcommands.ExitFailure + } + defer bucket.Close() + + // Open a *blob.Reader for the blob at blobKey. + reader, err := bucket.NewReader(ctx, blobKey, nil) + if err != nil { + log.Printf("Failed to read %q: %v\n", blobKey, err) + return subcommands.ExitFailure + } + defer reader.Close() + + // Copy the data. + _, err = io.Copy(os.Stdout, reader) + if err != nil { + log.Printf("Failed to copy data: %v\n", err) + return subcommands.ExitFailure + } + return subcommands.ExitSuccess +} + +type listCmd struct { + prefix string + delimiter string +} + +func (*listCmd) Name() string { return "ls" } +func (*listCmd) Synopsis() string { return "List blobs in a bucket" } +func (*listCmd) Usage() string { + return `ls [-p ] [d ] + + List the blobs in . + + Example: + gocdk-blob ls -p "subdir/" gs://mybucket` + helpSuffix +} + +func (cmd *listCmd) SetFlags(f *flag.FlagSet) { + f.StringVar(&cmd.prefix, "p", "", "prefix to match") + f.StringVar(&cmd.delimiter, "d", "/", "directory delimiter; empty string returns flattened listing") +} + +func (cmd *listCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 1 { + f.Usage() + return subcommands.ExitUsageError + } + bucketURL := f.Arg(0) + + // Open a *blob.Bucket using the bucketURL. + bucket, err := blob.OpenBucket(ctx, bucketURL) + if err != nil { + log.Printf("Failed to open bucket: %v\n", err) + return subcommands.ExitFailure + } + defer bucket.Close() + + opts := blob.ListOptions{ + Prefix: cmd.prefix, + Delimiter: cmd.delimiter, + } + iter := bucket.List(&opts) + for { + obj, err := iter.Next(ctx) + if err == io.EOF { + break + } + if err != nil { + log.Printf("Failed to list: %v", err) + return subcommands.ExitFailure + } + fmt.Println(obj.Key) + } + return subcommands.ExitSuccess +} + +type uploadCmd struct{} + +func (*uploadCmd) Name() string { return "upload" } +func (*uploadCmd) Synopsis() string { return "Upload a blob from stdin" } +func (*uploadCmd) Usage() string { + return `upload + + Read from stdin and write to the blob in . + + Example: + cat foo.txt | gocdk-blob upload gs://mybucket my/gcs/file` + helpSuffix +} + +func (*uploadCmd) SetFlags(_ *flag.FlagSet) {} + +func (*uploadCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) (status subcommands.ExitStatus) { + if f.NArg() != 2 { + f.Usage() + return subcommands.ExitUsageError + } + bucketURL := f.Arg(0) + blobKey := f.Arg(1) + + // Open a *blob.Bucket using the bucketURL. + bucket, err := blob.OpenBucket(ctx, bucketURL) + if err != nil { + log.Printf("Failed to open bucket: %v\n", err) + return subcommands.ExitFailure + } + defer bucket.Close() + + // Open a *blob.Writer for the blob at blobKey. + writer, err := bucket.NewWriter(ctx, blobKey, nil) + if err != nil { + log.Printf("Failed to write %q: %v\n", blobKey, err) + return subcommands.ExitFailure + } + defer func() { + if err := writer.Close(); err != nil && status == subcommands.ExitSuccess { + log.Printf("closing the writer: %v", err) + status = subcommands.ExitFailure + } + }() + + // Copy the data. + _, err = io.Copy(writer, os.Stdin) + if err != nil { + log.Printf("Failed to copy data: %v\n", err) + return subcommands.ExitFailure + } + return subcommands.ExitSuccess +} diff --git a/go-cloud/samples/gocdk-blob/main_test.go b/go-cloud/samples/gocdk-blob/main_test.go new file mode 100644 index 000000000..3aecbb2f5 --- /dev/null +++ b/go-cloud/samples/gocdk-blob/main_test.go @@ -0,0 +1,44 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "flag" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/google/go-cmdtest" +) + +var update = flag.Bool("update", false, "replace test file contents with output") + +func Test(t *testing.T) { + ts, err := cmdtest.Read(".") + if err != nil { + t.Fatal(err) + } + ts.Commands["gocdk-blob"] = cmdtest.InProcessProgram("gocdk-blob", run) + ts.Setup = func(rootdir string) error { + // On Windows, convert "\" to "/" and add a leading "/": + slashdir := filepath.ToSlash(rootdir) + if os.PathSeparator != '/' && !strings.HasPrefix(slashdir, "/") { + slashdir = "/" + slashdir + } + return os.Setenv("ROOTDIR_URL", "file://"+slashdir) + } + ts.Run(t, *update) +} diff --git a/go-cloud/samples/gocdk-docstore/docstore.ct b/go-cloud/samples/gocdk-docstore/docstore.ct new file mode 100644 index 000000000..ebbd7ee6a --- /dev/null +++ b/go-cloud/samples/gocdk-docstore/docstore.ct @@ -0,0 +1,44 @@ +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Tests of the gocdk-doctore program. + +$ setenv url mem://sample-coll/ID?filename=save + +# Collection is initially empty. +$ gocdk-docstore ls ${url} + +$ gocdk-docstore put -d 2019-05-01 -id first ${url} message1 +Put message: first 2019-05-01: message1 + +$ gocdk-docstore ls -d 2019-05-01 ${url} +first 2019-05-01: message1 + +$ gocdk-docstore put -d 2019-05-02 -id second ${url} message2 +$ gocdk-docstore ls -d 2019-05-02 ${url} +Put message: second 2019-05-02: message2 +second 2019-05-02: message2 + +$ gocdk-docstore update first ${url} new-message +updated: first 2019-05-01: new-message + + +# Delete everything. +$ gocdk-docstore delete ${url} + +# Collection is empty again. +$ gocdk-docstore ls ${url} + + + diff --git a/go-cloud/samples/gocdk-docstore/main.go b/go-cloud/samples/gocdk-docstore/main.go new file mode 100644 index 000000000..8884f372c --- /dev/null +++ b/go-cloud/samples/gocdk-docstore/main.go @@ -0,0 +1,281 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// gocdk-docstore demonstrates the use of the Go CDK docstore package in a +// simple command-line application. +package main + +import ( + "context" + "flag" + "fmt" + "io" + "os" + "time" + + "github.com/google/subcommands" + "github.com/google/uuid" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + + // Import the docstore driver packages we want to be able to open. + _ "github.com/DataDog/iceberg-go/go-cloud/docstore/awsdynamodb" + _ "github.com/DataDog/iceberg-go/go-cloud/docstore/gcpfirestore" + _ "github.com/DataDog/iceberg-go/go-cloud/docstore/memdocstore" + _ "github.com/DataDog/iceberg-go/go-cloud/docstore/mongodocstore" +) + +const helpSuffix = ` + + See https://gocloud.dev/concepts/urls/ for more background on + Go CDK URLs, and sub-packages under gocloud.dev/docstore + (https://godoc.org/gocloud.dev/docstore#pkg-subdirectories) + for details on the docstore.Collection URL format. +` + +func main() { + os.Exit(run()) +} + +func run() int { + subcommands.Register(subcommands.HelpCommand(), "") + subcommands.Register(&listCmd{}, "") + subcommands.Register(&putCmd{}, "") + subcommands.Register(&updateCmd{}, "") + subcommands.Register(&deleteCmd{}, "") + flag.Parse() + return int(subcommands.Execute(context.Background())) +} + +// A Message is a document entry stored in a collection. +type Message struct { + ID string // unique ID of each document + Date string + Content string + DocstoreRevision any +} + +func (m Message) String() string { + return fmt.Sprintf("%s %s: %s", m.ID, m.Date, m.Content) +} + +type listCmd struct { + date string +} + +func (*listCmd) Name() string { return "ls" } +func (*listCmd) Synopsis() string { return "List items in a collection" } +func (*listCmd) Usage() string { + return `ls [-d ] + + List the documents in . + + Example: + gocdk-docstore ls -d "2006-01-02" "mongo://myDB/myCollection?id_field=ID"` + helpSuffix +} + +func (cmd *listCmd) SetFlags(f *flag.FlagSet) { + f.StringVar(&cmd.date, "d", "", "get the messages from this date, in the format YYYY-MM-DD") +} + +func (cmd *listCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 1 { + f.Usage() + return subcommands.ExitUsageError + } + collectionURL := f.Arg(0) + + // Open a *docstore.Collection using the collectionURL. + collection, err := docstore.OpenCollection(ctx, collectionURL) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to open collection: %v\n", err) + return subcommands.ExitFailure + } + defer collection.Close() + + q := collection.Query() + if cmd.date != "" { + q = q.Where("Date", "=", cmd.date) + } + iter := q.Get(ctx) + defer iter.Stop() + for { + var msg Message + err := iter.Next(ctx, &msg) + if err == io.EOF { + break + } + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to list: %v\n", err) + return subcommands.ExitFailure + } + fmt.Println(msg) + } + return subcommands.ExitSuccess +} + +type putCmd struct { + id string // user-chosen ID + date string // user-chosen date +} + +func (*putCmd) Name() string { return "put" } +func (*putCmd) Synopsis() string { return "Put an item from stdin" } +func (*putCmd) Usage() string { + return `put [-id ] [-d ] + + Read from stdin and put an message with the current timestamp in . + + Example: + gocdk-docstore put "mongo://myDB/myCollection?id_field=ID" "hello docstore"` + helpSuffix +} + +func (p *putCmd) SetFlags(f *flag.FlagSet) { + f.StringVar(&p.id, "id", "", "ID of document") + f.StringVar(&p.date, "d", "", "date of document") +} + +func (p *putCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 2 { + f.Usage() + return subcommands.ExitUsageError + } + collectionURL := f.Arg(0) + content := f.Arg(1) + + // Open a *docstore.Collection using the collectionURL. + collection, err := docstore.OpenCollection(ctx, collectionURL) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to open collection: %v\n", err) + return subcommands.ExitFailure + } + defer collection.Close() + + if p.id == "" { + p.id = uuid.New().String() + } + if p.date == "" { + p.date = time.Now().Format("2006-01-02") + } + msg := &Message{ + ID: p.id, + Date: p.date, + Content: content, + } + if err := collection.Put(ctx, msg); err != nil { + fmt.Fprintf(os.Stderr, "Failed to put message: %v\n", err) + return subcommands.ExitFailure + } + fmt.Printf("Put message: %s\n", msg) + return subcommands.ExitSuccess +} + +type updateCmd struct{} + +func (*updateCmd) Name() string { return "update" } +func (*updateCmd) Synopsis() string { return "Update an item in a collection" } +func (*updateCmd) Usage() string { + return `update + + Update the document with ID in . + + Example: + gocdk-docstore update "mongo://myDB/myCollection?id_field=ID" "hello again"` + helpSuffix +} + +func (*updateCmd) SetFlags(_ *flag.FlagSet) {} + +func (cmd *updateCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 3 { + f.Usage() + return subcommands.ExitUsageError + } + id := f.Arg(0) + collectionURL := f.Arg(1) + updated := f.Arg(2) + + // Open a *docstore.Collection using the collectionURL. + collection, err := docstore.OpenCollection(ctx, collectionURL) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to open collection: %v\n", err) + return subcommands.ExitFailure + } + defer collection.Close() + + msg := &Message{ID: id} + mods := docstore.Mods{"Content": updated} + if errs := collection.Actions().Update(msg, mods).Get(msg).Do(ctx); errs != nil { + fmt.Fprintf(os.Stderr, "Failed to update message: %v\n", errs) + return subcommands.ExitFailure + } + fmt.Printf("updated: %s\n", msg) + return subcommands.ExitSuccess +} + +type deleteCmd struct { + date string +} + +func (*deleteCmd) Name() string { return "delete" } +func (*deleteCmd) Synopsis() string { return "Delete items in a collection" } +func (*deleteCmd) Usage() string { + return `delete [-d ] + + Delete the documents in . + + Example: + gocdk-docstore delete -d 2006-01-02 mongo://myDB/myCollection?id_field=ID` + helpSuffix +} + +func (cmd *deleteCmd) SetFlags(f *flag.FlagSet) { + f.StringVar(&cmd.date, "d", "", "delete the messages from this date, in the format YYYY-MM-DD") +} + +func (cmd *deleteCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 1 { + f.Usage() + return subcommands.ExitUsageError + } + collectionURL := f.Arg(0) + + // Open a *docstore.Collection using the collectionURL. + collection, err := docstore.OpenCollection(ctx, collectionURL) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to open collection: %v\n", err) + return subcommands.ExitFailure + } + defer collection.Close() + + q := collection.Query() + if cmd.date != "" { + q = q.Where("Date", "=", cmd.date) + } + iter := q.Get(ctx, "ID") + dels := collection.Actions() + for { + var msg Message + err := iter.Next(ctx, &msg) + if err == io.EOF { + break + } + if err != nil { + return subcommands.ExitFailure + } + dels.Delete(&msg) + } + if err := dels.Do(ctx); err != nil { + fmt.Fprintf(os.Stderr, "Failed to delete: %v\n", err) + return subcommands.ExitFailure + } + return subcommands.ExitSuccess +} diff --git a/go-cloud/samples/gocdk-docstore/main_test.go b/go-cloud/samples/gocdk-docstore/main_test.go new file mode 100644 index 000000000..19330e387 --- /dev/null +++ b/go-cloud/samples/gocdk-docstore/main_test.go @@ -0,0 +1,33 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "flag" + "testing" + + "github.com/google/go-cmdtest" +) + +var update = flag.Bool("update", false, "replace test file contents with output") + +func Test(t *testing.T) { + ts, err := cmdtest.Read(".") + if err != nil { + t.Fatal(err) + } + ts.Commands["gocdk-docstore"] = cmdtest.InProcessProgram("gocdk-docstore", run) + ts.Run(t, *update) +} diff --git a/go-cloud/samples/gocdk-pubsub/main.go b/go-cloud/samples/gocdk-pubsub/main.go new file mode 100644 index 000000000..118b443c3 --- /dev/null +++ b/go-cloud/samples/gocdk-pubsub/main.go @@ -0,0 +1,159 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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. + +// gocdk-pubsub demonstrates the use of the Go CDK pubsub package in a +// simple command-line application. +package main + +import ( + "bufio" + "context" + "flag" + "fmt" + "log" + "os" + + "github.com/google/subcommands" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + + // Import the pubsub driver packages we want to be able to open. + _ "github.com/DataDog/iceberg-go/go-cloud/pubsub/awssnssqs" + _ "github.com/DataDog/iceberg-go/go-cloud/pubsub/azuresb" + _ "github.com/DataDog/iceberg-go/go-cloud/pubsub/gcppubsub" + _ "github.com/DataDog/iceberg-go/go-cloud/pubsub/kafkapubsub" + _ "github.com/DataDog/iceberg-go/go-cloud/pubsub/natspubsub" + _ "github.com/DataDog/iceberg-go/go-cloud/pubsub/rabbitpubsub" +) + +const helpSuffix = ` + + See https://gocloud.dev/concepts/urls/ for more background on + Go CDK URLs, and sub-packages under gocloud.dev/pubsub + (https://godoc.org/gocloud.dev/pubsub#pkg-subdirectories) + for details on the topic/subscription URL format. +` + +func main() { + os.Exit(run()) +} + +func run() int { + subcommands.Register(subcommands.HelpCommand(), "") + subcommands.Register(&pubCmd{}, "") + subcommands.Register(&subCmd{}, "") + log.SetFlags(0) + log.SetPrefix("gocdk-pubsub: ") + flag.Parse() + return int(subcommands.Execute(context.Background())) +} + +type pubCmd struct{} + +func (*pubCmd) Name() string { return "pub" } +func (*pubCmd) Synopsis() string { return "Publish a message to a topic" } +func (*pubCmd) Usage() string { + return `pub + + Read messages from stdin, one per line and send them to . + + Example: + gocdk-pubsub pub gcppubsub://myproject/mytopic` + helpSuffix +} + +func (*pubCmd) SetFlags(_ *flag.FlagSet) {} + +func (*pubCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 1 { + f.Usage() + return subcommands.ExitUsageError + } + topicURL := f.Arg(0) + + // Open a *pubsub.Topic using the URL. + topic, err := pubsub.OpenTopic(ctx, topicURL) + if err != nil { + log.Print(err) + return subcommands.ExitFailure + } + defer topic.Shutdown(ctx) + + // Read lines from stdin and send them as messages to the topic. + fmt.Fprintf(os.Stderr, "Enter messages, one per line, to be published to %q.\n", topicURL) + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + line := scanner.Text() + if line == "" { + log.Print("Skipping empty message.") + continue + } + m := &pubsub.Message{Body: []byte(line)} + if err := topic.Send(ctx, m); err != nil { + log.Print(err) + return subcommands.ExitFailure + } + } + if err := scanner.Err(); err != nil { + log.Print(err) + return subcommands.ExitFailure + } + return subcommands.ExitSuccess +} + +type subCmd struct { + n int // number of messages to receive, or 0 for infinite +} + +func (*subCmd) Name() string { return "sub" } +func (*subCmd) Synopsis() string { return "Receive messages from a subscription" } +func (*subCmd) Usage() string { + return `sub [-n N] + + Receive messages from and send them to stdout, one per line. + + Example: + gocdk-pubsub sub gcppubsub://myproject/mytopic` + helpSuffix +} + +func (cmd *subCmd) SetFlags(f *flag.FlagSet) { + f.IntVar(&cmd.n, "n", 0, "number of messages to receive, or 0 for unlimited") +} + +func (cmd *subCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 1 { + f.Usage() + return subcommands.ExitUsageError + } + subURL := f.Arg(0) + + // Open a *pubsub.Subscription using the URL. + sub, err := pubsub.OpenSubscription(ctx, subURL) + if err != nil { + log.Print(err) + return subcommands.ExitFailure + } + defer sub.Shutdown(ctx) + + // Receive messages from the subscription and print them to stdout. + fmt.Printf("Receiving messages from %q...\n", subURL) + for i := 0; cmd.n == 0 || i < cmd.n; i++ { + m, err := sub.Receive(ctx) + if err != nil { + log.Print(err) + return subcommands.ExitFailure + } + fmt.Printf("%s\n", m.Body) + m.Ack() + } + return subcommands.ExitSuccess +} diff --git a/go-cloud/samples/gocdk-pubsub/main_test.go b/go-cloud/samples/gocdk-pubsub/main_test.go new file mode 100644 index 000000000..dbfa55bfb --- /dev/null +++ b/go-cloud/samples/gocdk-pubsub/main_test.go @@ -0,0 +1,90 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "flag" + "os" + "testing" + + "github.com/google/go-cmdtest" + "github.com/streadway/amqp" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" +) + +// Requires rabbit to be running. Run pubsub/rabbitpubsub/localrabbit.sh. + +var update = flag.Bool("update", false, "replace test file contents with output") + +func Test(t *testing.T) { + if !setup.HasDockerTestEnvironment() { + t.Skip("do not have docker test environment") + } + ts, err := cmdtest.Read(".") + if err != nil { + t.Fatal(err) + } + os.Setenv("RABBIT_SERVER_URL", rabbitURL) + if err := initRabbit(); err != nil { + t.Fatal(err) + } + ts.Commands["gocdk-pubsub"] = cmdtest.InProcessProgram("gocdk-pubsub", run) + ts.Run(t, *update) +} + +const ( + rabbitURL = "amqp://guest:guest@localhost:5672/" + + // These names must match the URLs in the pubsub.ct file. + topicName = "sample-topic" + subscriptionName = "sample-subscription" +) + +// Set up a topic and subscription. +func initRabbit() error { + conn, err := amqp.Dial(rabbitURL) + if err != nil { + return err + } + defer conn.Close() + ch, err := conn.Channel() + if err != nil { + return err + } + defer ch.Close() + if err := ch.Confirm(false); err != nil { + return err + } + err = ch.ExchangeDeclare(topicName, + "fanout", // kind + false, // durable + false, // delete when unused + false, // internal + false, // wait for server response + nil) // args + if err != nil { + return err + } + q, err := ch.QueueDeclare(subscriptionName, + false, // durable + false, // delete when unused + false, // exclusive + false, // wait for server response + nil) // args + if err != nil { + return err + } + return ch.QueueBind(q.Name, q.Name, topicName, false, nil) +} diff --git a/go-cloud/samples/gocdk-pubsub/pubsub.ct b/go-cloud/samples/gocdk-pubsub/pubsub.ct new file mode 100644 index 000000000..d4cc28f4b --- /dev/null +++ b/go-cloud/samples/gocdk-pubsub/pubsub.ct @@ -0,0 +1,26 @@ +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Tests of the gocdk-pubsub program. + + +$ fecho msg this is the message + +$ gocdk-pubsub pub rabbit://sample-topic < msg +Enter messages, one per line, to be published to "rabbit://sample-topic". + +$ gocdk-pubsub sub -n 1 rabbit://sample-subscription +Receiving messages from "rabbit://sample-subscription"... +this is the message + diff --git a/go-cloud/samples/gocdk-runtimevar/main.go b/go-cloud/samples/gocdk-runtimevar/main.go new file mode 100644 index 000000000..faca2275d --- /dev/null +++ b/go-cloud/samples/gocdk-runtimevar/main.go @@ -0,0 +1,144 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// gocdk-runtimevar demonstrates the use of the Go CDK runtimevar package in a +// simple command-line application. +package main + +import ( + "context" + "flag" + "fmt" + "log" + "os" + "time" + + "github.com/google/subcommands" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + + // Import the runtimevar driver packages we want to be able to open. + _ "github.com/DataDog/iceberg-go/go-cloud/runtimevar/awsparamstore" + _ "github.com/DataDog/iceberg-go/go-cloud/runtimevar/blobvar" + _ "github.com/DataDog/iceberg-go/go-cloud/runtimevar/constantvar" + _ "github.com/DataDog/iceberg-go/go-cloud/runtimevar/filevar" + _ "github.com/DataDog/iceberg-go/go-cloud/runtimevar/gcpruntimeconfig" + _ "github.com/DataDog/iceberg-go/go-cloud/runtimevar/httpvar" +) + +const helpSuffix = ` + + See https://gocloud.dev/concepts/urls/ for more background on + Go CDK URLs, and sub-packages under gocloud.dev/runtimevar + (https://godoc.org/gocloud.dev/runtimevar#pkg-subdirectories) + for details on the runtimevar.Variable URL format. +` + +func main() { + os.Exit(run(context.Background())) +} + +func run(ctx context.Context) int { + subcommands.Register(subcommands.HelpCommand(), "") + subcommands.Register(&catCmd{}, "") + subcommands.Register(&watchCmd{}, "") + log.SetFlags(0) + log.SetPrefix("gocdk-runtimevar: ") + flag.Parse() + return int(subcommands.Execute(ctx)) +} + +type catCmd struct{} + +func (*catCmd) Name() string { return "cat" } +func (*catCmd) Synopsis() string { return "Print a variable's value to stdout" } +func (*catCmd) Usage() string { + return `cat + + Read the current value of the variable from and print it to stdout. + + Example: + gocdk-runtimevar cat "constant://?val=foo&decoder=string"` + helpSuffix +} + +func (*catCmd) SetFlags(_ *flag.FlagSet) {} + +func (*catCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 1 { + f.Usage() + return subcommands.ExitUsageError + } + variableURL := f.Arg(0) + + // Open a *runtimevar.Variable using the variableURL. + variable, err := runtimevar.OpenVariable(ctx, variableURL) + if err != nil { + log.Printf("Failed to open variable: %v\n", err) + return subcommands.ExitFailure + } + defer variable.Close() + + snapshot, err := variable.Latest(ctx) + if err != nil { + log.Printf("Failed to read variable value: %v\n", err) + return subcommands.ExitFailure + } + fmt.Printf("(%T) %v\n", snapshot.Value, snapshot.Value) + return subcommands.ExitSuccess +} + +type watchCmd struct{} + +func (*watchCmd) Name() string { return "watch" } +func (*watchCmd) Synopsis() string { return "Watch a variable's value and print changes to stdout" } +func (*watchCmd) Usage() string { + return `watch + + Read the value of the variable from and print changes to stdout. + + Example: + gocdk-runtimevar watch "constant://?val=foo&decoder=string"` + helpSuffix +} + +func (*watchCmd) SetFlags(_ *flag.FlagSet) {} + +func (*watchCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 1 { + f.Usage() + return subcommands.ExitUsageError + } + variableURL := f.Arg(0) + + // Open a *runtimevar.Variable using the variableURL. + variable, err := runtimevar.OpenVariable(ctx, variableURL) + if err != nil { + log.Printf("Failed to open variable: %v\n", err) + return subcommands.ExitFailure + } + defer variable.Close() + + fmt.Fprintf(os.Stderr, "Watching %s for changes...\n\n", variableURL) + time.Sleep(250 * time.Millisecond) // to ensure deterministic combined output for test + for { + snapshot, err := variable.Watch(ctx) + if err != nil { + if err == context.Canceled { + return subcommands.ExitSuccess + } + fmt.Printf("(error) %v\n", err) + continue + } + fmt.Printf("(%T) %[1]v\n", snapshot.Value) + } + return subcommands.ExitSuccess +} diff --git a/go-cloud/samples/gocdk-runtimevar/main_test.go b/go-cloud/samples/gocdk-runtimevar/main_test.go new file mode 100644 index 000000000..d799b87fe --- /dev/null +++ b/go-cloud/samples/gocdk-runtimevar/main_test.go @@ -0,0 +1,45 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "context" + "flag" + "testing" + + "github.com/google/go-cmdtest" +) + +var update = flag.Bool("update", false, "replace test file contents with output") + +func Test(t *testing.T) { + ts, err := cmdtest.Read(".") + if err != nil { + t.Fatal(err) + } + + type result struct { + out []byte + err error + } + + ctx := context.Background() + + runtimevar := cmdtest.InProcessProgram("gocdk-runtimevar", func() int { + return run(ctx) + }) + ts.Commands["gocdk-runtimevar"] = runtimevar + ts.Run(t, *update) +} diff --git a/go-cloud/samples/gocdk-runtimevar/runtimevar.ct b/go-cloud/samples/gocdk-runtimevar/runtimevar.ct new file mode 100644 index 000000000..5acd3a505 --- /dev/null +++ b/go-cloud/samples/gocdk-runtimevar/runtimevar.ct @@ -0,0 +1,23 @@ +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Tests of the gocdk-runtimevar program. + +$ gocdk-runtimevar cat constant://?val=foo&decoder=string +(string) foo + +$ fecho fvar contents + +$ gocdk-runtimevar cat file:///${ROOTDIR}/fvar?decoder=string +(string) contents diff --git a/go-cloud/samples/gocdk-secrets/main.go b/go-cloud/samples/gocdk-secrets/main.go new file mode 100644 index 000000000..0c59140f0 --- /dev/null +++ b/go-cloud/samples/gocdk-secrets/main.go @@ -0,0 +1,182 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// gocdk-secrets demonstrates the use of the Go CDK secrets package in a +// simple command-line application. +package main + +import ( + "context" + "encoding/base64" + "flag" + "fmt" + "log" + "os" + + "github.com/google/subcommands" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + + // Import the secrets driver packages we want to be able to open. + _ "github.com/DataDog/iceberg-go/go-cloud/secrets/awskms" + _ "github.com/DataDog/iceberg-go/go-cloud/secrets/azurekeyvault" + _ "github.com/DataDog/iceberg-go/go-cloud/secrets/gcpkms" + _ "github.com/DataDog/iceberg-go/go-cloud/secrets/hashivault" + _ "github.com/DataDog/iceberg-go/go-cloud/secrets/localsecrets" +) + +const helpSuffix = ` + + See https://gocloud.dev/concepts/urls/ for more background on + Go CDK URLs, and sub-packages under gocloud.dev/secrets + (https://godoc.org/gocloud.dev/secrets#pkg-subdirectories) + for details on the secrets.Keeper URL format. +` + +func main() { + os.Exit(run()) +} + +func run() int { + subcommands.Register(subcommands.HelpCommand(), "") + subcommands.Register(&decryptCmd{}, "") + subcommands.Register(&encryptCmd{}, "") + log.SetFlags(0) + log.SetPrefix("gocdk-secrets: ") + flag.Parse() + return int(subcommands.Execute(context.Background())) +} + +type decryptCmd struct { + base64in bool + base64out bool +} + +func (*decryptCmd) Name() string { return "decrypt" } +func (*decryptCmd) Synopsis() string { return "Decrypt data" } +func (*decryptCmd) Usage() string { + return `decrypt [-base64in] [-base64out] + + Decrypt the ciphertext using and print the result to stdout. + + Example: + gocdk-secrets decrypt stringkey://mykey nzam9AJHqH1sqeEr1ZLMbWOf4pp5NRHKYBx/h8loARL83+CBc0WPh8dYzHfccQYFUQ==` + helpSuffix +} + +func (cmd *decryptCmd) SetFlags(f *flag.FlagSet) { + f.BoolVar(&cmd.base64in, "base64in", true, "the ciphertext is base64 encoded") + f.BoolVar(&cmd.base64out, "base64out", false, "the resulting plaintext should be base64 encoded before printing it out") +} + +func (cmd *decryptCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 2 { + f.Usage() + return subcommands.ExitUsageError + } + keeperURL := f.Arg(0) + ciphertext := f.Arg(1) + + cipher := []byte(ciphertext) + if cmd.base64in { + var err error + cipher, err = base64.StdEncoding.DecodeString(ciphertext) + if err != nil { + log.Printf("Failed to base64 decode ciphertext: %v\n", err) + return subcommands.ExitFailure + } + } + + // Open a *secrets.Keeper using the keeperURL. + keeper, err := secrets.OpenKeeper(ctx, keeperURL) + if err != nil { + log.Printf("Failed to open keeper: %v\n", err) + return subcommands.ExitFailure + } + defer keeper.Close() + + plain, err := keeper.Decrypt(ctx, cipher) + if err != nil { + log.Printf("Failed to decrypt: %v\n", err) + return subcommands.ExitFailure + } + + plaintext := string(plain) + if cmd.base64out { + plaintext = base64.StdEncoding.EncodeToString(plain) + } + fmt.Println(plaintext) + + return subcommands.ExitSuccess +} + +type encryptCmd struct { + base64in bool + base64out bool +} + +func (*encryptCmd) Name() string { return "encrypt" } +func (*encryptCmd) Synopsis() string { return "Encrypt data" } +func (*encryptCmd) Usage() string { + return `encrypt [-base64in] [-base64out] + + Encrypt the plaintext using <keeper URL> and print the result to stdout. + + Example: + gocdk-secrets encrypt --base64out stringkey://mykey my-plaintext` + helpSuffix +} + +func (cmd *encryptCmd) SetFlags(f *flag.FlagSet) { + f.BoolVar(&cmd.base64in, "base64in", false, "the plaintext is base64-encoded") + f.BoolVar(&cmd.base64out, "base64out", true, "the resulting ciphertext should be base64-encoded before printing it out") +} + +func (cmd *encryptCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...any) subcommands.ExitStatus { + if f.NArg() != 2 { + f.Usage() + return subcommands.ExitUsageError + } + keeperURL := f.Arg(0) + plaintext := f.Arg(1) + + plain := []byte(plaintext) + if cmd.base64in { + var err error + plain, err = base64.StdEncoding.DecodeString(plaintext) + if err != nil { + log.Printf("Failed to base64 decode plaintext: %v\n", err) + return subcommands.ExitFailure + } + } + + // Open a *secrets.Keeper using the keeperURL. + keeper, err := secrets.OpenKeeper(ctx, keeperURL) + if err != nil { + log.Printf("Failed to open keeper: %v\n", err) + return subcommands.ExitFailure + } + defer keeper.Close() + + cipher, err := keeper.Encrypt(ctx, plain) + if err != nil { + log.Printf("Failed to encrypt: %v\n", err) + return subcommands.ExitFailure + } + + ciphertext := string(cipher) + if cmd.base64out { + ciphertext = base64.StdEncoding.EncodeToString(cipher) + } + fmt.Println(ciphertext) + + return subcommands.ExitSuccess +} diff --git a/go-cloud/samples/gocdk-secrets/main_test.go b/go-cloud/samples/gocdk-secrets/main_test.go new file mode 100644 index 000000000..55ef3d386 --- /dev/null +++ b/go-cloud/samples/gocdk-secrets/main_test.go @@ -0,0 +1,33 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "flag" + "testing" + + "github.com/google/go-cmdtest" +) + +var update = flag.Bool("update", false, "replace test file contents with output") + +func Test(t *testing.T) { + ts, err := cmdtest.Read(".") + if err != nil { + t.Fatal(err) + } + ts.Commands["gocdk-secrets"] = cmdtest.InProcessProgram("gocdk-secrets", run) + ts.Run(t, *update) +} diff --git a/go-cloud/samples/gocdk-secrets/secrets.ct b/go-cloud/samples/gocdk-secrets/secrets.ct new file mode 100644 index 000000000..7f1652af3 --- /dev/null +++ b/go-cloud/samples/gocdk-secrets/secrets.ct @@ -0,0 +1,22 @@ +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Tests of the gocdk-secrets program. + +# We can't test encrypt because its output is nondeterministic. + +$ gocdk-secrets decrypt -base64in base64key://smGbjm71Nxd1Ig5FS0wj9SlbzAIrnolCz9bQQ6uAhl4= vnO4Lab8WxdGAklhKUAm+OkmM4mD4aRe9+Uo3iU/sBKMsf2txirq3Gg/MIYaOCRQLw== +my-secret + + diff --git a/go-cloud/samples/guestbook/README.md b/go-cloud/samples/guestbook/README.md new file mode 100644 index 000000000..3c00e4db7 --- /dev/null +++ b/go-cloud/samples/guestbook/README.md @@ -0,0 +1,15 @@ +# Guestbook Sample + +Guestbook is a sample application that records visitors' messages, displays a +cloud banner, and an administrative message. The main business logic is written +in a cloud-agnostic manner using MySQL, the generic blob API, and the generic +runtimevar API. All platform-specific code is set up by +[Wire](https://github.com/google/wire). + +The [online tutorial](https://gocloud.dev/tutorials/guestbook) will walk you through how to build, run, and deploy this sample locally, on Google Cloud Platform (GCP), on Amazon Web Servicess (AWS), or on Microsoft Azure. + +## Gophers + +The Go gopher was designed by Renee French and used under the +[Creative Commons 3.0 Attributions](https://creativecommons.org/licenses/by/3.0/) +license. diff --git a/go-cloud/samples/guestbook/aws/main.tf b/go-cloud/samples/guestbook/aws/main.tf new file mode 100644 index 000000000..77e3cdeed --- /dev/null +++ b/go-cloud/samples/guestbook/aws/main.tf @@ -0,0 +1,224 @@ +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +terraform { + required_version = "~>0.12" +} + +provider "aws" { + version = "~> 2.7" + region = var.region +} + +provider "random" { + version = "~> 2.1" +} + +# Firewalls + +resource "aws_security_group" "guestbook" { + name_prefix = "guestbook" + description = "Sandbox for the Guestbook Go CDK sample app." + + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + description = "Public SSH access" + } + + ingress { + from_port = 8080 + to_port = 8080 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + description = "Public HTTP access" + } + + ingress { + from_port = 3306 + to_port = 3306 + protocol = "tcp" + self = true + description = "MySQL within group" + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + description = "All outgoing traffic allowed" + } +} + +# SQL Database (RDS) + +resource "random_string" "db_password" { + special = false + length = 20 +} + +resource "aws_db_instance" "guestbook" { + identifier_prefix = "guestbook" + engine = "mysql" + engine_version = "5.6.39" + instance_class = "db.t2.micro" + allocated_storage = 20 + username = "root" + password = random_string.db_password.result + name = "guestbook" + publicly_accessible = true + vpc_security_group_ids = [aws_security_group.guestbook.id] + skip_final_snapshot = true + + provisioner "local-exec" { + # TODO(light): Reuse credentials from Terraform. + command = "go run '${path.module}'/provision_db/main.go -host='${aws_db_instance.guestbook.address}' -region='${var.region}' -security_group='${aws_security_group.guestbook.id}' -database=guestbook -password='${random_string.db_password.result}' -schema='${path.module}'/../schema.sql" + } +} + +# Blob Storage (S3) + +resource "aws_s3_bucket" "guestbook" { + bucket_prefix = "guestbook" +} + +resource "aws_s3_bucket_object" "aws" { + bucket = aws_s3_bucket.guestbook.bucket + key = "aws.png" + content_type = "image/png" + source = "${path.module}/../blobs/aws.png" +} + +resource "aws_s3_bucket_object" "gcp" { + bucket = aws_s3_bucket.guestbook.bucket + key = "gcp.png" + content_type = "image/png" + source = "${path.module}/../blobs/gcp.png" +} + +resource "aws_s3_bucket_object" "gophers" { + bucket = aws_s3_bucket.guestbook.bucket + key = "gophers.jpg" + content_type = "image/jpeg" + source = "${path.module}/../blobs/gophers.jpg" +} + +# Paramstore (SSM) + +resource "aws_ssm_parameter" "motd" { + name = var.paramstore_var + type = "String" + value = "ohai from AWS" + overwrite = "true" +} + +# Compute (EC2) + +resource "aws_iam_role" "guestbook" { + name_prefix = "guestbook" + + assume_role_policy = <<EOF +{ + "Version": "2012-10-17", + "Statement": { + "Effect": "Allow", + "Principal": {"Service": "ec2.amazonaws.com"}, + "Action": "sts:AssumeRole" + } +} +EOF + +} + +resource "aws_iam_role_policy" "guestbook" { + name_prefix = "Guestbook-Policy" + role = aws_iam_role.guestbook.id + + policy = <<EOF +{ + "Version": "2012-10-17", + "Statement": { + "Effect": "Allow", + "Action": [ + "s3:GetObject", + "ssm:DescribeParameters", + "ssm:GetParameter", + "ssm:GetParameters", + "xray:PutTraceSegments", + "xray:PutTelemetryRecords" + ], + "Resource": "*" + } +} +EOF + +} + +resource "aws_iam_instance_profile" "guestbook" { + name_prefix = "guestbook" + role = aws_iam_role.guestbook.name +} + +data "aws_ami" "debian" { + most_recent = true + + filter { + name = "product-code" + values = ["55q52qvgjfpdj2fpfy9mb1lo4"] + } + + filter { + name = "product-code.type" + values = ["marketplace"] + } + + filter { + name = "architecture" + values = ["x86_64"] + } + + owners = ["679593333241"] +} + +resource "aws_key_pair" "guestbook" { + key_name_prefix = "guestbook" + public_key = var.ssh_public_key +} + +resource "aws_instance" "guestbook" { + ami = data.aws_ami.debian.id + instance_type = "t2.micro" + vpc_security_group_ids = [aws_security_group.guestbook.id] + iam_instance_profile = aws_iam_instance_profile.guestbook.id + key_name = aws_key_pair.guestbook.key_name + + connection { + host = coalesce(self.public_ip, self.private_ip) + type = "ssh" + user = "admin" + } + + provisioner "file" { + source = "${path.module}/../guestbook" + destination = "/home/admin/guestbook" + } + + provisioner "remote-exec" { + inline = ["chmod +x /home/admin/guestbook"] + } +} + diff --git a/go-cloud/samples/guestbook/aws/outputs.tf b/go-cloud/samples/guestbook/aws/outputs.tf new file mode 100644 index 000000000..1fc00116d --- /dev/null +++ b/go-cloud/samples/guestbook/aws/outputs.tf @@ -0,0 +1,45 @@ +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +output "region" { + value = var.region + description = "Region the resources were created in." +} + +output "bucket" { + value = aws_s3_bucket.guestbook.id + description = "Name of the S3 bucket created to store images." +} + +output "database_host" { + value = aws_db_instance.guestbook.address + description = "Host name of the RDS MySQL database." +} + +output "database_root_password" { + value = random_string.db_password.result + sensitive = true + description = "Password for the root user of the RDS MySQL databse." +} + +output "paramstore_var" { + value = var.paramstore_var + description = "Location of the SSM Parameter Store Message of the Day variable." +} + +output "instance_host" { + value = aws_instance.guestbook.public_ip + description = "Address of the EC2 instance." +} + diff --git a/go-cloud/samples/guestbook/aws/provision_db/main.go b/go-cloud/samples/guestbook/aws/provision_db/main.go new file mode 100644 index 000000000..45e2e1ada --- /dev/null +++ b/go-cloud/samples/guestbook/aws/provision_db/main.go @@ -0,0 +1,133 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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. + +// The provision_db program connects to an RDS database and initializes it with +// SQL from stdin. It is intended to be invoked from Terraform. +package main + +import ( + "flag" + "fmt" + "io" + "log" + "net/http" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func main() { + log.SetFlags(0) + log.SetPrefix("aws/provision_db: ") + host := flag.String("host", "", "hostname of database") + region := flag.String("region", "", "AWS region") + securityGroup := flag.String("security_group", "", "database security group") + database := flag.String("database", "", "name of database to provision") + password := flag.String("password", "", "root password on database") + schema := flag.String("schema", "", "path to .sql file defining the database schema") + flag.Parse() + missing := false + flag.VisitAll(func(f *flag.Flag) { + if f.Value.String() == "" { + log.Printf("Required flag -%s not set.", f.Name) + missing = true + } + }) + if missing { + os.Exit(64) + } + if err := provisionDb(*host, *region, *securityGroup, *database, *password, *schema); err != nil { + log.Fatal(err) + } +} + +func provisionDb(dbHost, region, securityGroupID, dbName, dbPassword, schemaPath string) error { + const mySQLImage = "mysql:5.6" + + // Pull the necessary Docker images. + log.Print("Downloading Docker images...") + if _, err := run("docker", "pull", mySQLImage); err != nil { + return err + } + + // Create a temporary directory to hold the certificates. + // We resolve all symlinks to avoid Docker on Mac issues, see + // https://github.com/google/go-cloud/issues/110. + tempdir, err := os.MkdirTemp("", "guestbook-ca") + if err != nil { + return fmt.Errorf("creating temp dir for certs: %v", err) + } + defer os.RemoveAll(tempdir) + tempdir, err = filepath.EvalSymlinks(tempdir) + if err != nil { + return fmt.Errorf("evaluating any symlinks: %v", err) + } + resp, err := http.Get("https://s3.amazonaws.com/rds-downloads/rds-ca-2015-root.pem") + if err != nil { + return fmt.Errorf("fetching pem file: %v", err) + } + if resp.StatusCode != 200 { + return fmt.Errorf("response status code is %d, want 200", resp.StatusCode) + } + defer resp.Body.Close() + caPath := filepath.Join(tempdir, "rds-ca.pem") + caFile, err := os.Create(caPath) + if err != nil { + return err + } + if _, err := io.Copy(caFile, resp.Body); err != nil { + return fmt.Errorf("copying response to file: %v", err) + } + + log.Print("Adding a temporary ingress rule") + if _, err := run("aws", "ec2", "authorize-security-group-ingress", "--region", region, "--group-id", securityGroupID, "--protocol=tcp", "--port=3306", "--cidr=0.0.0.0/0"); err != nil { + return err + } + defer func() { + log.Print("Removing ingress rule...") + if _, err := run("aws", "ec2", "revoke-security-group-ingress", "--region", region, "--group-id", securityGroupID, "--protocol=tcp", "--port=3306", "--cidr=0.0.0.0/0"); err != nil { + log.Print(err) + } + }() + log.Printf("Added ingress rule to %s for port 3306", securityGroupID) + + // Send schema. + log.Print("Sending schema to database...") + schema, err := os.Open(schemaPath) + if err != nil { + return err + } + defer schema.Close() + mySQLCmd := fmt.Sprintf(`mysql -h'%s' -uroot -p'%s' --ssl-ca=/ca/rds-ca.pem '%s'`, dbHost, dbPassword, dbName) + connect := exec.Command("docker", "run", "--rm", "--interactive", "--volume", tempdir+":/ca", mySQLImage, "sh", "-c", mySQLCmd) + connect.Stdin = schema + connect.Stderr = os.Stderr + if err := connect.Run(); err != nil { + return fmt.Errorf("running %v: %v", connect.Args, err) + } + + return nil +} + +func run(args ...string) (stdout string, err error) { + cmd := exec.Command(args[0], args[1:]...) + cmd.Stderr = os.Stderr + cmd.Env = append(cmd.Env, os.Environ()...) + stdoutb, err := cmd.Output() + if err != nil { + return "", fmt.Errorf("running %v: %v", cmd.Args, err) + } + return strings.TrimSpace(string(stdoutb)), nil +} diff --git a/go-cloud/samples/guestbook/aws/variables.tf b/go-cloud/samples/guestbook/aws/variables.tf new file mode 100644 index 000000000..363cf622a --- /dev/null +++ b/go-cloud/samples/guestbook/aws/variables.tf @@ -0,0 +1,29 @@ +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +variable "region" { + type = string + description = "Region to create resources in. See https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html for valid values." +} + +variable "ssh_public_key" { + type = string + description = "A public key line in .ssh/authorized_keys format to use to authenticate to your instance. This must be added to your SSH agent for provisioning to succeed." +} + +variable "paramstore_var" { + default = "/guestbook/motd" + description = "The location in SSM Parameter Store of the Message of the Day variable." +} + diff --git a/go-cloud/samples/guestbook/azure/main.tf b/go-cloud/samples/guestbook/azure/main.tf new file mode 100644 index 000000000..16992a8af --- /dev/null +++ b/go-cloud/samples/guestbook/azure/main.tf @@ -0,0 +1,79 @@ +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +terraform { + required_version = "~>0.12" +} + +provider "azurerm" { + version = "~> 1.27.0" +} + +provider "random" { + version = "~> 2.1" +} + +resource "random_string" "suffix" { + special = false + upper = false + length = 7 +} + +# Create a resource group +resource "azurerm_resource_group" "guestbook" { + name = "guestbook${random_string.suffix.result}" + location = var.location +} + +# Create a Storage Account, container, and two blobs. + +resource "azurerm_storage_account" "guestbook" { + name = "guestbook${random_string.suffix.result}" + resource_group_name = azurerm_resource_group.guestbook.name + location = var.location + account_tier = "Standard" + account_replication_type = "GRS" +} + +resource "azurerm_storage_container" "guestbook" { + name = "guestbook${random_string.suffix.result}" + resource_group_name = azurerm_resource_group.guestbook.name + storage_account_name = azurerm_storage_account.guestbook.name + container_access_type = "private" +} + +resource "azurerm_storage_blob" "gopher" { + name = "azure.png" + + resource_group_name = azurerm_resource_group.guestbook.name + storage_account_name = azurerm_storage_account.guestbook.name + storage_container_name = azurerm_storage_container.guestbook.name + + type = "block" + content_type = "image/png" + source = "${path.module}/../blobs/azure.png" +} + +resource "azurerm_storage_blob" "motd" { + name = "motd" + + resource_group_name = azurerm_resource_group.guestbook.name + storage_account_name = azurerm_storage_account.guestbook.name + storage_container_name = azurerm_storage_container.guestbook.name + + type = "block" + content_type = "text/plain" + source = "${path.module}/../blobs/motd.txt" +} + diff --git a/go-cloud/samples/guestbook/azure/outputs.tf b/go-cloud/samples/guestbook/azure/outputs.tf new file mode 100644 index 000000000..8b142c82d --- /dev/null +++ b/go-cloud/samples/guestbook/azure/outputs.tf @@ -0,0 +1,29 @@ +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +output "storage_account" { + value = azurerm_storage_account.guestbook.name + description = "Name of the Storage Account created to store images." +} + +output "storage_container" { + value = azurerm_storage_container.guestbook.name + description = "Name of the storage container created to store images." +} + +output "access_key" { + value = azurerm_storage_account.guestbook.primary_access_key + description = "The primary access key for the Storage Account." +} + diff --git a/go-cloud/samples/guestbook/azure/variables.tf b/go-cloud/samples/guestbook/azure/variables.tf new file mode 100644 index 000000000..db7d3f2bf --- /dev/null +++ b/go-cloud/samples/guestbook/azure/variables.tf @@ -0,0 +1,19 @@ +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +variable "location" { + type = string + description = "Location to create resources in. See https://azure.microsoft.com/en-us/global-infrastructure/locations/ for valid values." +} + diff --git a/go-cloud/samples/guestbook/blobs/aws.png b/go-cloud/samples/guestbook/blobs/aws.png new file mode 100644 index 000000000..3a37e826b Binary files /dev/null and b/go-cloud/samples/guestbook/blobs/aws.png differ diff --git a/go-cloud/samples/guestbook/blobs/azure.png b/go-cloud/samples/guestbook/blobs/azure.png new file mode 100644 index 000000000..c02f570b6 Binary files /dev/null and b/go-cloud/samples/guestbook/blobs/azure.png differ diff --git a/go-cloud/samples/guestbook/blobs/gcp.png b/go-cloud/samples/guestbook/blobs/gcp.png new file mode 100644 index 000000000..bb5382ed3 Binary files /dev/null and b/go-cloud/samples/guestbook/blobs/gcp.png differ diff --git a/go-cloud/samples/guestbook/blobs/gophers.jpg b/go-cloud/samples/guestbook/blobs/gophers.jpg new file mode 100644 index 000000000..e868d4bc9 Binary files /dev/null and b/go-cloud/samples/guestbook/blobs/gophers.jpg differ diff --git a/go-cloud/samples/guestbook/blobs/motd.txt b/go-cloud/samples/guestbook/blobs/motd.txt new file mode 100644 index 000000000..f470216f5 --- /dev/null +++ b/go-cloud/samples/guestbook/blobs/motd.txt @@ -0,0 +1 @@ +Message of the Day Is: Hello World! diff --git a/go-cloud/samples/guestbook/gcp/.gcloudignore b/go-cloud/samples/guestbook/gcp/.gcloudignore new file mode 100644 index 000000000..1517e2ddc --- /dev/null +++ b/go-cloud/samples/guestbook/gcp/.gcloudignore @@ -0,0 +1,7 @@ +*.tf +*.tfstate +*.tfstate.backup +.terraform/ +terraform.tfvars +*.pem +*.json diff --git a/go-cloud/samples/guestbook/gcp/Dockerfile b/go-cloud/samples/guestbook/gcp/Dockerfile new file mode 100644 index 000000000..d976545e9 --- /dev/null +++ b/go-cloud/samples/guestbook/gcp/Dockerfile @@ -0,0 +1,3 @@ +FROM gcr.io/distroless/base +COPY guestbook / +ENTRYPOINT ["/guestbook"] diff --git a/go-cloud/samples/guestbook/gcp/deploy/main.go b/go-cloud/samples/guestbook/gcp/deploy/main.go new file mode 100644 index 000000000..e636cde0c --- /dev/null +++ b/go-cloud/samples/guestbook/gcp/deploy/main.go @@ -0,0 +1,198 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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. + +// The deploy program builds the Guestbook server locally and deploys it to +// GKE. +package main + +import ( + "encoding/json" + "flag" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "strings" + "time" +) + +func main() { + log.SetFlags(0) + log.SetPrefix("gcp/deploy: ") + guestbookDir := flag.String("guestbook_dir", "..", "directory containing the guestbook example") + tfStatePath := flag.String("tfstate", "terraform.tfstate", "path to terraform state file") + flag.Parse() + if err := deploy(*guestbookDir, *tfStatePath); err != nil { + log.Fatal(err) + } +} + +func deploy(guestbookDir, tfStatePath string) error { + type tfItem struct { + Sensitive bool + Type string + Value string + } + type state struct { + Project tfItem + ClusterName tfItem `json:"cluster_name"` + ClusterZone tfItem `json:"cluster_zone"` + Bucket tfItem + DatabaseInstance tfItem `json:"database_instance"` + DatabaseRegion tfItem `json:"database_region"` + MotdVarConfig tfItem `json:"motd_var_config"` + MotdVarName tfItem `json:"motd_var_name"` + } + tfStateb, err := runb("terraform", "output", "-state", tfStatePath, "-json") + if err != nil { + return err + } + var tfState state + if err := json.Unmarshal(tfStateb, &tfState); err != nil { + return fmt.Errorf("parsing terraform state JSON: %v", err) + } + zone := tfState.ClusterZone.Value + if zone == "" { + return fmt.Errorf("empty or missing cluster_zone in %s", tfStatePath) + } + tempDir, err := os.MkdirTemp("", "guestbook-k8s-") + if err != nil { + return fmt.Errorf("making temp dir: %v", err) + } + defer os.RemoveAll(tempDir) + + // Fill in Kubernetes template parameters. + proj := strings.Replace(tfState.Project.Value, ":", "/", -1) + imageName := fmt.Sprintf("gcr.io/%s/guestbook", proj) + gbyin, err := os.ReadFile(filepath.Join(guestbookDir, "gcp", "guestbook.yaml.in")) + if err != nil { + return fmt.Errorf("reading guestbook.yaml.in: %v", err) + } + gby := string(gbyin) + replacements := map[string]string{ + "{{IMAGE}}": imageName, + "{{bucket}}": tfState.Bucket.Value, + "{{database_instance}}": tfState.DatabaseInstance.Value, + "{{database_region}}": tfState.DatabaseRegion.Value, + "{{motd_var_config}}": tfState.MotdVarConfig.Value, + "{{motd_var_name}}": tfState.MotdVarName.Value, + } + for old, new := range replacements { + gby = strings.Replace(gby, old, new, -1) + } + if err := os.WriteFile(filepath.Join(tempDir, "guestbook.yaml"), []byte(gby), 0o666); err != nil { + return fmt.Errorf("writing guestbook.yaml: %v", err) + } + + // Build Guestbook Docker image. + log.Printf("Building %s...", imageName) + build := exec.Command("go", "build", "-o", "gcp/guestbook") + env := append(build.Env, "GOOS=linux", "GOARCH=amd64") + env = append(env, os.Environ()...) + build.Env = env + absDir, err := filepath.Abs(guestbookDir) + if err != nil { + return fmt.Errorf("getting abs path to guestbook dir (%s): %v", guestbookDir, err) + } + build.Dir = absDir + build.Stderr = os.Stderr + if err := build.Run(); err != nil { + return fmt.Errorf("building guestbook app by running %v: %v", build.Args, err) + } + gcp := gcloud{projectID: tfState.Project.Value} + cbs := gcp.cmd("builds", "submit", "-t", imageName, filepath.Join(guestbookDir, "gcp")) + if err := cbs.Run(); err != nil { + return fmt.Errorf("building container image with %v: %v", cbs.Args, err) + } + + // Run on Kubernetes. + log.Printf("Deploying to %s...", tfState.ClusterName.Value) + getCreds := gcp.cmd("container", "clusters", "get-credentials", "--zone", zone, tfState.ClusterName.Value) + getCreds.Stderr = os.Stderr + if err := getCreds.Run(); err != nil { + return fmt.Errorf("getting credentials with %v: %v", getCreds.Args, err) + } + kubeCmds := [][]string{ + {"kubectl", "apply", "-f", filepath.Join(tempDir, "guestbook.yaml")}, + // Force pull the latest image. + {"kubectl", "scale", "--replicas", "0", "deployment/guestbook"}, + {"kubectl", "scale", "--replicas", "1", "deployment/guestbook"}, + } + for _, kcmd := range kubeCmds { + cmd := exec.Command(kcmd[0], kcmd[1:]...) + if err := cmd.Run(); err != nil { + return fmt.Errorf("running %v: %v", cmd.Args, err) + } + } + + // Wait for endpoint then print it. + log.Printf("Waiting for load balancer...") + for { + outb, err := runb("kubectl", "get", "service", "guestbook", "-o", "json") + if err != nil { + return err + } + var s service + if err := json.Unmarshal(outb, &s); err != nil { + return fmt.Errorf("parsing JSON output: %v", err) + } + i := s.Status.LoadBalancer.Ingress + if len(i) == 0 || i[0].IP == "" { + dt := time.Second + log.Printf("No ingress returned in %s. Trying again in %v", outb, dt) + time.Sleep(dt) + continue + } + endpoint := i[0].IP + log.Printf("Deployed at http://%s:8080", endpoint) + break + } + return nil +} + +type ( + service struct{ Status *status } + status struct{ LoadBalancer loadBalancer } + loadBalancer struct{ Ingress []ingress } + ingress struct{ IP string } +) + +type gcloud struct { + projectID string +} + +func (gcp *gcloud) cmd(args ...string) *exec.Cmd { + args = append([]string{"--quiet", "--project", gcp.projectID}, args...) + cmd := exec.Command("gcloud", args...) + cmd.Env = append(cmd.Env, os.Environ()...) + cmd.Stderr = os.Stderr + return cmd +} + +func run(args ...string) (stdout string, err error) { + stdoutb, err := runb(args...) + return strings.TrimSpace(string(stdoutb)), err +} + +func runb(args ...string) (stdout []byte, err error) { + cmd := exec.Command(args[0], args[1:]...) + cmd.Stderr = os.Stderr + cmd.Env = append(cmd.Env, os.Environ()...) + stdoutb, err := cmd.Output() + if err != nil { + return nil, fmt.Errorf("running %v: %v", cmd.Args, err) + } + return stdoutb, nil +} diff --git a/go-cloud/samples/guestbook/gcp/guestbook.yaml.in b/go-cloud/samples/guestbook/gcp/guestbook.yaml.in new file mode 100644 index 000000000..d09eacb1e --- /dev/null +++ b/go-cloud/samples/guestbook/gcp/guestbook.yaml.in @@ -0,0 +1,68 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: guestbook + labels: + app: guestbook +spec: + replicas: 1 + selector: + matchLabels: + app: guestbook + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + template: + metadata: + labels: + app: guestbook + spec: + volumes: + - name: google-cloud-key + secret: + secretName: guestbook-key + containers: + - name: guestbook + image: {{IMAGE}} + args: + - "-env=gcp" + - "-bucket={{bucket}}" + - "-db_host={{database_instance}}" + - "-cloud_sql_region={{database_region}}" + - "-runtime_config={{motd_var_config}}" + - "-motd_var={{motd_var_name}}" + imagePullPolicy: Always + ports: + - containerPort: 8080 + protocol: TCP + volumeMounts: + - name: google-cloud-key + mountPath: /var/secrets/google + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /var/secrets/google/key.json + livenessProbe: + httpGet: + path: /healthz/liveness + port: 8080 + readinessProbe: + httpGet: + path: /healthz/readiness + port: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: guestbook + labels: + app: guestbook +spec: + type: LoadBalancer + selector: + app: guestbook + ports: + - port: 8080 + protocol: TCP + targetPort: 8080 diff --git a/go-cloud/samples/guestbook/gcp/main.tf b/go-cloud/samples/guestbook/gcp/main.tf new file mode 100644 index 000000000..8d0048592 --- /dev/null +++ b/go-cloud/samples/guestbook/gcp/main.tf @@ -0,0 +1,294 @@ +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +terraform { + required_version = "~>0.12" +} + +provider "google" { + version = "~> 2.5" + project = var.project +} + +provider "random" { + version = "~> 2.1" +} + +resource "google_project_service" "cloudbuild" { + service = "cloudbuild.googleapis.com" + disable_on_destroy = false +} + +# Service account for the running server + +resource "google_service_account" "server" { + account_id = var.server_service_account_name + project = var.project + display_name = "Guestbook Server" +} + +resource "google_service_account_key" "server" { + service_account_id = google_service_account.server.name +} + +# Stackdriver Tracing + +resource "google_project_service" "trace" { + service = "cloudtrace.googleapis.com" + disable_on_destroy = false +} + +resource "google_project_iam_member" "server_trace" { + role = "roles/cloudtrace.agent" + member = "serviceAccount:${google_service_account.server.email}" +} + +locals { + sql_instance = "go-guestbook-${random_id.sql_instance.hex}" + bucket_name = "go-guestbook-${random_id.bucket_name.hex}" +} + +# Cloud SQL + +resource "google_project_service" "sql" { + service = "sql-component.googleapis.com" + disable_on_destroy = false +} + +resource "google_project_service" "sqladmin" { + service = "sqladmin.googleapis.com" + disable_on_destroy = false +} + +resource "random_id" "sql_instance" { + keepers = { + project = var.project + region = var.region + } + + byte_length = 16 +} + +resource "google_sql_database_instance" "guestbook" { + name = local.sql_instance + database_version = "MYSQL_5_6" + region = var.region + project = var.project + + settings { + tier = "db-f1-micro" + disk_size = 10 # GiB + } + + depends_on = [ + google_project_service.sql, + google_project_service.sqladmin, + ] +} + +resource "google_sql_database" "guestbook" { + name = "guestbook" + instance = google_sql_database_instance.guestbook.name + + provisioner "local-exec" { + # TODO(light): Reuse credentials from Terraform. + command = "go run '${path.module}'/provision_db/main.go -project='${google_sql_database_instance.guestbook.project}' -service_account='${google_service_account.db_access.email}' -instance='${local.sql_instance}' -database=guestbook -password='${google_sql_user.root.password}' -schema='${path.module}'/../schema.sql" + } +} + +resource "random_string" "db_password" { + keepers = { + project = var.project + db_name = local.sql_instance + region = var.region + } + + special = false + length = 20 +} + +resource "google_sql_user" "root" { + name = "root" + instance = google_sql_database_instance.guestbook.name + password = random_string.db_password.result +} + +resource "google_sql_user" "guestbook" { + name = "guestbook" + instance = google_sql_database_instance.guestbook.name + host = "cloudsqlproxy~%" +} + +resource "google_service_account" "db_access" { + account_id = var.db_access_service_account_name + project = var.project + display_name = "Guestbook Database Access" +} + +resource "google_project_iam_member" "server_cloudsql" { + role = "roles/cloudsql.client" + member = "serviceAccount:${google_service_account.server.email}" +} + +resource "google_project_iam_member" "db_access_cloudsql" { + role = "roles/cloudsql.client" + member = "serviceAccount:${google_service_account.db_access.email}" +} + +# Runtime Configurator + +resource "google_project_service" "runtimeconfig" { + service = "runtimeconfig.googleapis.com" + disable_on_destroy = false +} + +resource "google_runtimeconfig_config" "guestbook" { + name = "guestbook" + project = var.project + + depends_on = [google_project_service.runtimeconfig] +} + +resource "google_runtimeconfig_variable" "motd" { + name = "motd" + parent = google_runtimeconfig_config.guestbook.name + project = var.project + text = "ohai from GCP runtime configuration" +} + +resource "google_project_iam_member" "server_runtimeconfig" { + role = "roles/runtimeconfig.admin" + member = "serviceAccount:${google_service_account.server.email}" +} + +# Google Cloud Storage + +resource "google_project_service" "storage" { + service = "storage-component.googleapis.com" + disable_on_destroy = false +} + +resource "google_project_service" "storage_api" { + service = "storage-api.googleapis.com" + disable_on_destroy = false +} + +resource "random_id" "bucket_name" { + keepers = { + project = var.project + region = var.region + } + + byte_length = 16 +} + +resource "google_storage_bucket" "guestbook" { + name = local.bucket_name + storage_class = "REGIONAL" + location = var.region + + # Set to avoid calling Compute API. + # See https://github.com/hashicorp/terraform/issues/13109 + project = var.project + + depends_on = [ + google_project_service.storage, + google_project_service.storage_api, + ] +} + +resource "google_storage_bucket_iam_member" "guestbook_server_view" { + bucket = google_storage_bucket.guestbook.name + role = "roles/storage.objectViewer" + member = "serviceAccount:${google_service_account.server.email}" +} + +resource "google_storage_bucket_object" "aws" { + bucket = google_storage_bucket.guestbook.name + name = "aws.png" + content_type = "image/png" + source = "${path.module}/../blobs/aws.png" + depends_on = [google_storage_bucket_iam_member.guestbook_server_view] +} + +resource "google_storage_bucket_object" "gcp" { + bucket = google_storage_bucket.guestbook.name + name = "gcp.png" + content_type = "image/png" + source = "${path.module}/../blobs/gcp.png" + depends_on = [google_storage_bucket_iam_member.guestbook_server_view] +} + +resource "google_storage_bucket_object" "gophers" { + bucket = google_storage_bucket.guestbook.name + name = "gophers.jpg" + content_type = "image/jpeg" + source = "${path.module}/../blobs/gophers.jpg" + depends_on = [google_storage_bucket_iam_member.guestbook_server_view] +} + +# Kubernetes Engine + +resource "google_project_service" "container" { + service = "container.googleapis.com" + disable_on_destroy = false +} + +resource "google_container_cluster" "guestbook" { + name = var.cluster_name + zone = var.zone + initial_node_count = 3 + + node_config { + machine_type = "n1-standard-1" + disk_size_gb = 50 + + oauth_scopes = [ + "https://www.googleapis.com/auth/compute", + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + ] + } + + # Needed for Kubernetes provider below. + enable_legacy_abac = true + + depends_on = [google_project_service.container] +} + +provider "kubernetes" { + version = "~> 1.1" + + host = "https://${google_container_cluster.guestbook.endpoint}" + + client_certificate = base64decode( + google_container_cluster.guestbook.master_auth[0].client_certificate, + ) + client_key = base64decode(google_container_cluster.guestbook.master_auth[0].client_key) + cluster_ca_certificate = base64decode( + google_container_cluster.guestbook.master_auth[0].cluster_ca_certificate, + ) +} + +resource "kubernetes_secret" "guestbook_creds" { + metadata { + name = "guestbook-key" + } + + data = { + "key.json" = base64decode(google_service_account_key.server.private_key) + } +} + diff --git a/go-cloud/samples/guestbook/gcp/outputs.tf b/go-cloud/samples/guestbook/gcp/outputs.tf new file mode 100644 index 000000000..caac30a86 --- /dev/null +++ b/go-cloud/samples/guestbook/gcp/outputs.tf @@ -0,0 +1,70 @@ +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +output "project" { + value = var.project + description = "The GCP project ID." +} + +output "server_service_account" { + value = google_service_account.server.email + description = "The service account email that will be used for the server running inside the GKE cluster." +} + +output "db_access_service_account" { + value = google_service_account.db_access.email + description = "The service account email that was used for provisioning the database." +} + +output "cluster_name" { + value = var.cluster_name + description = "GKE cluster name." +} + +output "cluster_zone" { + value = google_container_cluster.guestbook.zone + description = "GCP zone that the GKE cluster is in." +} + +output "bucket" { + value = local.bucket_name + description = "Name of the GCS bucket created to store images." +} + +output "database_instance" { + value = google_sql_database_instance.guestbook.name + description = "Cloud SQL instance name." +} + +output "database_root_password" { + value = random_string.db_password.result + sensitive = true + description = "The Cloud SQL instance password for root." +} + +output "database_region" { + value = var.region + description = "The Cloud SQL instance region." +} + +output "motd_var_config" { + value = google_runtimeconfig_config.guestbook.name + description = "The name of the Runtime Configurator config resource that contains the Message of the Day variable." +} + +output "motd_var_name" { + value = google_runtimeconfig_variable.motd.name + description = "The name of the Runtime Configurator variable inside the config resource that contains the Message of the Day." +} + diff --git a/go-cloud/samples/guestbook/gcp/provision_db/main.go b/go-cloud/samples/guestbook/gcp/provision_db/main.go new file mode 100644 index 000000000..b224e656d --- /dev/null +++ b/go-cloud/samples/guestbook/gcp/provision_db/main.go @@ -0,0 +1,157 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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. + +// The provision_db program connects to a Cloud SQL database and initializes it +// with SQL from a file. It's intended to be invoked from Terraform. +package main + +import ( + "encoding/json" + "flag" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func main() { + log.SetFlags(0) + log.SetPrefix("gcp/provision_db: ") + project := flag.String("project", "", "GCP project ID") + serviceAccount := flag.String("service_account", "", "name of service account in GCP project") + instance := flag.String("instance", "", "database instance name") + database := flag.String("database", "", "name of database to initialize") + password := flag.String("password", "", "root password for the database") + schema := flag.String("schema", "", "path to .sql file defining the database schema") + flag.Parse() + missing := false + flag.VisitAll(func(f *flag.Flag) { + if f.Value.String() == "" { + log.Printf("Required flag -%s is not set.", f.Name) + missing = true + } + }) + if missing { + os.Exit(64) + } + if err := provisionDB(*project, *serviceAccount, *instance, *database, *password, *schema); err != nil { + log.Fatal(err) + } +} + +type key struct { + PrivateKeyID string `json:"private_key_id"` +} + +func provisionDB(projectID, serviceAccount, dbInstance, dbName, dbPassword, schemaPath string) error { + log.Printf("Downloading Docker images...") + const mySQLImage = "mysql:5.6" + cloudSQLProxyImage := "gcr.io/cloudsql-docker/gce-proxy:1.11" + images := []string{mySQLImage, cloudSQLProxyImage} + for _, img := range images { + if _, err := run("docker", "pull", img); err != nil { + return err + } + } + + log.Printf("Getting connection string from database metadata...") + gcp := &gcloud{projectID} + dbConnStr, err := run(gcp.cmd("sql", "instances", "describe", "--format", "value(connectionName)", dbInstance)...) + if err != nil { + return fmt.Errorf("getting connection string: %v", err) + } + + // Create a temporary directory to hold the service account key. + // We resolve all symlinks to avoid Docker on Mac issues, see + // https://github.com/google/go-cloud/issues/110. + serviceAccountVolDir, err := os.MkdirTemp("", "guestbook-service-acct") + if err != nil { + return fmt.Errorf("creating temp dir to hold service account key: %v", err) + } + serviceAccountVolDir, err = filepath.EvalSymlinks(serviceAccountVolDir) + if err != nil { + return fmt.Errorf("evaluating any symlinks: %v", err) + } + defer os.RemoveAll(serviceAccountVolDir) + log.Printf("Created %v", serviceAccountVolDir) + + // Furnish a new service account key. + if _, err := run(gcp.cmd("iam", "service-accounts", "keys", "create", "--iam-account="+serviceAccount, serviceAccountVolDir+"/key.json")...); err != nil { + return fmt.Errorf("creating new service account key: %v", err) + } + keyJSONb, err := os.ReadFile(filepath.Join(serviceAccountVolDir, "key.json")) + if err != nil { + return fmt.Errorf("reading key.json file: %v", err) + } + var k key + if err := json.Unmarshal(keyJSONb, &k); err != nil { + return fmt.Errorf("parsing key.json: %v", err) + } + serviceAccountKeyID := k.PrivateKeyID + defer func() { + if _, err := run(gcp.cmd("iam", "service-accounts", "keys", "delete", "--iam-account", serviceAccount, serviceAccountKeyID)...); err != nil { + log.Printf("deleting service account key: %v", err) + } + }() + log.Printf("Created service account key %s", serviceAccountKeyID) + + log.Printf("Starting Cloud SQL proxy...") + proxyContainerID, err := run("docker", "run", "--detach", "--rm", "--volume", serviceAccountVolDir+":/creds", "--publish", "3306", cloudSQLProxyImage, "/cloud_sql_proxy", "-instances", dbConnStr+"=tcp:0.0.0.0:3306", "-credential_file=/creds/key.json") + if err != nil { + return err + } + defer func() { + if _, err := run("docker", "kill", proxyContainerID); err != nil { + log.Printf("failed to kill docker container for proxy: %v", err) + } + }() + + log.Print("Sending schema to database...") + mySQLCmd := fmt.Sprintf(`mysql --wait -h"$PROXY_PORT_3306_TCP_ADDR" -P"$PROXY_PORT_3306_TCP_PORT" -uroot -p'%s' '%s'`, dbPassword, dbName) + connect := exec.Command("docker", "run", "--rm", "--interactive", "--link", proxyContainerID+":proxy", mySQLImage, "sh", "-c", mySQLCmd) + schema, err := os.Open(schemaPath) + if err != nil { + return err + } + defer schema.Close() + connect.Stdin = schema + connect.Stderr = os.Stderr + if err := connect.Run(); err != nil { + return fmt.Errorf("running %v: %v", connect.Args, err) + } + + return nil +} + +func run(args ...string) (stdout string, err error) { + cmd := exec.Command(args[0], args[1:]...) + cmd.Stderr = os.Stderr + cmd.Env = append(cmd.Env, os.Environ()...) + stdoutb, err := cmd.Output() + if err != nil { + return "", fmt.Errorf("running %v: %v", cmd.Args, err) + } + return strings.TrimSpace(string(stdoutb)), nil +} + +type gcloud struct { + // project ID + project string +} + +func (gcp *gcloud) cmd(args ...string) []string { + return append([]string{"gcloud", "--quiet", "--project", gcp.project}, args...) +} diff --git a/go-cloud/samples/guestbook/gcp/variables.tf b/go-cloud/samples/guestbook/gcp/variables.tf new file mode 100644 index 000000000..dad948ad4 --- /dev/null +++ b/go-cloud/samples/guestbook/gcp/variables.tf @@ -0,0 +1,44 @@ +# Copyright 2018 The Go Cloud Development Kit 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 +# +# https://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. + +variable "project" { + type = string + description = "Project to set up." +} + +variable "region" { + type = string + description = "GCP region to create database and storage in, for example 'us-central1'. See https://cloud.google.com/compute/docs/regions-zones/ for valid values." +} + +variable "zone" { + type = string + description = "GCP zone to create the GKE cluster in, for example 'us-central1-a'. See https://cloud.google.com/compute/docs/regions-zones/ for valid values." +} + +variable "server_service_account_name" { + default = "guestbook" + description = "The username part of the service account email that will be used for the server running inside the GKE cluster." +} + +variable "db_access_service_account_name" { + default = "guestbook-db" + description = "The username part of the service account email that will be used for provisioning the database." +} + +variable "cluster_name" { + default = "guestbook-cluster" + description = "The GKE cluster name." +} + diff --git a/go-cloud/samples/guestbook/inject_aws.go b/go-cloud/samples/guestbook/inject_aws.go new file mode 100644 index 000000000..318c8fcae --- /dev/null +++ b/go-cloud/samples/guestbook/inject_aws.go @@ -0,0 +1,88 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build wireinject +// +build wireinject + +package main + +import ( + "context" + "database/sql" + "net/url" + + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/aws/awscloud" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/s3blob" + "github.com/DataDog/iceberg-go/go-cloud/mysql/awsmysql" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/awsparamstore" + "github.com/DataDog/iceberg-go/go-cloud/server" +) + +// This file wires the generic interfaces up to Amazon Web Services (AWS). It +// won't be directly included in the final binary, since it includes a Wire +// injector template function (setupAWS), but the declarations will be copied +// into wire_gen.go when Wire is run. + +// setupAWS is a Wire injector function that sets up the application using AWS. +func setupAWS(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) { + // This will be filled in by Wire with providers from the provider sets in + // wire.Build. + wire.Build( + awscloud.AWS, + wire.Struct(new(awsmysql.URLOpener), "CertSource"), + applicationSet, + awsBucket, + awsMOTDVar, + openAWSDatabase, + ) + return nil, nil, nil +} + +// awsBucket is a Wire provider function that returns the S3 bucket based on the +// command-line flags. +func awsBucket(ctx context.Context, client *s3.Client, flags *cliFlags) (*blob.Bucket, func(), error) { + b, err := s3blob.OpenBucketV2(ctx, client, flags.bucket, nil) + if err != nil { + return nil, nil, err + } + return b, func() { b.Close() }, nil +} + +// openAWSDatabase is a Wire provider function that connects to an AWS RDS +// MySQL database based on the command-line flags. +func openAWSDatabase(ctx context.Context, opener *awsmysql.URLOpener, flags *cliFlags) (*sql.DB, func(), error) { + db, err := opener.OpenMySQLURL(ctx, &url.URL{ + Scheme: "awsmysql", + User: url.UserPassword(flags.dbUser, flags.dbPassword), + Host: flags.dbHost, + Path: "/" + flags.dbName, + }) + if err != nil { + return nil, nil, err + } + return db, func() { db.Close() }, nil +} + +// awsMOTDVar is a Wire provider function that returns the Message of the Day +// variable from SSM Parameter Store. +func awsMOTDVar(ctx context.Context, client *ssm.Client, flags *cliFlags) (*runtimevar.Variable, error) { + return awsparamstore.OpenVariableV2(client, flags.motdVar, runtimevar.StringDecoder, &awsparamstore.Options{ + WaitDuration: flags.motdVarWaitTime, + }) +} diff --git a/go-cloud/samples/guestbook/inject_azure.go b/go-cloud/samples/guestbook/inject_azure.go new file mode 100644 index 000000000..8ca94b44c --- /dev/null +++ b/go-cloud/samples/guestbook/inject_azure.go @@ -0,0 +1,84 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build wireinject +// +build wireinject + +package main + +import ( + "context" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/trace" + + azcontainer "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/azureblob" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/blobvar" + "github.com/DataDog/iceberg-go/go-cloud/server" + "github.com/DataDog/iceberg-go/go-cloud/server/requestlog" +) + +// This file wires the generic interfaces up to Microsoft Azure. It +// won't be directly included in the final binary, since it includes a Wire +// injector template function (setupAzure), but the declarations will be copied +// into wire_gen.go when Wire is run. + +// setupAzure is a Wire injector function that sets up the application using +// Azure. +func setupAzure(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) { + // This will be filled in by Wire with providers from the provider sets in + // wire.Build. + wire.Build( + wire.InterfaceValue(new(requestlog.Logger), requestlog.Logger(nil)), + azureblob.NewDefaultServiceURLOptions, + azureblob.NewDefaultClient, + azureblob.NewServiceURL, + applicationSet, + bucketName, + azureBucket, + azureMOTDVar, + server.Set, + wire.InterfaceValue(new(propagation.TextMapPropagator), propagation.TextMapPropagator(nil)), + wire.InterfaceValue(new(trace.TracerProvider), trace.TracerProvider(nil)), + wire.InterfaceValue(new(metric.MeterProvider), metric.MeterProvider(nil)), + dialLocalSQL, + ) + return nil, nil, nil +} + +func bucketName(flags *cliFlags) azureblob.ContainerName { + return azureblob.ContainerName(flags.bucket) +} + +// azureBucket is a Wire provider function that returns the Azure bucket based +// on the command-line flags. +func azureBucket(ctx context.Context, client *azcontainer.Client, flags *cliFlags) (*blob.Bucket, func(), error) { + b, err := azureblob.OpenBucket(ctx, client, nil) + if err != nil { + return nil, nil, err + } + return b, func() { b.Close() }, nil +} + +// azureMOTDVar is a Wire provider function that returns the Message of the Day +// variable read from a blob stored in Azure. +func azureMOTDVar(ctx context.Context, b *blob.Bucket, flags *cliFlags) (*runtimevar.Variable, error) { + return blobvar.OpenVariable(b, flags.motdVar, runtimevar.StringDecoder, &blobvar.Options{ + WaitDuration: flags.motdVarWaitTime, + }) +} diff --git a/go-cloud/samples/guestbook/inject_gcp.go b/go-cloud/samples/guestbook/inject_gcp.go new file mode 100644 index 000000000..f05548953 --- /dev/null +++ b/go-cloud/samples/guestbook/inject_gcp.go @@ -0,0 +1,94 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build wireinject +// +build wireinject + +package main + +import ( + "context" + "database/sql" + "fmt" + "net/url" + + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/gcsblob" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/gcp/gcpcloud" + "github.com/DataDog/iceberg-go/go-cloud/mysql/gcpmysql" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/gcpruntimeconfig" + "github.com/DataDog/iceberg-go/go-cloud/server" + pb "google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1" +) + +// This file wires the generic interfaces up to Google Cloud Platform (GCP). It +// won't be directly included in the final binary, since it includes a Wire +// injector template function (setupGCP), but the declarations will be copied +// into wire_gen.go when Wire is run. + +// setupGCP is a Wire injector function that sets up the application using GCP. +func setupGCP(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) { + // This will be filled in by Wire with providers from the provider sets in + // wire.Build. + wire.Build( + gcpcloud.GCP, + wire.Struct(new(gcpmysql.URLOpener), "CertSource"), + applicationSet, + gcpBucket, + gcpMOTDVar, + openGCPDatabase, + ) + return nil, nil, nil +} + +// gcpBucket is a Wire provider function that returns the GCS bucket based on +// the command-line flags. +func gcpBucket(ctx context.Context, flags *cliFlags, client *gcp.HTTPClient) (*blob.Bucket, func(), error) { + b, err := gcsblob.OpenBucket(ctx, client, flags.bucket, nil) + if err != nil { + return nil, nil, err + } + return b, func() { b.Close() }, nil +} + +// openGCPDatabase is a Wire provider function that connects to a GCP Cloud SQL +// MySQL database based on the command-line flags. +func openGCPDatabase(ctx context.Context, opener *gcpmysql.URLOpener, id gcp.ProjectID, flags *cliFlags) (*sql.DB, func(), error) { + db, err := opener.OpenMySQLURL(ctx, &url.URL{ + Scheme: "gcpmysql", + User: url.UserPassword(flags.dbUser, flags.dbPassword), + Host: string(id), + Path: fmt.Sprintf("/%s/%s/%s", flags.cloudSQLRegion, flags.dbHost, flags.dbName), + }) + if err != nil { + return nil, nil, err + } + return db, func() { db.Close() }, nil +} + +// gcpMOTDVar is a Wire provider function that returns the Message of the Day +// variable from Runtime Configurator. +func gcpMOTDVar(ctx context.Context, client pb.RuntimeConfigManagerClient, project gcp.ProjectID, flags *cliFlags) (*runtimevar.Variable, func(), error) { + variableKey := gcpruntimeconfig.VariableKey(project, flags.runtimeConfigName, flags.motdVar) + v, err := gcpruntimeconfig.OpenVariable(client, variableKey, runtimevar.StringDecoder, &gcpruntimeconfig.Options{ + WaitDuration: flags.motdVarWaitTime, + }) + if err != nil { + return nil, nil, err + } + return v, func() { v.Close() }, nil +} diff --git a/go-cloud/samples/guestbook/inject_local.go b/go-cloud/samples/guestbook/inject_local.go new file mode 100644 index 000000000..8727006fb --- /dev/null +++ b/go-cloud/samples/guestbook/inject_local.go @@ -0,0 +1,91 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build wireinject +// +build wireinject + +package main + +import ( + "context" + "database/sql" + + "github.com/go-sql-driver/mysql" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/fileblob" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/filevar" + "github.com/DataDog/iceberg-go/go-cloud/server" + "github.com/DataDog/iceberg-go/go-cloud/server/requestlog" +) + +// This file wires the generic interfaces up to local implementations. It won't +// be directly included in the final binary, since it includes a Wire injector +// template function (setupLocal), but the declarations will be copied into +// wire_gen.go when Wire is run. + +// setupLocal is a Wire injector function that sets up the application using +// local implementations. +func setupLocal(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) { + // This will be filled in by Wire with providers from the provider sets in + // wire.Build. + wire.Build( + wire.InterfaceValue(new(requestlog.Logger), requestlog.Logger(nil)), + server.Set, + newPropagationTextMap, + newTraceSampler, + newTraceExporter, + otelTracesProviderSet, + otelMetricsProviderSet, + newMetricsReader, + applicationSet, + dialLocalSQL, + localBucket, + localRuntimeVar, + ) + return nil, nil, nil +} + +// localBucket is a Wire provider function that returns a directory-based bucket +// based on the command-line flags. +func localBucket(flags *cliFlags) (*blob.Bucket, error) { + return fileblob.OpenBucket(flags.bucket, nil) +} + +// dialLocalSQL is a Wire provider function that connects to a MySQL database +// (usually on localhost). +func dialLocalSQL(flags *cliFlags) (*sql.DB, error) { + cfg := &mysql.Config{ + Net: "tcp", + Addr: flags.dbHost, + DBName: flags.dbName, + User: flags.dbUser, + Passwd: flags.dbPassword, + AllowNativePasswords: true, + } + return sql.Open("mysql", cfg.FormatDSN()) +} + +// localRuntimeVar is a Wire provider function that returns the Message of the +// Day variable based on a local file. +func localRuntimeVar(flags *cliFlags) (*runtimevar.Variable, func(), error) { + v, err := filevar.OpenVariable(flags.motdVar, runtimevar.StringDecoder, &filevar.Options{ + WaitDuration: flags.motdVarWaitTime, + }) + if err != nil { + return nil, nil, err + } + return v, func() { v.Close() }, nil +} diff --git a/go-cloud/samples/guestbook/localdb/main.go b/go-cloud/samples/guestbook/localdb/main.go new file mode 100644 index 000000000..e1459a23c --- /dev/null +++ b/go-cloud/samples/guestbook/localdb/main.go @@ -0,0 +1,138 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "context" + "errors" + "flag" + "fmt" + "log" + "os" + "os/exec" + "os/signal" + "path/filepath" + "strings" + "time" + + pipe "gopkg.in/pipe.v2" +) + +func main() { + guestbookDir := flag.String("guestbook_dir", ".", "directory containing guestbook sample source code") + flag.Parse() + if flag.NArg() > 1 { + fmt.Fprintf(os.Stderr, "usage: localdb [flags] container_name\n") + os.Exit(1) + } + log.SetPrefix("localdb: ") + log.SetFlags(0) + if err := runLocalDB(flag.Arg(0), *guestbookDir); err != nil { + log.Fatal(err) + } +} + +func runLocalDB(containerName, guestbookDir string) error { + image := "mysql:5.6" + + log.Printf("Starting container running MySQL") + dockerArgs := []string{"run", "--rm"} + if containerName != "" { + dockerArgs = append(dockerArgs, "--name", containerName) + } + dockerArgs = append(dockerArgs, + "--platform", "linux/amd64", + "--env", "MYSQL_DATABASE=guestbook", + "--env", "MYSQL_ROOT_PASSWORD=password", + "--detach", + "--publish", "3306:3306", + image) + cmd := exec.Command("docker", dockerArgs...) + cmd.Stderr = os.Stderr + out, err := cmd.Output() + if err != nil { + return fmt.Errorf("running %v: %v: %s", cmd.Args, err, out) + } + containerID := strings.TrimSpace(string(out)) + defer func() { + log.Printf("killing %s", containerID) + stop := exec.Command("docker", "kill", containerID) + stop.Stderr = os.Stderr + if err := stop.Run(); err != nil { + log.Printf("failed to kill db container: %v", err) + } + }() + + // Stop the container on Ctrl-C. + ctx, cancel := context.WithCancel(context.Background()) + go func() { + c := make(chan os.Signal, 1) + // TODO(ijt): Handle SIGTERM. + signal.Notify(c, os.Interrupt) + <-c + cancel() + }() + + nap := 10 * time.Second + log.Printf("Waiting %v for database to come up", nap) + select { + case <-time.After(nap): + // ok + case <-ctx.Done(): + return errors.New("interrupted while napping") + } + + log.Printf("Initializing database schema and users") + schema, err := os.ReadFile(filepath.Join(guestbookDir, "schema.sql")) + if err != nil { + return fmt.Errorf("reading schema: %v", err) + } + roles, err := os.ReadFile(filepath.Join(guestbookDir, "roles.sql")) + if err != nil { + return fmt.Errorf("reading roles: %v", err) + } + tooMany := 10 + var i int + for i = 0; i < tooMany; i++ { + mySQL := `mysql -h"${MYSQL_PORT_3306_TCP_ADDR?}" -P"${MYSQL_PORT_3306_TCP_PORT?}" -uroot -ppassword guestbook` + p := pipe.Line( + pipe.Read(strings.NewReader(string(schema)+string(roles))), + pipe.Exec("docker", "run", "--rm", "--interactive", "--link", containerID+":mysql", image, "sh", "-c", mySQL), + ) + if _, stderr, err := pipe.DividedOutput(p); err != nil { + log.Printf("Failed to seed database: %q; retrying", stderr) + select { + case <-time.After(time.Second): + continue + case <-ctx.Done(): + return errors.New("interrupted while napping in between database seeding attempts") + } + } + break + } + if i == tooMany { + return fmt.Errorf("gave up after %d tries to seed database", i) + } + + log.Printf("Database running at localhost:3306") + attach := exec.CommandContext(ctx, "docker", "attach", containerID) + attach.Stdout = os.Stdout + attach.Stderr = os.Stderr + if err := attach.Run(); err != nil { + return fmt.Errorf("running %v: %q", attach.Args, err) + } + + return nil +} diff --git a/go-cloud/samples/guestbook/main.go b/go-cloud/samples/guestbook/main.go new file mode 100644 index 000000000..648861280 --- /dev/null +++ b/go-cloud/samples/guestbook/main.go @@ -0,0 +1,308 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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. + +// guestbook is a sample application that records visitors' messages, displays a +// cloud banner, and an administrative message. +package main + +import ( + "bytes" + "context" + "database/sql" + "flag" + "html/template" + "io" + "log" + "net/http" + "strconv" + "time" + + "github.com/google/wire" + "github.com/gorilla/mux" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + + "github.com/DataDog/iceberg-go/go-cloud/server" + "github.com/DataDog/iceberg-go/go-cloud/server/health" + "github.com/DataDog/iceberg-go/go-cloud/server/health/sqlhealth" +) + +type cliFlags struct { + bucket string + dbHost string + dbName string + dbUser string + dbPassword string + motdVar string + motdVarWaitTime time.Duration + + // GCP only. + cloudSQLRegion string + runtimeConfigName string +} + +var envFlag string + +func main() { + // Determine environment to set up based on flag. + cf := new(cliFlags) + flag.StringVar(&envFlag, "env", "local", "environment to run under (gcp, aws, azure, or local)") + addr := flag.String("listen", ":8080", "port to listen for HTTP on") + flag.StringVar(&cf.bucket, "bucket", "", "bucket name") + flag.StringVar(&cf.dbHost, "db_host", "", "database host or Cloud SQL instance name") + flag.StringVar(&cf.dbName, "db_name", "guestbook", "database name") + flag.StringVar(&cf.dbUser, "db_user", "guestbook", "database user") + flag.StringVar(&cf.dbPassword, "db_password", "", "database user password") + flag.StringVar(&cf.motdVar, "motd_var", "", "message of the day variable location") + flag.DurationVar(&cf.motdVarWaitTime, "motd_var_wait_time", 5*time.Second, "polling frequency of message of the day") + flag.StringVar(&cf.cloudSQLRegion, "cloud_sql_region", "", "region of the Cloud SQL instance (GCP only)") + flag.StringVar(&cf.runtimeConfigName, "runtime_config", "", "Runtime Configurator config resource (GCP only)") + flag.Parse() + + ctx := context.Background() + var srv *server.Server + var cleanup func() + var err error + switch envFlag { + case "gcp": + srv, cleanup, err = setupGCP(ctx, cf) + case "aws": + srv, cleanup, err = setupAWS(ctx, cf) + case "azure": + if cf.dbHost == "" { + cf.dbHost = "localhost" + } + if cf.dbPassword == "" { + cf.dbPassword = "xyzzy" + } + srv, cleanup, err = setupAzure(ctx, cf) + case "local": + // The default MySQL instance is running on localhost + // with this root password. + if cf.dbHost == "" { + cf.dbHost = "localhost" + } + if cf.dbPassword == "" { + cf.dbPassword = "xyzzy" + } + srv, cleanup, err = setupLocal(ctx, cf) + default: + log.Fatalf("unknown -env=%s", envFlag) + } + if err != nil { + log.Fatal(err) + } + defer cleanup() + + // Listen and serve HTTP. + log.Printf("Running, connected to %q cloud", envFlag) + log.Fatal(srv.ListenAndServe(*addr)) +} + +// applicationSet is the Wire provider set for the Guestbook application that +// does not depend on the underlying platform. +var applicationSet = wire.NewSet( + newApplication, + appHealthChecks, + newRouter, + wire.Bind(new(http.Handler), new(*mux.Router)), +) + +func newRouter(app *application) *mux.Router { + r := mux.NewRouter() + r.HandleFunc("/", app.index) + r.HandleFunc("/sign", app.sign) + r.HandleFunc("/blob/{key:.+}", app.serveBlob) + return r +} + +// application is the main server struct for Guestbook. It contains the state of +// the most recently read message of the day. +type application struct { + db *sql.DB + bucket *blob.Bucket + motdVar *runtimevar.Variable +} + +// newApplication creates a new application struct based on the backends and the message +// of the day variable. +func newApplication(db *sql.DB, bucket *blob.Bucket, motdVar *runtimevar.Variable) *application { + return &application{ + db: db, + bucket: bucket, + motdVar: motdVar, + } +} + +// index serves the server's landing page. It lists the 100 most recent +// greetings, shows a cloud environment banner, and displays the message of the +// day. +func (app *application) index(w http.ResponseWriter, r *http.Request) { + var data struct { + MOTD string + Env string + BannerSrc string + Greetings []greeting + } + snap, err := app.motdVar.Latest(r.Context()) + if err != nil { + log.Println("index page error:", err) + http.Error(w, "could not load motd", http.StatusInternalServerError) + return + } + data.MOTD = snap.Value.(string) + + switch envFlag { + case "gcp": + data.Env = "GCP" + data.BannerSrc = "/blob/gcp.png" + case "aws": + data.Env = "AWS" + data.BannerSrc = "/blob/aws.png" + case "azure": + data.Env = "Azure" + data.BannerSrc = "/blob/azure.png" + case "local": + data.Env = "Local" + data.BannerSrc = "/blob/gophers.jpg" + } + + const query = "SELECT content FROM (SELECT content, post_date FROM greetings ORDER BY post_date DESC LIMIT 100) AS recent_greetings ORDER BY post_date ASC;" + q, err := app.db.QueryContext(r.Context(), query) + if err != nil { + log.Println("main page SQL error:", err) + http.Error(w, "could not load greetings", http.StatusInternalServerError) + return + } + defer q.Close() + for q.Next() { + var g greeting + if err := q.Scan(&g.Content); err != nil { + log.Println("main page SQL error:", err) + http.Error(w, "could not load greetings", http.StatusInternalServerError) + return + } + data.Greetings = append(data.Greetings, g) + } + if err := q.Err(); err != nil { + log.Println("main page SQL error:", err) + http.Error(w, "could not load greetings", http.StatusInternalServerError) + return + } + buf := new(bytes.Buffer) + if err := tmpl.Execute(buf, data); err != nil { + log.Println("template error:", err) + http.Error(w, "could not render page", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.Header().Set("Content-Length", strconv.Itoa(buf.Len())) + if _, err := w.Write(buf.Bytes()); err != nil { + log.Println("writing response:", err) + } +} + +type greeting struct { + Content string +} + +var tmpl = template.Must(template.New("index.html").Parse(`<!DOCTYPE html> +<title>Guestbook - {{.Env}}</title> +<style type="text/css"> +html, body { + font-family: Helvetica, sans-serif; +} +blockquote { + font-family: cursive, Helvetica, sans-serif; +} +.banner { + height: 125px; + width: 250px; +} +.greeting { + font-size: 85%; +} +.motd { + font-weight: bold; +} +</style> +<h1>Guestbook</h1> +<div><img class="banner" src="{{.BannerSrc}}"></div> +{{with .MOTD}}<p class="motd">Admin says: {{.}}</p>{{end}} +{{range .Greetings}} +<div class="greeting"> + Someone wrote: + <blockquote>{{.Content}}</blockquote> +</div> +{{end}} +<form action="/sign" method="POST"> + <div><textarea name="content" rows="3"></textarea></div> + <div><input type="submit" value="Sign"></div> +</form> +`)) + +// sign is a form action handler for adding a greeting. +func (app *application) sign(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + w.Header().Set("Allow", "POST") + http.Error(w, "Only POST allowed", http.StatusMethodNotAllowed) + return + } + content := r.FormValue("content") + if content == "" { + http.Error(w, "content must not be empty", http.StatusBadRequest) + return + } + const sqlStmt = "INSERT INTO greetings (content) VALUES (?);" + _, err := app.db.ExecContext(r.Context(), sqlStmt, content) + if err != nil { + log.Println("sign SQL error:", err) + http.Error(w, "database error", http.StatusInternalServerError) + return + } + http.Redirect(w, r, "/", http.StatusSeeOther) +} + +// serveBlob handles a request for a static asset by retrieving it from a bucket. +func (app *application) serveBlob(w http.ResponseWriter, r *http.Request) { + key := mux.Vars(r)["key"] + blobReader, err := app.bucket.NewReader(r.Context(), key, nil) + if err != nil { + log.Println("serve blob:", err) + if gcerrors.Code(err) == gcerrors.NotFound { + http.Error(w, "blob not found", http.StatusNotFound) + } else { + http.Error(w, "blob read error", http.StatusInternalServerError) + } + return + } + defer blobReader.Close() + w.Header().Set("Content-Type", blobReader.ContentType()) + w.Header().Set("Content-Length", strconv.FormatInt(blobReader.Size(), 10)) + if _, err = io.Copy(w, blobReader); err != nil { + log.Println("Copying blob:", err) + } +} + +// appHealthChecks returns a health check for the database. This will signal +// to Kubernetes or other orchestrators that the server should not receive +// traffic until the server is able to connect to its database. +func appHealthChecks(db *sql.DB) ([]health.Checker, func()) { + dbCheck := sqlhealth.New(db) + list := []health.Checker{dbCheck} + return list, func() { + dbCheck.Stop() + } +} diff --git a/go-cloud/samples/guestbook/roles.sql b/go-cloud/samples/guestbook/roles.sql new file mode 100644 index 000000000..c9c47f511 --- /dev/null +++ b/go-cloud/samples/guestbook/roles.sql @@ -0,0 +1,16 @@ +-- Copyright 2018 The Go Cloud Development Kit 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 +-- +-- https://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. + +CREATE USER 'guestbook'@'%' IDENTIFIED BY 'xyzzy'; +GRANT SELECT,INSERT,UPDATE,DELETE ON guestbook.* TO 'guestbook'@'%'; diff --git a/go-cloud/samples/guestbook/schema.sql b/go-cloud/samples/guestbook/schema.sql new file mode 100644 index 000000000..c49691bc3 --- /dev/null +++ b/go-cloud/samples/guestbook/schema.sql @@ -0,0 +1,20 @@ +-- Copyright 2018 The Go Cloud Development Kit 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 +-- +-- https://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. + +CREATE TABLE greetings ( + content VARCHAR(255) CHARACTER SET utf8 + NOT NULL + CHECK (content <> ''), + post_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); diff --git a/go-cloud/samples/guestbook/telemetry.go b/go-cloud/samples/guestbook/telemetry.go new file mode 100644 index 000000000..407556545 --- /dev/null +++ b/go-cloud/samples/guestbook/telemetry.go @@ -0,0 +1,145 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "context" + "github.com/google/wire" + "go.opentelemetry.io/contrib/exporters/autoexport" + "go.opentelemetry.io/contrib/propagators/autoprop" + "go.opentelemetry.io/otel/log" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/propagation" + sdklog "go.opentelemetry.io/otel/sdk/log" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/trace" +) + +// otelTracesProviderSet is a Wire provider set that provides the open telemetry trace provider +var otelTracesProviderSet = wire.NewSet( + NewTraceProvider, + wire.Bind(new(trace.TracerProvider), new(*sdktrace.TracerProvider)), +) + +// otelMetricsProviderSet is a Wire provider set that provides the open telemetry metrics provider +var otelMetricsProviderSet = wire.NewSet( + NewMeterProvider, + wire.Bind(new(metric.MeterProvider), new(*sdkmetric.MeterProvider)), +) + +// OtelLogsSet is a Wire provider set that provides the open telemetry logs provider given the exporter +var OtelLogsSet = wire.NewSet( + NewLogsExporter, + NewLoggerProvider, + wire.Bind(new(log.LoggerProvider), new(*sdklog.LoggerProvider)), +) + +func newResource() *resource.Resource { + return resource.Default() +} + +func newPropagationTextMap() propagation.TextMapPropagator { + return autoprop.NewTextMapPropagator() +} + +// newTraceExporter returns a new OpenTelemetry gcp trace exporter. +func newTraceExporter(ctx context.Context) (sdktrace.SpanExporter, error) { + + traceExporter, err := autoexport.NewSpanExporter(ctx) + if err != nil { + return nil, err + } + + return traceExporter, nil +} + +// newTraceSampler returns a new OpenTelemetry trace sampler. +func newTraceSampler(ctx context.Context) sdktrace.Sampler { + return sdktrace.AlwaysSample() +} + +// NewTraceProvider returns a new trace provider for our service to utilise. +// +// The second return value is a Wire cleanup function that calls Close on the provider, +func NewTraceProvider(ctx context.Context, exporter sdktrace.SpanExporter, sampler sdktrace.Sampler) (*sdktrace.TracerProvider, func()) { + + res := newResource() + tp := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(exporter), + sdktrace.WithSampler(sampler), + sdktrace.WithResource(res), + ) + + return tp, func() { _ = tp.Shutdown(ctx) } +} + +// newMetricsReader returns a new OpenTelemetry gcp metrics exporter. +func newMetricsReader(ctx context.Context) (sdkmetric.Reader, error) { + // Create and start new OTLP metric exporter + metricReader, err := autoexport.NewMetricReader(ctx) + if err != nil { + return nil, err + } + + return metricReader, nil +} + +// NewMeterProvider returns a new metric provider for our service to utilise. +// +// The second return value is a Wire cleanup function that calls Close on the provider, +func NewMeterProvider(ctx context.Context, reader sdkmetric.Reader) (*sdkmetric.MeterProvider, func()) { + + res := newResource() + + meterProvider := sdkmetric.NewMeterProvider( + sdkmetric.WithResource(res), + sdkmetric.WithReader(reader), + ) + return meterProvider, func() { _ = meterProvider.Shutdown(ctx) } +} + +// NewLogsExporter returns a new OpenTelemetry gcp metrics exporter. +func NewLogsExporter(ctx context.Context) (sdklog.Exporter, error) { + // Create and start new OTLP metric exporter + logsExporter, err := autoexport.NewLogExporter(ctx) + if err != nil { + return nil, err + } + + return logsExporter, nil +} + +// NewLoggerProvider returns a new logger provider for our service to utilise. +// +// The second return value is a Wire cleanup function that calls Close on the provider, +func NewLoggerProvider(ctx context.Context, res *resource.Resource, exporter sdklog.Exporter) (*sdklog.LoggerProvider, func(), error) { + + var err error + if exporter == nil { + exporter, err = autoexport.NewLogExporter(ctx) + if err != nil { + return nil, nil, err + } + } + + processor := sdklog.NewBatchProcessor(exporter) + logProvider := sdklog.NewLoggerProvider( + sdklog.WithResource(res), + sdklog.WithProcessor(processor), + ) + return logProvider, func() { _ = logProvider.Shutdown(context.TODO()) }, nil +} diff --git a/go-cloud/samples/guestbook/wire_gen.go b/go-cloud/samples/guestbook/wire_gen.go new file mode 100644 index 000000000..c944c91ed --- /dev/null +++ b/go-cloud/samples/guestbook/wire_gen.go @@ -0,0 +1,496 @@ +// Code generated by Wire. DO NOT EDIT. + +//go:generate go run -mod=mod github.com/google/wire/cmd/wire +//go:build !wireinject +// +build !wireinject + +package main + +import ( + "context" + "database/sql" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/go-sql-driver/mysql" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/trace" + "github.com/DataDog/iceberg-go/go-cloud/aws" + "github.com/DataDog/iceberg-go/go-cloud/aws/rds" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/azureblob" + "github.com/DataDog/iceberg-go/go-cloud/blob/fileblob" + "github.com/DataDog/iceberg-go/go-cloud/blob/gcsblob" + "github.com/DataDog/iceberg-go/go-cloud/blob/s3blob" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/gcp/cloudsql" + "github.com/DataDog/iceberg-go/go-cloud/mysql/awsmysql" + "github.com/DataDog/iceberg-go/go-cloud/mysql/gcpmysql" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/awsparamstore" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/blobvar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/filevar" + "github.com/DataDog/iceberg-go/go-cloud/runtimevar/gcpruntimeconfig" + "github.com/DataDog/iceberg-go/go-cloud/server" + "github.com/DataDog/iceberg-go/go-cloud/server/requestlog" + "github.com/DataDog/iceberg-go/go-cloud/server/sdserver" + "github.com/DataDog/iceberg-go/go-cloud/server/xrayserver" + "google.golang.org/genproto/googleapis/cloud/runtimeconfig/v1beta1" + "net/http" + "net/url" +) + +// Injectors from inject_aws.go: + +// setupAWS is a Wire injector function that sets up the application using AWS. +func setupAWS(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) { + client := _wireClientValue + certFetcher := &rds.CertFetcher{ + Client: client, + } + urlOpener := &awsmysql.URLOpener{ + CertSource: certFetcher, + } + db, cleanup, err := openAWSDatabase(ctx, urlOpener, flags) + if err != nil { + return nil, nil, err + } + config, err := aws.NewDefaultV2Config(ctx) + if err != nil { + cleanup() + return nil, nil, err + } + s3Client := s3blob.Dial(config) + bucket, cleanup2, err := awsBucket(ctx, s3Client, flags) + if err != nil { + cleanup() + return nil, nil, err + } + ssmClient := awsparamstore.Dial(config) + variable, err := awsMOTDVar(ctx, ssmClient, flags) + if err != nil { + cleanup2() + cleanup() + return nil, nil, err + } + mainApplication := newApplication(db, bucket, variable) + router := newRouter(mainApplication) + ncsaLogger := xrayserver.NewRequestLogger() + v, cleanup3 := appHealthChecks(db) + propagator := xrayserver.NewTextMapPropagator() + spanExporter, err := xrayserver.NewTraceExporter(ctx) + if err != nil { + cleanup3() + cleanup2() + cleanup() + return nil, nil, err + } + sampler := xrayserver.NewTraceSampler() + tracerProvider, cleanup4, err := xrayserver.NewTraceProvider(ctx, spanExporter, sampler) + if err != nil { + cleanup3() + cleanup2() + cleanup() + return nil, nil, err + } + reader, err := xrayserver.NewMetricsReader(ctx) + if err != nil { + cleanup4() + cleanup3() + cleanup2() + cleanup() + return nil, nil, err + } + meterProvider, cleanup5, err := xrayserver.NewMeterProvider(ctx, reader) + if err != nil { + cleanup4() + cleanup3() + cleanup2() + cleanup() + return nil, nil, err + } + defaultDriver := _wireDefaultDriverValue + options := &server.Options{ + RequestLogger: ncsaLogger, + HealthChecks: v, + TraceTextMapPropagator: propagator, + TraceProvider: tracerProvider, + MetricsProvider: meterProvider, + Driver: defaultDriver, + } + serverServer := server.New(router, options) + return serverServer, func() { + cleanup5() + cleanup4() + cleanup3() + cleanup2() + cleanup() + }, nil +} + +var ( + _wireClientValue = http.DefaultClient + _wireDefaultDriverValue = &server.DefaultDriver{} +) + +// Injectors from inject_azure.go: + +// setupAzure is a Wire injector function that sets up the application using +// Azure. +func setupAzure(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) { + db, err := dialLocalSQL(flags) + if err != nil { + return nil, nil, err + } + serviceURLOptions := azureblob.NewDefaultServiceURLOptions() + serviceURL, err := azureblob.NewServiceURL(serviceURLOptions) + if err != nil { + return nil, nil, err + } + containerName := bucketName(flags) + client, err := azureblob.NewDefaultClient(serviceURL, containerName) + if err != nil { + return nil, nil, err + } + bucket, cleanup, err := azureBucket(ctx, client, flags) + if err != nil { + return nil, nil, err + } + variable, err := azureMOTDVar(ctx, bucket, flags) + if err != nil { + cleanup() + return nil, nil, err + } + mainApplication := newApplication(db, bucket, variable) + router := newRouter(mainApplication) + logger := _wireLoggerValue + v, cleanup2 := appHealthChecks(db) + textMapPropagator := _wireTextMapPropagatorValue + tracerProvider := _wireTracerProviderValue + meterProvider := _wireMeterProviderValue + defaultDriver := _wireDefaultDriverValue + options := &server.Options{ + RequestLogger: logger, + HealthChecks: v, + TraceTextMapPropagator: textMapPropagator, + TraceProvider: tracerProvider, + MetricsProvider: meterProvider, + Driver: defaultDriver, + } + serverServer := server.New(router, options) + return serverServer, func() { + cleanup2() + cleanup() + }, nil +} + +var ( + _wireLoggerValue = requestlog.Logger(nil) + _wireTextMapPropagatorValue = propagation.TextMapPropagator(nil) + _wireTracerProviderValue = trace.TracerProvider(nil) + _wireMeterProviderValue = metric.MeterProvider(nil) +) + +// Injectors from inject_gcp.go: + +// setupGCP is a Wire injector function that sets up the application using GCP. +func setupGCP(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) { + roundTripper := gcp.DefaultTransport() + credentials, err := gcp.DefaultCredentials(ctx) + if err != nil { + return nil, nil, err + } + tokenSource := gcp.CredentialsTokenSource(credentials) + httpClient, err := gcp.NewHTTPClient(roundTripper, tokenSource) + if err != nil { + return nil, nil, err + } + remoteCertSource := cloudsql.NewCertSource(httpClient) + urlOpener := &gcpmysql.URLOpener{ + CertSource: remoteCertSource, + } + projectID, err := gcp.DefaultProjectID(credentials) + if err != nil { + return nil, nil, err + } + db, cleanup, err := openGCPDatabase(ctx, urlOpener, projectID, flags) + if err != nil { + return nil, nil, err + } + bucket, cleanup2, err := gcpBucket(ctx, flags, httpClient) + if err != nil { + cleanup() + return nil, nil, err + } + runtimeConfigManagerClient, cleanup3, err := gcpruntimeconfig.Dial(ctx, tokenSource) + if err != nil { + cleanup2() + cleanup() + return nil, nil, err + } + variable, cleanup4, err := gcpMOTDVar(ctx, runtimeConfigManagerClient, projectID, flags) + if err != nil { + cleanup3() + cleanup2() + cleanup() + return nil, nil, err + } + mainApplication := newApplication(db, bucket, variable) + router := newRouter(mainApplication) + stackdriverLogger := sdserver.NewRequestLogger() + v, cleanup5 := appHealthChecks(db) + textMapPropagator := sdserver.NewTextMapPropagator() + spanExporter, err := sdserver.NewTraceExporter(projectID) + if err != nil { + cleanup5() + cleanup4() + cleanup3() + cleanup2() + cleanup() + return nil, nil, err + } + sampler := sdserver.NewTraceSampler(ctx) + tracerProvider, cleanup6, err := sdserver.NewTraceProvider(ctx, spanExporter, sampler) + if err != nil { + cleanup5() + cleanup4() + cleanup3() + cleanup2() + cleanup() + return nil, nil, err + } + reader, err := sdserver.NewMetricsReader(projectID) + if err != nil { + cleanup6() + cleanup5() + cleanup4() + cleanup3() + cleanup2() + cleanup() + return nil, nil, err + } + meterProvider, cleanup7, err := sdserver.NewMeterProvider(ctx, reader) + if err != nil { + cleanup6() + cleanup5() + cleanup4() + cleanup3() + cleanup2() + cleanup() + return nil, nil, err + } + defaultDriver := _wireDefaultDriverValue + options := &server.Options{ + RequestLogger: stackdriverLogger, + HealthChecks: v, + TraceTextMapPropagator: textMapPropagator, + TraceProvider: tracerProvider, + MetricsProvider: meterProvider, + Driver: defaultDriver, + } + serverServer := server.New(router, options) + return serverServer, func() { + cleanup7() + cleanup6() + cleanup5() + cleanup4() + cleanup3() + cleanup2() + cleanup() + }, nil +} + +// Injectors from inject_local.go: + +// setupLocal is a Wire injector function that sets up the application using +// local implementations. +func setupLocal(ctx context.Context, flags *cliFlags) (*server.Server, func(), error) { + db, err := dialLocalSQL(flags) + if err != nil { + return nil, nil, err + } + bucket, err := localBucket(flags) + if err != nil { + return nil, nil, err + } + variable, cleanup, err := localRuntimeVar(flags) + if err != nil { + return nil, nil, err + } + mainApplication := newApplication(db, bucket, variable) + router := newRouter(mainApplication) + logger := _wireRequestlogLoggerValue + v, cleanup2 := appHealthChecks(db) + textMapPropagator := newPropagationTextMap() + spanExporter, err := newTraceExporter(ctx) + if err != nil { + cleanup2() + cleanup() + return nil, nil, err + } + sampler := newTraceSampler(ctx) + tracerProvider, cleanup3 := NewTraceProvider(ctx, spanExporter, sampler) + reader, err := newMetricsReader(ctx) + if err != nil { + cleanup3() + cleanup2() + cleanup() + return nil, nil, err + } + meterProvider, cleanup4 := NewMeterProvider(ctx, reader) + defaultDriver := _wireDefaultDriverValue + options := &server.Options{ + RequestLogger: logger, + HealthChecks: v, + TraceTextMapPropagator: textMapPropagator, + TraceProvider: tracerProvider, + MetricsProvider: meterProvider, + Driver: defaultDriver, + } + serverServer := server.New(router, options) + return serverServer, func() { + cleanup4() + cleanup3() + cleanup2() + cleanup() + }, nil +} + +var ( + _wireRequestlogLoggerValue = requestlog.Logger(nil) +) + +// inject_aws.go: + +// awsBucket is a Wire provider function that returns the S3 bucket based on the +// command-line flags. +func awsBucket(ctx context.Context, client *s3.Client, flags *cliFlags) (*blob.Bucket, func(), error) { + b, err := s3blob.OpenBucketV2(ctx, client, flags.bucket, nil) + if err != nil { + return nil, nil, err + } + return b, func() { b.Close() }, nil +} + +// openAWSDatabase is a Wire provider function that connects to an AWS RDS +// MySQL database based on the command-line flags. +func openAWSDatabase(ctx context.Context, opener *awsmysql.URLOpener, flags *cliFlags) (*sql.DB, func(), error) { + db, err := opener.OpenMySQLURL(ctx, &url.URL{ + Scheme: "awsmysql", + User: url.UserPassword(flags.dbUser, flags.dbPassword), + Host: flags.dbHost, + Path: "/" + flags.dbName, + }) + if err != nil { + return nil, nil, err + } + return db, func() { db.Close() }, nil +} + +// awsMOTDVar is a Wire provider function that returns the Message of the Day +// variable from SSM Parameter Store. +func awsMOTDVar(ctx context.Context, client *ssm.Client, flags *cliFlags) (*runtimevar.Variable, error) { + return awsparamstore.OpenVariableV2(client, flags.motdVar, runtimevar.StringDecoder, &awsparamstore.Options{ + WaitDuration: flags.motdVarWaitTime, + }) +} + +// inject_azure.go: + +func bucketName(flags *cliFlags) azureblob.ContainerName { + return azureblob.ContainerName(flags.bucket) +} + +// azureBucket is a Wire provider function that returns the Azure bucket based +// on the command-line flags. +func azureBucket(ctx context.Context, client *container.Client, flags *cliFlags) (*blob.Bucket, func(), error) { + b, err := azureblob.OpenBucket(ctx, client, nil) + if err != nil { + return nil, nil, err + } + return b, func() { b.Close() }, nil +} + +// azureMOTDVar is a Wire provider function that returns the Message of the Day +// variable read from a blob stored in Azure. +func azureMOTDVar(ctx context.Context, b *blob.Bucket, flags *cliFlags) (*runtimevar.Variable, error) { + return blobvar.OpenVariable(b, flags.motdVar, runtimevar.StringDecoder, &blobvar.Options{ + WaitDuration: flags.motdVarWaitTime, + }) +} + +// inject_gcp.go: + +// gcpBucket is a Wire provider function that returns the GCS bucket based on +// the command-line flags. +func gcpBucket(ctx context.Context, flags *cliFlags, client *gcp.HTTPClient) (*blob.Bucket, func(), error) { + b, err := gcsblob.OpenBucket(ctx, client, flags.bucket, nil) + if err != nil { + return nil, nil, err + } + return b, func() { b.Close() }, nil +} + +// openGCPDatabase is a Wire provider function that connects to a GCP Cloud SQL +// MySQL database based on the command-line flags. +func openGCPDatabase(ctx context.Context, opener *gcpmysql.URLOpener, id gcp.ProjectID, flags *cliFlags) (*sql.DB, func(), error) { + db, err := opener.OpenMySQLURL(ctx, &url.URL{ + Scheme: "gcpmysql", + User: url.UserPassword(flags.dbUser, flags.dbPassword), + Host: string(id), + Path: fmt.Sprintf("/%s/%s/%s", flags.cloudSQLRegion, flags.dbHost, flags.dbName), + }) + if err != nil { + return nil, nil, err + } + return db, func() { db.Close() }, nil +} + +// gcpMOTDVar is a Wire provider function that returns the Message of the Day +// variable from Runtime Configurator. +func gcpMOTDVar(ctx context.Context, client runtimeconfig.RuntimeConfigManagerClient, project gcp.ProjectID, flags *cliFlags) (*runtimevar.Variable, func(), error) { + variableKey := gcpruntimeconfig.VariableKey(project, flags.runtimeConfigName, flags.motdVar) + v, err := gcpruntimeconfig.OpenVariable(client, variableKey, runtimevar.StringDecoder, &gcpruntimeconfig.Options{ + WaitDuration: flags.motdVarWaitTime, + }) + if err != nil { + return nil, nil, err + } + return v, func() { v.Close() }, nil +} + +// inject_local.go: + +// localBucket is a Wire provider function that returns a directory-based bucket +// based on the command-line flags. +func localBucket(flags *cliFlags) (*blob.Bucket, error) { + return fileblob.OpenBucket(flags.bucket, nil) +} + +// dialLocalSQL is a Wire provider function that connects to a MySQL database +// (usually on localhost). +func dialLocalSQL(flags *cliFlags) (*sql.DB, error) { + cfg := &mysql.Config{ + Net: "tcp", + Addr: flags.dbHost, + DBName: flags.dbName, + User: flags.dbUser, + Passwd: flags.dbPassword, + AllowNativePasswords: true, + } + return sql.Open("mysql", cfg.FormatDSN()) +} + +// localRuntimeVar is a Wire provider function that returns the Message of the +// Day variable based on a local file. +func localRuntimeVar(flags *cliFlags) (*runtimevar.Variable, func(), error) { + v, err := filevar.OpenVariable(flags.motdVar, runtimevar.StringDecoder, &filevar.Options{ + WaitDuration: flags.motdVarWaitTime, + }) + if err != nil { + return nil, nil, err + } + return v, func() { v.Close() }, nil +} diff --git a/go-cloud/samples/order/common.go b/go-cloud/samples/order/common.go new file mode 100644 index 000000000..0bc8c1e21 --- /dev/null +++ b/go-cloud/samples/order/common.go @@ -0,0 +1,40 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "time" +) + +// Order represents an order for a single image operation. +type Order struct { + ID string // unique ID, randomly generated + Email string // email address of customer + InImage string // name of input image + OutImage string // name of output image; empty if there was an error + CreateTime time.Time // time the order was created + FinishTime time.Time // time the order was finished + Note string // note to the customer from the processor, describing success or error + DocstoreRevision any +} + +// OrderRequest is a request for an order. It is the contents of the messages +// sent to the requests topic. +type OrderRequest struct { + ID string + Email string + InImage string + CreateTime time.Time +} diff --git a/go-cloud/samples/order/frontend.go b/go-cloud/samples/order/frontend.go new file mode 100644 index 000000000..fd250b9ea --- /dev/null +++ b/go-cloud/samples/order/frontend.go @@ -0,0 +1,236 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "html/template" + "io" + "log" + "net/http" + "os" + "path/filepath" + "strings" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + _ "github.com/DataDog/iceberg-go/go-cloud/blob/fileblob" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + _ "github.com/DataDog/iceberg-go/go-cloud/docstore/memdocstore" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + _ "github.com/DataDog/iceberg-go/go-cloud/pubsub/mempubsub" + "github.com/DataDog/iceberg-go/go-cloud/server" + "github.com/DataDog/iceberg-go/go-cloud/server/requestlog" +) + +// A frontend is a web server that takes image-processing orders. +type frontend struct { + requestTopic *pubsub.Topic + bucket *blob.Bucket + coll *docstore.Collection +} + +var ( + listTemplate *template.Template + orderFormTemplate *template.Template +) + +func init() { + // Work around a bug in go test where -coverpkg=./... uses the wrong + // working directory (golang.org/issue/33016). + dir, err := os.Getwd() + if err != nil { + log.Fatal(err) + } + if filepath.Base(dir) != "order" { + // The bug puts us in a sibling directory. + log.Printf("working around #33016, which put us in %s", dir) + dir = filepath.Join(filepath.Dir(dir), "order") + } + listTemplate = template.Must(template.ParseFiles(filepath.Join(dir, "list.htmlt"))) + orderFormTemplate = template.Must(template.ParseFiles(filepath.Join(dir, "order-form.htmlt"))) +} + +// run starts the server on port and runs it indefinitely. +func (f *frontend) run(ctx context.Context, port int) error { + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "index.html") }) + http.HandleFunc("/style.css", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "style.css") }) + http.HandleFunc("/orders/", wrapHTTPError(f.listOrders)) + http.HandleFunc("/orders/new", wrapHTTPError(f.orderForm)) + http.HandleFunc("/createOrder", wrapHTTPError(f.createOrder)) + http.HandleFunc("/show/", wrapHTTPError(f.showImage)) + + rl := requestlog.NewNCSALogger(os.Stdout, func(err error) { fmt.Fprintf(os.Stderr, "%v\n", err) }) + s := server.New(nil, &server.Options{ + RequestLogger: rl, + }) + return s.ListenAndServe(fmt.Sprintf(":%d", port)) +} + +// wrapHTTPError turns handlers that return error into ordinary http.Handlers, +// by calling http.Error on non-nil errors. +func wrapHTTPError(f func(http.ResponseWriter, *http.Request) error) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + if err := f(w, r); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } +} + +// orderForm serves a page that lets the user input a new order. +func (*frontend) orderForm(w http.ResponseWriter, r *http.Request) error { + if r.Method != "GET" { + http.Error(w, "bad method for orderForm: want GET", http.StatusBadRequest) + return nil + } + return executeTemplate(orderFormTemplate, nil, w) +} + +// createOrder handles a submitted order form. +func (f *frontend) createOrder(w http.ResponseWriter, r *http.Request) error { + if r.Method != "POST" { + http.Error(w, "bad method for createOrder: want POST", http.StatusBadRequest) + return nil + } + email := r.FormValue("email") + if email == "" { + http.Error(w, "email missing", http.StatusBadRequest) + return nil + } + + file, _, err := r.FormFile("file") + if err != nil { + return err + } + defer file.Close() + if _, err := f.doCreateOrder(r.Context(), email, file, time.Now()); err != nil { + return err + } + fmt.Fprintln(w, "Order received. Thank you.") + return nil +} + +// doCreateOrder creates a new order. +// It is passed the customer's email address, an io.Reader for reading the input +// image, and the current time. +// It creates an Order in the database and sends an OrderRequest over the pub/sub topic. +// It returns the order ID it generates, for testing. +func (f *frontend) doCreateOrder(ctx context.Context, email string, file io.Reader, now time.Time) (id string, err error) { + // Assign an ID for the order here, rather than in the processor. + // That allows the processor to detect duplicate pub/sub messages. + id = f.newID() + req := &OrderRequest{ + ID: id, + InImage: id + "-in", + Email: email, + CreateTime: now, + } + + // Copy the uploaded input file to the bucket. + w, err := f.bucket.NewWriter(ctx, req.InImage, nil) + if err != nil { + return "", err + } + _, err = io.Copy(w, file) + if err != nil { + _ = w.Close() // ignore error + return "", err + } + if err := w.Close(); err != nil { + return "", err + } + + defer func() { + // if we can't send the request, the image will never be processed. + // Try to delete it. + if err != nil { + if err := f.bucket.Delete(ctx, req.InImage); err != nil { + log.Printf("deleting orphan image %q: %v", req.InImage, err) + } + } + }() + + // Publish the new order. + bytes, err := json.Marshal(req) + if err != nil { + return "", err + } + if err := f.requestTopic.Send(ctx, &pubsub.Message{Body: bytes}); err != nil { + return "", err + } + return id, nil +} + +// listOrders lists all the orders in the database. +func (f *frontend) listOrders(w http.ResponseWriter, r *http.Request) error { + if r.Method != "GET" { + http.Error(w, "bad method for listOrders: want GET", http.StatusBadRequest) + return nil + } + ctx := r.Context() + iter := f.coll.Query().Get(ctx) + var orders []*Order + for { + var ord Order + err := iter.Next(ctx, &ord) + if err == io.EOF { + break + } + if err != nil { + return err + } + orders = append(orders, &ord) + } + return executeTemplate(listTemplate, orders, w) +} + +func (f *frontend) showImage(w http.ResponseWriter, r *http.Request) error { + objKey := strings.TrimPrefix(r.URL.Path, "/show/") + reader, err := f.bucket.NewReader(r.Context(), objKey, nil) + if err != nil { + http.Error(w, fmt.Sprintf("file %q not found", objKey), http.StatusNotFound) + return nil + } + defer reader.Close() + if _, err := io.Copy(w, reader); err != nil { + log.Printf("copy from %q failed: %v", objKey, err) + } + return nil +} + +// newID creates a new unique ID for an incoming order. It uses the current +// second, formatted in a readable way. The resulting IDs sort nicely and are +// easy to read, but of course are not suitable for production because there +// could be more than one request in a second and because the clock can be +// reset to the past, resulting in duplicates. +func (f *frontend) newID() string { + return time.Now().Format("060102-150405") +} + +// executeTemplate executes t into a buffer using data, and if that succeeds it +// writes the bytes to w. +func executeTemplate(t *template.Template, data any, w http.ResponseWriter) error { + var buf bytes.Buffer + if err := t.Execute(&buf, data); err != nil { + return err + } + if _, err := buf.WriteTo(w); err != nil { + log.Printf("write failed: %v", err) + } + return nil +} diff --git a/go-cloud/samples/order/frontend_test.go b/go-cloud/samples/order/frontend_test.go new file mode 100644 index 000000000..e35271b15 --- /dev/null +++ b/go-cloud/samples/order/frontend_test.go @@ -0,0 +1,176 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "context" + "fmt" + "io" + "net/http/httptest" + "os" + "strings" + "testing" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/docstore" +) + +func TestOrderForm(t *testing.T) { + f, _, cleanup, err := setup(testConfig("OrderForm")) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + w := httptest.NewRecorder() + r := httptest.NewRequest("GET", "/orders/new", nil) + if err := f.orderForm(w, r); err != nil { + t.Fatal(err) + } + res := w.Result() + if res.StatusCode != 200 { + t.Fatalf("got %d, want 200", res.StatusCode) + } + wantb, err := os.ReadFile("order-form.htmlt") + if err != nil { + t.Fatal(err) + } + gotb, err := io.ReadAll(res.Body) + if err != nil { + t.Fatal(err) + } + res.Body.Close() + got := string(gotb) + want := string(wantb) + + if got != want { + t.Errorf("got %q, want %q", got, want) + } +} + +func TestCreateOrder(t *testing.T) { + f, _, cleanup, err := setup(testConfig("CreateOrder")) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + ctx := context.Background() + file := strings.NewReader("an image") + tm := time.Date(2019, 7, 1, 0, 0, 0, 0, time.Local) + id, err := f.doCreateOrder(ctx, "pat@example.com", file, tm) + if err != nil { + t.Fatal(err) + } + + r, err := f.bucket.NewReader(ctx, id+"-in", nil) + if err != nil { + t.Fatal(err) + } + defer r.Close() + gotb, err := io.ReadAll(r) + if err != nil { + t.Fatal(err) + } + gots := string(gotb) + wants := "an image" + if gots != wants { + t.Errorf("got %q, want %q", gots, wants) + } +} + +func TestListOrders(t *testing.T) { + f, _, cleanup, err := setup(testConfig("ListOrders")) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + ctx := context.Background() + // Clear the collection. + if err := clearCollection(ctx, f.coll); err != nil { + t.Fatal(err) + } + orders := []*Order{ + { + ID: "a", Email: "pat@example.com", InImage: "a-in", OutImage: "a-out", + CreateTime: time.Now().Add(-18 * time.Second), FinishTime: time.Now(), + }, + {ID: "b", Email: "mel@example.com", InImage: "b-in", CreateTime: time.Now()}, + } + actions := f.coll.Actions() + for _, ord := range orders { + actions.Put(ord) + } + if err := actions.Do(ctx); err != nil { + t.Fatal(err) + } + + w := httptest.NewRecorder() + r := httptest.NewRequest("GET", "/orders", nil) + if err := f.listOrders(w, r); err != nil { + t.Fatal(err) + } + + res := w.Result() + if res.StatusCode != 200 { + t.Fatalf("got %d, want 200", res.StatusCode) + } + gotb, err := io.ReadAll(res.Body) + if err != nil { + t.Fatal(err) + } + res.Body.Close() + got := string(gotb) + for _, ord := range orders { + if !strings.Contains(got, ord.ID) { + t.Errorf("got %q, should contain %q", got, ord.ID) + } + if !strings.Contains(got, ord.Email) { + t.Errorf("got %q, should contain %q", got, ord.Email) + } + } + url := `<a href="/show/a-out">a-out</a>` + if !strings.Contains(got, url) { + t.Errorf("got %q, should contain %q", got, url) + } +} + +func testConfig(name string) config { + reqURL := "mem://requests-" + name + return config{ + requestTopicURL: reqURL, + requestSubURL: reqURL, + bucketURL: "", // setup will use fileblob with a temporary dir + collectionURL: fmt.Sprintf("mem://orders-%s/ID", name), + } +} + +func clearCollection(ctx context.Context, coll *docstore.Collection) error { + iter := coll.Query().Get(ctx, "ID") + dels := coll.Actions() + for { + var order Order + err := iter.Next(ctx, &order) + if err == io.EOF { + break + } + if err != nil { + return err + } + dels.Delete(&order) + } + return dels.Do(ctx) +} diff --git a/go-cloud/samples/order/index.html b/go-cloud/samples/order/index.html new file mode 100644 index 000000000..60e05650d --- /dev/null +++ b/go-cloud/samples/order/index.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <title>Go CDK Image Conversion Sample</title> + <link href="https://fonts.googleapis.com/css?family=Roboto:400,400i,700&display=swap" rel="stylesheet"> + <link rel="stylesheet" type="text/css" href="/style.css"> + </head> + <body> + <header id="PageHeader"> + <a href="/" class="PageTitle-link"><h1 id="PageTitle">Go CDK Image Conversion Sample</h1></a> + </header> + <main id="PageContent"> + <div class="FrontPageActions"> + <button class="FrontPageActions-button" data-href="/orders/new">Convert an Image</button> + <button class="FrontPageActions-button" data-href="/orders">List Conversions</button> + </div> + </main> + <script type="text/javascript"> + // If an element with the attribute "data-href" is clicked, then redirect + // the browser to the value of the attribute instead of performing the + // default behavior. + document.addEventListener('click', function(e) { + if (e.target.dataset.href) { + window.location.href = e.target.dataset.href; + return false; + } + }); + </script> + </body> +</html> diff --git a/go-cloud/samples/order/list.htmlt b/go-cloud/samples/order/list.htmlt new file mode 100644 index 000000000..0357b1237 --- /dev/null +++ b/go-cloud/samples/order/list.htmlt @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <title>Orders - Go CDK Image Conversion Sample</title> + <link href="https://fonts.googleapis.com/css?family=Roboto:400,400i,700&display=swap" rel="stylesheet"> + <link rel="stylesheet" type="text/css" href="/style.css"> + </head> + <body> + <header id="PageHeader"> + <a href="/" class="PageTitle-link"><h1 id="PageTitle">Go CDK Image Conversion Sample</h1></a> + </header> + <main id="PageContent"> + <h1>Orders</h1> + {{if .}} + <table id="OrderList"> + <thead> + <tr> + <th scope="col" class="OrderList-heading">ID</th> + <th scope="col" class="OrderList-heading">Email</th> + <th scope="col" class="OrderList-heading">In</th> + <th scope="col" class="OrderList-heading">Out</th> + <th scope="col" class="OrderList-heading">Created</th> + <th scope="col" class="OrderList-heading">Finished</th> + <th scope="col" class="OrderList-heading">Note</th> + </tr> + </thead> + <tbody> + {{- range .}} + <tr> + <td class="OrderList-cell">{{.ID}}</td> + <td class="OrderList-cell">{{.Email}}</td> + <td class="OrderList-cell">{{.InImage}}</td> + <td class="OrderList-cell">{{with .OutImage}}<a href="/show/{{.}}">{{.}}</a>{{end}}</td> + <td class="OrderList-cell">{{with .CreateTime}}{{.Format "2006-01-02 03:04 AM"}}{{end}}</td> + <td class="OrderList-cell">{{with .FinishTime}}{{.Format "2006-01-02 03:04 AM"}}{{end}}</td> + <td class="OrderList-cell">{{.Note}}</td> + </tr> + {{- end}} + </tbody> + </table> + {{else}} + <p>No orders.</p> + {{end}} + </main> + </body> +</html> diff --git a/go-cloud/samples/order/order-form.htmlt b/go-cloud/samples/order/order-form.htmlt new file mode 100644 index 000000000..9c2c0d461 --- /dev/null +++ b/go-cloud/samples/order/order-form.htmlt @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <title>Create Order - Go CDK Image Conversion Sample</title> + <link href="https://fonts.googleapis.com/css?family=Roboto:400,400i,700&display=swap" rel="stylesheet"> + <link rel="stylesheet" type="text/css" href="/style.css"> + </head> + <body> + <header id="PageHeader"> + <a href="/" class="PageTitle-link"><h1 id="PageTitle">Go CDK Image Conversion Sample</h1></a> + </header> + <main id="PageContent"> + <h1>Submit an Image</h1> + <form id="OrderForm" action="/createOrder" method="post" enctype="multipart/form-data"> + <label class="OrderForm-label" for="OrderForm-email"> + Email: + </label> + <div class="OrderForm-widget"> + <input type="email" name="email" id="OrderForm-email" class="OrderForm-input"> + </div> + <label class="OrderForm-label" for="OrderForm-file"> + File: + </label> + <div class="OrderForm-widget"> + <input type="file" name="file" id="OrderForm-file" class="OrderForm-input"> + </div> + <div class="OrderForm-actions"> + <input type="submit" value="Submit" class="OrderForm-button"> + </div> + </form> + </main> + </body> +</html> diff --git a/go-cloud/samples/order/order.go b/go-cloud/samples/order/order.go new file mode 100644 index 000000000..1634f73a8 --- /dev/null +++ b/go-cloud/samples/order/order.go @@ -0,0 +1,163 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// This application processes orders for converting images to PNG format. It +// consists of two components: a frontend, which serves web pages that people +// can use to place and view orders; and a processor, which performs the +// conversions. This binary can run both together in one process (the default), +// or it can run either on its own. Either way, the two components: +// - communicate over a topic using the gocloud.dev/pubsub API; +// - write orders to a database using the gocloud.dev/docstore API; +// - and save image files to cloud storage using the gocloud.dev/blob API. +// +// This application assumes at-least-once processing. Make sure the pubsub +// implementation you provide to it has that behavior. +package main + +import ( + "context" + "flag" + "log" + "os" + "path/filepath" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" +) + +var ( + requestTopicURL = flag.String("request-topic", "mem://requests", "gocloud.dev/pubsub URL for request topic") + requestSubURL = flag.String("request-sub", "mem://requests", "gocloud.dev/pubsub URL for request subscription") + bucketURL = flag.String("bucket", "", "gocloud.dev/blob URL for image bucket") + collectionURL = flag.String("collection", "mem://orders/ID", "gocloud.dev/docstore URL for order collection") + + port = flag.Int("port", 10538, "HTTP port for frontend") + runFrontend = flag.Bool("frontend", true, "run the frontend") + runProcessor = flag.Bool("processor", true, "run the image processor") +) + +func main() { + flag.Parse() + conf := config{ + requestTopicURL: *requestTopicURL, + requestSubURL: *requestSubURL, + bucketURL: *bucketURL, + collectionURL: *collectionURL, + } + frontend, processor, cleanup, err := setup(conf) + if err != nil { + log.Fatal(err) + } + defer cleanup() + + // Run the frontend, or the processor, or both. + // When we want to run both, one of them has to run in a goroutine. + // So it's simpler to run both in goroutines, even if we only need + // to run one. + errc := make(chan error, 2) + if *runFrontend { + go func() { errc <- frontend.run(context.Background(), *port) }() + log.Printf("listening on port %d", *port) + } else { + errc <- nil + } + if *runProcessor { + go func() { errc <- processor.run(context.Background()) }() + log.Println("processing") + } else { + errc <- nil + } + // Each of the goroutines will send once to errc, so receive two values. + for i := 0; i < 2; i++ { + if err := <-errc; err != nil { + log.Fatal(err) + } + } +} + +// config describes the URLs for the resources used by the order application. +type config struct { + requestTopicURL string + requestSubURL string + bucketURL string + collectionURL string +} + +// setup opens all the necessary resources for the application. +func setup(conf config) (_ *frontend, _ *processor, cleanup func(), err error) { + addCleanup := func(f func()) { + old := cleanup + cleanup = func() { old(); f() } + } + + defer func() { + if err != nil { + cleanup() + cleanup = nil + } + }() + + ctx := context.Background() + cleanup = func() {} + + reqTopic, err := pubsub.OpenTopic(ctx, conf.requestTopicURL) + if err != nil { + return nil, nil, cleanup, err + } + addCleanup(func() { reqTopic.Shutdown(ctx) }) + + reqSub, err := pubsub.OpenSubscription(ctx, conf.requestSubURL) + if err != nil { + return nil, nil, cleanup, err + } + addCleanup(func() { reqSub.Shutdown(ctx) }) + + burl := conf.bucketURL + if burl == "" { + dir, err := os.MkdirTemp("", "gocdk-order") + if err != nil { + return nil, nil, cleanup, err + } + if os.PathSeparator == '\\' { + burl = "file:///" + filepath.ToSlash(dir) + } else { + burl = "file://" + dir + } + addCleanup(func() { os.Remove(dir) }) + } + bucket, err := blob.OpenBucket(ctx, burl) + if err != nil { + return nil, nil, cleanup, err + } + addCleanup(func() { bucket.Close() }) + + coll, err := docstore.OpenCollection(ctx, conf.collectionURL) + if err != nil { + return nil, nil, cleanup, err + } + addCleanup(func() { coll.Close() }) + + f := &frontend{ + requestTopic: reqTopic, + bucket: bucket, + coll: coll, + } + p := &processor{ + requestSub: reqSub, + bucket: bucket, + coll: coll, + } + return f, p, cleanup, nil +} diff --git a/go-cloud/samples/order/processor.go b/go-cloud/samples/order/processor.go new file mode 100644 index 000000000..950f587e4 --- /dev/null +++ b/go-cloud/samples/order/processor.go @@ -0,0 +1,195 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// A processor processes images in orders. It receives requests by +// subscribing to the requests topic, and writes responses to the response +// topic. +// +// At present, it just encodes input images into PNG format. + +package main + +import ( + "context" + "encoding/json" + "fmt" + "image" + _ "image/jpeg" + "image/png" + "log" + "math/rand" + "strings" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + _ "github.com/DataDog/iceberg-go/go-cloud/blob/fileblob" + "github.com/DataDog/iceberg-go/go-cloud/docstore" + _ "github.com/DataDog/iceberg-go/go-cloud/docstore/memdocstore" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + _ "github.com/DataDog/iceberg-go/go-cloud/pubsub/mempubsub" +) + +// A processor holds the state for processing images. +type processor struct { + requestSub *pubsub.Subscription + bucket *blob.Bucket + coll *docstore.Collection +} + +// run handles requests until the context is done or there is a fatal error. +func (p *processor) run(ctx context.Context) error { + for { + if err := p.handleRequest(ctx); err != nil { + return err + } + } +} + +// handleRequest handles one image-processing request. +// A non-nil error from handleRequest will end request processing. +func (p *processor) handleRequest(ctx context.Context) error { + msg, err := p.requestSub.Receive(ctx) + if err != nil { + // If we can't receive messages, we should stop processing. + return err + } + + var req OrderRequest + if err := json.Unmarshal(msg.Body, &req); err != nil { + // We can't unmarshal the message body. That could be due to a bug or + // change in the frontend, or maybe some other program is sending + // malformed messages. + + // Ack the message, because if we can't unmarshal it then no one else can either. + msg.Ack() + // Don't terminate processing; maybe this is just one bad message. + log.Printf("unmarshaling request: %v", err) + return nil + } + log.Printf("received %+v", req) + order, err := createOrFindOrder(ctx, p.coll, &req) + if err != nil { + // There was a problem with the database, perhaps due to the network. + // Nack the message; perhaps another processor can succeed. + if msg.Nackable() { + msg.Nack() + } + // Assume the database error is permanent: terminate processing. + return err + } + if order == nil { + log.Printf("duplicate finished order %v", req.ID) + // We've already processed this order, so ack the message. + msg.Ack() + return nil + } + // At this point, order is an unfinished order in the database. + // Process it. + err = p.processOrder(ctx, order) + // Any processing errors are saved as notes in the order. + if err != nil { + order.Note = fmt.Sprintf("processing failed: %v", err) + order.OutImage = "" + } + // Save the finished order to the database. + err = p.coll.Update(ctx, order, docstore.Mods{ + "OutImage": order.OutImage, + "Note": order.Note, + "FinishTime": time.Now(), + }) + if err != nil { + // We couldn't save the order to the database. + // Nack the message; perhaps another processor can succeed. + if msg.Nackable() { + msg.Nack() + } + // Assume the database error is permanent: terminate processing. + return err + } + // We've successfully processed the image. + msg.Ack() + return nil +} + +// createOrFindOrder either creates a new order from req (the usual case), or returns an +// existing unfinished order. It returns a nil *Order if the order exists and is +// finished, that is, this request message is a duplicate. +// createOrFindOrder returns a non-nil error only for database problems. +func createOrFindOrder(ctx context.Context, coll *docstore.Collection, req *OrderRequest) (*Order, error) { + // See if there is already a document for this order. + order := &Order{ID: req.ID} + err := coll.Get(ctx, order) + if err != nil { + if gcerrors.Code(err) != gcerrors.NotFound { + return nil, err + } + // Normal case: the order wasn't found, because it hasn't been created + // yet. Create it. + order = &Order{ + ID: req.ID, + Email: req.Email, + InImage: req.InImage, + CreateTime: req.CreateTime, + } + if err := coll.Create(ctx, order); err != nil { + return nil, err + } + return order, nil + } + if order.FinishTime.IsZero() { + // The order exists, but was not finished. Either it was abandoned by the processor that + // was working on it (probably because the processor died), or it is in progress. Assume + // that it was abandoned, and process it. + return order, nil + } + // The order exists and was finished. This is most likely the result of a pubsub redelivery. + // We simply ignore it. + return nil, nil +} + +// processOrder processes the order request. +func (p *processor) processOrder(ctx context.Context, order *Order) error { + // Read the input image from the bucket. + r, err := p.bucket.NewReader(ctx, order.InImage, nil) + if err != nil { + return err + } + + defer r.Close() + img, format, err := image.Decode(r) + if err != nil { + return err + } + + // Process and write the output image. + order.OutImage = fmt.Sprintf("%s-out.png", strings.TrimSuffix(order.InImage, "-in")) + w, err := p.bucket.NewWriter(ctx, order.OutImage, nil) + if err != nil { + return err + } + if err := png.Encode(w, img); err != nil { + w.Close() + return err + } + if err := w.Close(); err != nil { + return err + } + + // Pretend that the conversion takes some time. + time.Sleep(time.Duration(rand.Intn(5)+2) * time.Second) + + order.Note = fmt.Sprintf("converted from %s to png", format) + return nil +} diff --git a/go-cloud/samples/order/processor_test.go b/go-cloud/samples/order/processor_test.go new file mode 100644 index 000000000..20e0c998f --- /dev/null +++ b/go-cloud/samples/order/processor_test.go @@ -0,0 +1,126 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 main + +import ( + "context" + "encoding/json" + "io" + "os" + "path/filepath" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/pubsub" + _ "github.com/DataDog/iceberg-go/go-cloud/pubsub/mempubsub" +) + +func TestHandleRequest(t *testing.T) { + f, p, cleanup, err := setup(testConfig("ProcessorRun")) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + ctx := context.Background() + req := &OrderRequest{ID: "x"} + bytes, err := json.Marshal(req) + if err != nil { + t.Fatal(err) + } + if err := f.requestTopic.Send(ctx, &pubsub.Message{Body: bytes}); err != nil { + t.Fatal(err) + } + if err := p.handleRequest(ctx); err != nil { + t.Fatal(err) + } + // Just verify that there is an order "x" in the collection. + order := &Order{ID: "x"} + if err := p.coll.Get(ctx, order); err != nil { + t.Fatal(err) + } +} + +func TestProcessOrder(t *testing.T) { + _, p, cleanup, err := setup(testConfig("ProcessOrder")) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + ctx := context.Background() + for _, test := range []struct { + filename string + want *Order + wantErr bool + }{ + { + "cat1", + &Order{ + ID: "cat1", + Email: "joe@example.com", + InImage: "cat1", + OutImage: "cat1-out.png", + Note: "converted from jpeg to png", + }, + false, + }, + { + "bad-image", + nil, + true, + }, + } { + if err := copyFileToBucket("testdata/"+test.filename, p.bucket); err != nil { + t.Fatal(err) + } + got := &Order{ + ID: test.filename, + Email: "joe@example.com", + InImage: test.filename, + } + err := p.processOrder(ctx, got) + if err == nil && test.wantErr { + t.Errorf("%s: got nil, want error", test.filename) + } else if err != nil && !test.wantErr { + t.Errorf("%s: got error %v, want nil", test.filename, err) + } else if err == nil && !cmp.Equal(got, test.want) { + t.Errorf("%s:\ngot %+v\nwant %+v", test.filename, got, test.want) + } + } +} + +func copyFileToBucket(filename string, bucket *blob.Bucket) (err error) { + f, err := os.Open(filename) + if err != nil { + return err + } + defer f.Close() + + w, err := bucket.NewWriter(context.Background(), filepath.Base(filename), nil) + if err != nil { + return err + } + defer func() { + err2 := w.Close() + if err == nil { + err = err2 + } + }() + + _, err = io.Copy(w, f) + return err +} diff --git a/go-cloud/samples/order/style.css b/go-cloud/samples/order/style.css new file mode 100644 index 000000000..24116e08c --- /dev/null +++ b/go-cloud/samples/order/style.css @@ -0,0 +1,114 @@ +/* +Copyright 2019 The Go Cloud Development Kit 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 + + https://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. +*/ + +html { + font: 20px/1.2 'Roboto', sans-serif; + margin: 0; + padding: 0; +} +body { + background: #555759; + color: #000; + margin: 0; + padding: 0; +} +#PageHeader { + background: #00add8; + margin: 0; + padding: 0; +} +@media (max-width: 1024px) { + /* Don't use a backdrop effect on smaller screen. */ + body { + background: white; + } +} +#PageHeader { + padding: 1rem; +} +#PageTitle { + color: white; + font-size: 2.5rem; + margin: 0 2rem; + padding: 0; +} +.PageTitle-link { + text-decoration: none; +} +#PageContent { + background: white; + border-radius: 3px; + box-sizing: border-box; + margin: 1rem auto; + min-height: 10rem; + max-width: 50rem; + padding: 0.5rem 2rem 1rem; +} +@media (max-width: 1024px) { + /* Don't use a backdrop effect on smaller screen. */ + #PageContent { + background: none; + border-radius: 0; + margin: 0 auto 1rem; + } +} +.FrontPageActions { + margin-top: 2rem; + text-align: center; + vertical-align: middle; +} +.FrontPageActions-button { + font: 1.5rem 'Roboto', sans-serif; + padding: 0.3rem; + width: 15rem; +} +input { + font: 20px/1.2 'Roboto', sans-serif; +} +#OrderForm { + width: 50%; +} +.OrderForm-label { + display: block; + font-weight: bold; + margin: 0 0 0.2rem; +} +.OrderForm-widget { + margin: 0 0 0.5rem; + width: 100%; +} +.OrderForm-input { + margin: 0; + width: 100%; +} +.OrderForm-actions { + margin: 1rem 0; + text-align: right; +} +.OrderForm-button { + padding: 0.25rem 1rem; +} +#OrderList { + border-collapse: collapse; +} +.OrderList-heading { + padding: 0.25rem 0.5rem; +} +.OrderList-cell { + border-bottom: 1px solid black; + border-top: 1px solid black; + padding: 0.25rem 0.5rem; +} diff --git a/go-cloud/samples/order/testdata/bad-image b/go-cloud/samples/order/testdata/bad-image new file mode 100644 index 000000000..7ba4f07a5 --- /dev/null +++ b/go-cloud/samples/order/testdata/bad-image @@ -0,0 +1 @@ +This is not an image. diff --git a/go-cloud/samples/order/testdata/cat1 b/go-cloud/samples/order/testdata/cat1 new file mode 100644 index 000000000..a260caf6e Binary files /dev/null and b/go-cloud/samples/order/testdata/cat1 differ diff --git a/go-cloud/samples/server/main.go b/go-cloud/samples/server/main.go new file mode 100644 index 000000000..df78cf013 --- /dev/null +++ b/go-cloud/samples/server/main.go @@ -0,0 +1,145 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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. + +// Command server runs a simple HTTP server with integrated Cloud Trace (OpenTelemetry) +// and health checks. +package main + +import ( + "context" + "errors" + "flag" + "fmt" + "go.opentelemetry.io/otel" + "log" + "net/http" + "sync" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/server" + "github.com/DataDog/iceberg-go/go-cloud/server/health" + "github.com/DataDog/iceberg-go/go-cloud/server/sdserver" +) + +// GlobalMonitoredResource implements monitoredresource.Interface to provide a +// basic global resource based on the project ID. If you're running this sample +// on GCE or EC2, you may prefer to use monitoredresource.Autodetect() instead. +type GlobalMonitoredResource struct { + projectID string +} + +// MonitoredResource returned the monitored resource. +func (g GlobalMonitoredResource) MonitoredResource() (string, map[string]string) { + return "global", map[string]string{"project_id": g.projectID} +} + +func helloHandler(w http.ResponseWriter, req *http.Request) { + fmt.Fprintf(w, "Hello\n") +} + +func mainHandler(w http.ResponseWriter, req *http.Request) { + fmt.Fprintf(w, "Welcome to the home page!\n") +} + +// customHealthCheck is an example health check. It implements the +// health.Checker interface and reports the server is healthy when the healthy +// field is set to true. +type customHealthCheck struct { + mu sync.RWMutex + healthy bool +} + +func (h *customHealthCheck) CheckHealth() error { + h.mu.RLock() + defer h.mu.RUnlock() + if !h.healthy { + return errors.New("not ready yet") + } + return nil +} + +func main() { + addr := flag.String("listen", ":8080", "HTTP port to listen on") + doTrace := flag.Bool("trace", true, "Export traces to Stackdriver") + flag.Parse() + + ctx := context.Background() + credentials, err := gcp.DefaultCredentials(ctx) + if err != nil { + log.Fatal(err) + } + + projectID, err := gcp.DefaultProjectID(credentials) + if err != nil { + log.Fatal(err) + } + + if *doTrace { + fmt.Println("Exporting traces to Stackdriver") + + traceSampler := sdserver.NewTraceSampler(ctx) + + spanExporter, err0 := sdserver.NewTraceExporter(projectID) + if err0 != nil { + log.Fatal(err0) + } + tp, cleanup, err0 := sdserver.NewTraceProvider(ctx, spanExporter, traceSampler) + if err0 != nil { + log.Fatal(err0) + } + defer cleanup() + otel.SetTracerProvider(tp) + + metricsReader, err0 := sdserver.NewMetricsReader(projectID) + if err0 != nil { + log.Fatal(err0) + } + mp, cleanup2, err0 := sdserver.NewMeterProvider(ctx, metricsReader) + if err0 != nil { + log.Fatal(err0) + } + defer cleanup2() + otel.SetMeterProvider(mp) + } + + mux := http.NewServeMux() + mux.HandleFunc("/hello", helloHandler) + mux.HandleFunc("/", mainHandler) + + // healthCheck will report the server is unhealthy for 10 seconds after + // startup, and as healthy henceforth. Check the /healthz/readiness + // HTTP path to see readiness. + healthCheck := new(customHealthCheck) + time.AfterFunc(10*time.Second, func() { + healthCheck.mu.Lock() + defer healthCheck.mu.Unlock() + healthCheck.healthy = true + }) + + options := &server.Options{ + RequestLogger: sdserver.NewRequestLogger(), + HealthChecks: []health.Checker{healthCheck}, + + Driver: &server.DefaultDriver{}, + } + + s := server.New(mux, options) + fmt.Printf("Listening on %s\n", *addr) + + err = s.ListenAndServe(*addr) + if err != nil { + log.Fatal(err) + } +} diff --git a/go-cloud/samples/tutorial/README.md b/go-cloud/samples/tutorial/README.md new file mode 100644 index 000000000..07f0fd163 --- /dev/null +++ b/go-cloud/samples/tutorial/README.md @@ -0,0 +1,5 @@ +# Getting Started With The Go Cloud Development Kit + +This is the source directory for the [command-line uploader tutorial][]. + +[command-line uploader tutorial]: https://gocloud.dev/tutorials/cli-uploader/ diff --git a/go-cloud/samples/tutorial/gopher.png b/go-cloud/samples/tutorial/gopher.png new file mode 100644 index 000000000..1eb81f0be Binary files /dev/null and b/go-cloud/samples/tutorial/gopher.png differ diff --git a/go-cloud/samples/tutorial/main.go b/go-cloud/samples/tutorial/main.go new file mode 100644 index 000000000..f93b8f2b0 --- /dev/null +++ b/go-cloud/samples/tutorial/main.go @@ -0,0 +1,64 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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. + +// Command upload saves files to blob storage on GCP, AWS, and Azure. +package main + +import ( + "context" + "log" + "os" + + "github.com/DataDog/iceberg-go/go-cloud/blob" + + // Import the blob packages we want to be able to open. + _ "github.com/DataDog/iceberg-go/go-cloud/blob/azureblob" + _ "github.com/DataDog/iceberg-go/go-cloud/blob/gcsblob" + _ "github.com/DataDog/iceberg-go/go-cloud/blob/s3blob" +) + +func main() { + // Define our input. + if len(os.Args) != 3 { + log.Fatal("usage: upload BUCKET_URL FILE") + } + bucketURL := os.Args[1] + file := os.Args[2] + + ctx := context.Background() + // Open a connection to the bucket. + b, err := blob.OpenBucket(ctx, bucketURL) + if err != nil { + log.Fatalf("Failed to setup bucket: %s", err) + } + defer b.Close() + + // Prepare the file for upload. + data, err := os.ReadFile(file) + if err != nil { + log.Fatalf("Failed to read file: %s", err) + } + + w, err := b.NewWriter(ctx, file, nil) + if err != nil { + log.Fatalf("Failed to obtain writer: %s", err) + } + _, err = w.Write(data) + if err != nil { + log.Fatalf("Failed to write to bucket: %s", err) + } + if err = w.Close(); err != nil { + log.Fatalf("Failed to close: %s", err) + } +} diff --git a/go-cloud/samples/wire/README.md b/go-cloud/samples/wire/README.md new file mode 100644 index 000000000..f24607c16 --- /dev/null +++ b/go-cloud/samples/wire/README.md @@ -0,0 +1,3 @@ +# Wire Tutorial has moved + +The Wire Tutorial has moved to [the Wire repository](https://github.com/google/wire/tree/master/_tutorial). diff --git a/go-cloud/secrets/awskms/example_test.go b/go-cloud/secrets/awskms/example_test.go new file mode 100644 index 000000000..5b2205813 --- /dev/null +++ b/go-cloud/secrets/awskms/example_test.go @@ -0,0 +1,82 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awskms_test + +import ( + "context" + "log" + + "github.com/aws/aws-sdk-go-v2/config" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "github.com/DataDog/iceberg-go/go-cloud/secrets/awskms" +) + +func ExampleOpenKeeper() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // Establish a AWS V2 Config. + // See https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ for more info. + ctx := context.Background() + cfg, err := config.LoadDefaultConfig(ctx) + if err != nil { + log.Fatal(err) + } + + // Get a client to use with the KMS API. + client, err := awskms.Dial(cfg) + if err != nil { + log.Fatal(err) + } + + // Construct a *secrets.Keeper. + keeper := awskms.OpenKeeper(client, "alias/test-secrets", nil) + defer keeper.Close() +} + +func Example_openFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/secrets/awskms" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Use one of the following: + + // 1. By ID. + keeperByID, err := secrets.OpenKeeper(ctx, + "awskms://1234abcd-12ab-34cd-56ef-1234567890ab?region=us-east-1") + if err != nil { + log.Fatal(err) + } + defer keeperByID.Close() + + // 2. By alias. + keeperByAlias, err := secrets.OpenKeeper(ctx, + "awskms://alias/ExampleAlias?region=us-east-1") + if err != nil { + log.Fatal(err) + } + defer keeperByAlias.Close() + + // 3. By ARN. Note that ARN may contain ":" characters, which cannot be escaped + // in the Host part of a URL, so the "awskms:///<ARN>" form should be used. + const arn = "arn:aws:kms:us-east-1:111122223333:key/" + + "1234abcd-12ab-34bc-56ef-1234567890ab" + keeperByARN, err := secrets.OpenKeeper(ctx, + "awskms:///"+arn+"?region=us-east-1") + if err != nil { + log.Fatal(err) + } + defer keeperByARN.Close() +} diff --git a/go-cloud/secrets/awskms/kms.go b/go-cloud/secrets/awskms/kms.go new file mode 100644 index 000000000..e37f2d3f1 --- /dev/null +++ b/go-cloud/secrets/awskms/kms.go @@ -0,0 +1,239 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awskms provides a secrets implementation backed by AWS KMS. +// Use OpenKeeper to construct a *secrets.Keeper. +// +// # URLs +// +// For secrets.OpenKeeper, awskms registers for the scheme "awskms". +// The default URL opener will use an AWS session with the default credentials +// and configuration. +// +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// awskms exposes the following type for As: +// - Error: any error type returned by the service, notably smithy.APIError +package awskms // import "gocloud.dev/secrets/awskms" + +import ( + "context" + "errors" + "fmt" + "net/url" + "path" + "strings" + "sync" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/kms" + "github.com/aws/aws-sdk-go-v2/service/kms/types" + "github.com/aws/smithy-go" + "github.com/google/wire" + gcaws "github.com/DataDog/iceberg-go/go-cloud/aws" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/secrets" +) + +func init() { + secrets.DefaultURLMux().RegisterKeeper(Scheme, new(lazySessionOpener)) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + Dial, +) + +// Dial gets an AWS KMS service client using the AWS SDK V2. +func Dial(cfg aws.Config) (*kms.Client, error) { + return kms.NewFromConfig(cfg), nil +} + +var DialV2 = Dial + +// lazySessionOpener obtains the AWS session from the environment on the first +// call to OpenKeeperURL. +type lazySessionOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazySessionOpener) OpenKeeperURL(ctx context.Context, u *url.URL) (*secrets.Keeper, error) { + opener := &URLOpener{} + return opener.OpenKeeperURL(ctx, u) +} + +// Scheme is the URL scheme awskms registers its URLOpener under on secrets.DefaultMux. +const Scheme = "awskms" + +// URLOpener opens AWS KMS URLs like "awskms://keyID" or "awskms:///keyID". +// +// The URL Host + Path are used as the key ID, which can be in the form of an +// Amazon Resource Name (ARN), alias name, or alias ARN. See +// https://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html#find-cmk-id-arn +// for more details. Note that ARNs may contain ":" characters, which cannot be +// escaped in the Host part of a URL, so the "awskms:///<ARN>" form should be used. +// +// See https://pkg.go.dev/gocloud.dev/aws#V2ConfigFromURLParams. +// +// EncryptionContext key/value pairs can be provided by providing URL parameters prefixed +// with "context_"; e.g., "...&context_abc=foo&context_def=bar" would result in +// an EncryptionContext of {abc=foo, def=bar}. +// See https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context. +type URLOpener struct { + // Options specifies the options to pass to OpenKeeper. + // EncryptionContext parameters from the URL are merged in. + Options KeeperOptions +} + +// addEncryptionContextFromURLParams merges any EncryptionContext URL parameters from +// u into opts.EncryptionParameters. +// It removes the processed URL parameters from u. +func addEncryptionContextFromURLParams(opts *KeeperOptions, u url.Values) error { + for k, vs := range u { + if strings.HasPrefix(k, "context_") { + if len(vs) != 1 { + return fmt.Errorf("open keeper: EncryptionContext URL parameters %q must have exactly 1 value", k) + } + u.Del(k) + if opts.EncryptionContext == nil { + opts.EncryptionContext = map[string]string{} + } + opts.EncryptionContext[k[8:]] = vs[0] + } + } + return nil +} + +// OpenKeeperURL opens an AWS KMS Keeper based on u. +func (o *URLOpener) OpenKeeperURL(ctx context.Context, u *url.URL) (*secrets.Keeper, error) { + // A leading "/" means the Host was empty; trim the slash. + // This is so that awskms:///foo:bar results in "foo:bar" instead of + // "/foo:bar". + keyID := strings.TrimPrefix(path.Join(u.Host, u.Path), "/") + + queryParams := u.Query() + opts := o.Options + if err := addEncryptionContextFromURLParams(&opts, queryParams); err != nil { + return nil, err + } + + cfg, err := gcaws.V2ConfigFromURLParams(ctx, queryParams) + if err != nil { + return nil, fmt.Errorf("open keeper %v: %v", u, err) + } + client, err := Dial(cfg) + if err != nil { + return nil, err + } + return OpenKeeper(client, keyID, &opts), nil +} + +// OpenKeeper returns a *secrets.Keeper that uses AWS KMS, using SDK v2. +// The key ID can be in the form of an Amazon Resource Name (ARN), alias +// name, or alias ARN. See +// https://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html#find-cmk-id-arn +// for more details. +// See the package documentation for an example. +func OpenKeeper(client *kms.Client, keyID string, opts *KeeperOptions) *secrets.Keeper { + if opts == nil { + opts = &KeeperOptions{} + } + return secrets.NewKeeper(&keeper{ + keyID: keyID, + client: client, + opts: *opts, + }) +} + +var OpenKeeperV2 = OpenKeeper + +type keeper struct { + keyID string + opts KeeperOptions + client *kms.Client +} + +// Decrypt decrypts the ciphertext into a plaintext. +func (k *keeper) Decrypt(ctx context.Context, ciphertext []byte) ([]byte, error) { + result, err := k.client.Decrypt(ctx, &kms.DecryptInput{ + CiphertextBlob: ciphertext, + EncryptionContext: k.opts.EncryptionContext, + }) + if err != nil { + return nil, err + } + return result.Plaintext, nil +} + +// Encrypt encrypts the plaintext into a ciphertext. +func (k *keeper) Encrypt(ctx context.Context, plaintext []byte) ([]byte, error) { + result, err := k.client.Encrypt(ctx, &kms.EncryptInput{ + KeyId: aws.String(k.keyID), + Plaintext: plaintext, + EncryptionContext: k.opts.EncryptionContext, + }) + if err != nil { + return nil, err + } + return result.CiphertextBlob, nil +} + +// Close implements driver.Keeper.Close. +func (k *keeper) Close() error { return nil } + +// ErrorAs implements driver.Keeper.ErrorAs. +func (k *keeper) ErrorAs(err error, i any) bool { + return errors.As(err, i) +} + +// ErrorCode implements driver.ErrorCode. +func (k *keeper) ErrorCode(err error) gcerrors.ErrorCode { + var ae smithy.APIError + if !errors.As(err, &ae) { + return gcerr.Unknown + } + code := ae.ErrorCode() + ec, ok := errorCodeMap[code] + if !ok { + return gcerr.Unknown + } + return ec +} + +var errorCodeMap = map[string]gcerrors.ErrorCode{ + (&types.NotFoundException{}).ErrorCode(): gcerrors.NotFound, + (&types.InvalidCiphertextException{}).ErrorCode(): gcerrors.InvalidArgument, + (&types.InvalidKeyUsageException{}).ErrorCode(): gcerrors.InvalidArgument, + (&types.KMSInternalException{}).ErrorCode(): gcerrors.Internal, + (&types.KMSInvalidStateException{}).ErrorCode(): gcerrors.FailedPrecondition, + (&types.DisabledException{}).ErrorCode(): gcerrors.PermissionDenied, + (&types.InvalidGrantTokenException{}).ErrorCode(): gcerrors.PermissionDenied, + (&types.KeyUnavailableException{}).ErrorCode(): gcerrors.ResourceExhausted, + (&types.DependencyTimeoutException{}).ErrorCode(): gcerrors.DeadlineExceeded, +} + +// KeeperOptions controls Keeper behaviors. +// It is provided for future extensibility. +type KeeperOptions struct { + // EncryptionContext parameters. + // See https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context. + EncryptionContext map[string]string +} diff --git a/go-cloud/secrets/awskms/kms_test.go b/go-cloud/secrets/awskms/kms_test.go new file mode 100644 index 000000000..c89ad3c3e --- /dev/null +++ b/go-cloud/secrets/awskms/kms_test.go @@ -0,0 +1,216 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 awskms + +import ( + "context" + "errors" + "fmt" + "net/url" + "testing" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/kms" + "github.com/aws/aws-sdk-go-v2/service/kms/types" + "github.com/aws/smithy-go" + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "github.com/DataDog/iceberg-go/go-cloud/secrets/driver" + "github.com/DataDog/iceberg-go/go-cloud/secrets/drivertest" +) + +const ( + keyID1 = "alias/test-secrets" + keyID2 = "alias/test-secrets2" + region = "us-east-2" +) + +type harness struct { + client *kms.Client + close func() +} + +func (h *harness) MakeDriver(ctx context.Context) (driver.Keeper, driver.Keeper, error) { + return &keeper{keyID: keyID1, client: h.client}, &keeper{keyID: keyID2, client: h.client}, nil +} + +func (h *harness) Close() { + h.close() +} + +// Lists all existing aliases in the account, to see if we need to create one. +func listExistingAliases(ctx context.Context, client *kms.Client) (map[string]bool, error) { + existing := map[string]bool{} + var nextMarker *string + for { + resp, err := client.ListAliases(ctx, &kms.ListAliasesInput{Marker: nextMarker}) + if err != nil { + return nil, fmt.Errorf("failed to list aliases: %w", err) + } + for _, alias := range resp.Aliases { + existing[*alias.AliasName] = true + } + if !resp.Truncated { + break + } + nextMarker = resp.NextMarker + } + return existing, nil +} + +func createKey(ctx context.Context, client *kms.Client, keyID string) error { + createKeyResult, err := client.CreateKey(ctx, &kms.CreateKeyInput{}) + if err != nil { + return fmt.Errorf("failed to create key %q: %w", keyID, err) + } + if _, err := client.CreateAlias(ctx, &kms.CreateAliasInput{ + AliasName: aws.String(keyID), + TargetKeyId: createKeyResult.KeyMetadata.KeyId, + }); err != nil { + return fmt.Errorf("failed to create alias for key %q: %w", keyID, err) + } + return nil +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + cfg, _, done, _ := setup.NewAWSv2Config(ctx, t, region, false) + client := kms.NewFromConfig(cfg) + + // Create the keys we need if they don't exist. + existing, err := listExistingAliases(ctx, client) + if err != nil { + return nil, err + } + if !existing[keyID1] { + if err := createKey(ctx, client, keyID1); err != nil { + return nil, err + } + } + if !existing[keyID2] { + if err := createKey(ctx, client, keyID2); err != nil { + return nil, err + } + } + return &harness{ + client: client, + close: done, + }, nil +} + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct { +} + +func (v verifyAs) Name() string { + return "verify As function" +} + +func (v verifyAs) ErrorCheck(k *secrets.Keeper, err error) error { + var e smithy.APIError + if !k.ErrorAs(err, &e) { + return errors.New("Keeper.ErrorAs failed") + } + code := e.ErrorCode() + want := (&types.InvalidCiphertextException{}).ErrorCode() + if code != want { + return fmt.Errorf("got %q, want %q", code, want) + } + return nil +} + +// KMS-specific tests. + +func TestEncryptionContext(t *testing.T) { + tests := []struct { + Existing map[string]string + URL string + WantErr bool + Want map[string]string + }{ + // None before or after. + {nil, "http://foo", false, nil}, + // New parameter. + {nil, "http://foo?context_foo=bar", false, map[string]string{"foo": "bar"}}, + // 2 new parameters. + {nil, "http://foo?context_foo=bar&context_abc=baz", false, map[string]string{"foo": "bar", "abc": "baz"}}, + // Multiple values. + {nil, "http://foo?context_foo=bar&context_foo=baz", true, nil}, + // Existing, no new. + {map[string]string{"foo": "bar"}, "http://foo", false, map[string]string{"foo": "bar"}}, + // No-conflict merge. + {map[string]string{"foo": "bar"}, "http://foo?context_abc=baz", false, map[string]string{"foo": "bar", "abc": "baz"}}, + // Overwrite merge. + {map[string]string{"foo": "bar"}, "http://foo?context_foo=baz", false, map[string]string{"foo": "baz"}}, + } + for _, test := range tests { + t.Run(fmt.Sprintf("existing %v URL %v", test.Existing, test.URL), func(t *testing.T) { + opts := KeeperOptions{ + EncryptionContext: test.Existing, + } + u, err := url.Parse(test.URL) + if err != nil { + t.Fatal(err) + } + err = addEncryptionContextFromURLParams(&opts, u.Query()) + if (err != nil) != test.WantErr { + t.Fatalf("got err %v, want error? %v", err, test.WantErr) + } + if diff := cmp.Diff(opts.EncryptionContext, test.Want); diff != "" { + t.Errorf("diff %v", diff) + } + }) + } +} + +func TestOpenKeeper(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK, by alias. + {"awskms://alias/my-key", false}, + // OK, by ARN with empty Host. + {"awskms:///arn:aws:kms:us-east-1:932528106278:alias/gocloud-test", false}, + // OK, by ARN with empty Host. + {"awskms:///arn:aws:kms:us-east-1:932528106278:key/8be0dcc5-da0a-4164-a99f-649015e344b5", false}, + // OK, overriding region. + {"awskms://alias/my-key?region=us-west1", false}, + // OK, adding EncryptionContext. + {"awskms://alias/my-key?context_abc=foo&context_def=bar", false}, + // Multiple values for an EncryptionContext. + {"awskms://alias/my-key?context_abc=foo&context_abc=bar", true}, + // Unknown parameter. + {"awskms://alias/my-key?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + keeper, err := secrets.OpenKeeper(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if err == nil { + if err = keeper.Close(); err != nil { + t.Errorf("%s: got error during close: %v", test.URL, err) + } + } + } +} diff --git a/go-cloud/secrets/awskms/testdata/TestConformance/TestAs/verify_As_function.replay b/go-cloud/secrets/awskms/testdata/TestConformance/TestAs/verify_As_function.replay new file mode 100644 index 000000000..8a6f637ca --- /dev/null +++ b/go-cloud/secrets/awskms/testdata/TestConformance/TestAs/verify_As_function.replay @@ -0,0 +1,175 @@ +{ + "Initial": "AQAAAA7gDMeJEYAxmAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "431e5776f3f73e0d", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.ListAliases" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "e30=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "2035" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:01 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "5e81e3ed-ef5a-4ebd-8fa0-5dbef1e2e51a" + ] + }, + "Body": "eyJBbGlhc0NvdW50IjoxNSwiQWxpYXNlcyI6W3siQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9keW5hbW9kYiIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9keW5hbW9kYiJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9lYnMiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZWJzIiwiQ3JlYXRpb25EYXRlIjoxLjU5MjQxMjAxODUyMUU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNTkyNDEyMDE4NTIxRTksIlRhcmdldEtleUlkIjoiZmI0NTdlOGUtNTQ2ZS00MDMzLWE1YWEtZThhZWRkYzlkODUxIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VzIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VzIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2dsdWUiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZ2x1ZSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9raW5lc2lzdmlkZW8iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mva2luZXNpc3ZpZGVvIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3JkcyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9yZHMifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnQiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvcmVkc2hpZnQifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnR0ZXN0IiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL3JlZHNoaWZ0dGVzdCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zMyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zMyJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkNyZWF0aW9uRGF0ZSI6MS43NDM0NTM4NDE2NjhFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc0MzQ1Mzg0MTY2OEU5LCJUYXJnZXRLZXlJZCI6ImY1NDQwMjcyLWEyYzktNGU3Ny05N2Y4LTdjYjE4NzA2NmViZCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zc20iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mvc3NtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3hyYXkiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MveHJheSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkFsaWFzTmFtZSI6ImFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkNyZWF0aW9uRGF0ZSI6MS43NTI4NzgxMjgwMzZFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc1Mjg3ODEyODAzNkU5LCJUYXJnZXRLZXlJZCI6IjgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0czIiLCJBbGlhc05hbWUiOiJhbGlhcy90ZXN0LXNlY3JldHMyIiwiQ3JlYXRpb25EYXRlIjoxLjc1Mjg3OTE3Nzc0NkU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNzUyODc5MTc3NzQ2RTksIlRhcmdldEtleUlkIjoiN2VkM2VkOTgtMDM2MS00ZWQyLWExN2EtOTE1YjBlZjJlOWJmIn1dLCJUcnVuY2F0ZWQiOmZhbHNlfQ==" + } + }, + { + "ID": "55b00d88c4a462e5", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Decrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDaXBoZXJ0ZXh0QmxvYiI6ImJXRnNabTl5YldWa0lHTnBjR2hsY2lCdFpYTnpZV2RsIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:01 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "84fde983-2fa0-4aee-af75-f2b0db55796a" + ] + }, + "Body": "eyJfX3R5cGUiOiJJbnZhbGlkQ2lwaGVydGV4dEV4Y2VwdGlvbiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/awskms/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/secrets/awskms/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..b6cb9af24 --- /dev/null +++ b/go-cloud/secrets/awskms/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,175 @@ +{ + "Initial": "AQAAAA7gDMeJIF8A8AAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "09eb9700084058bd", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.ListAliases" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "e30=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "2035" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:01 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "c59e13d3-20b6-4cd3-938c-481e730fe9f5" + ] + }, + "Body": "eyJBbGlhc0NvdW50IjoxNSwiQWxpYXNlcyI6W3siQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9keW5hbW9kYiIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9keW5hbW9kYiJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9lYnMiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZWJzIiwiQ3JlYXRpb25EYXRlIjoxLjU5MjQxMjAxODUyMUU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNTkyNDEyMDE4NTIxRTksIlRhcmdldEtleUlkIjoiZmI0NTdlOGUtNTQ2ZS00MDMzLWE1YWEtZThhZWRkYzlkODUxIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VzIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VzIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2dsdWUiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZ2x1ZSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9raW5lc2lzdmlkZW8iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mva2luZXNpc3ZpZGVvIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3JkcyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9yZHMifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnQiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvcmVkc2hpZnQifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnR0ZXN0IiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL3JlZHNoaWZ0dGVzdCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zMyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zMyJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkNyZWF0aW9uRGF0ZSI6MS43NDM0NTM4NDE2NjhFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc0MzQ1Mzg0MTY2OEU5LCJUYXJnZXRLZXlJZCI6ImY1NDQwMjcyLWEyYzktNGU3Ny05N2Y4LTdjYjE4NzA2NmViZCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zc20iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mvc3NtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3hyYXkiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MveHJheSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkFsaWFzTmFtZSI6ImFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkNyZWF0aW9uRGF0ZSI6MS43NTI4NzgxMjgwMzZFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc1Mjg3ODEyODAzNkU5LCJUYXJnZXRLZXlJZCI6IjgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0czIiLCJBbGlhc05hbWUiOiJhbGlhcy90ZXN0LXNlY3JldHMyIiwiQ3JlYXRpb25EYXRlIjoxLjc1Mjg3OTE3Nzc0NkU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNzUyODc5MTc3NzQ2RTksIlRhcmdldEtleUlkIjoiN2VkM2VkOTgtMDM2MS00ZWQyLWExN2EtOTE1YjBlZjJlOWJmIn1dLCJUcnVuY2F0ZWQiOmZhbHNlfQ==" + } + }, + { + "ID": "a78784116441c928", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "53" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Decrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDaXBoZXJ0ZXh0QmxvYiI6ImJXRnNabTl5YldWa0lHTnBjR2hsY2lCdFpYTnpZV2RsIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:01 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "be3173f6-e83f-40bc-aadc-505b480eb924" + ] + }, + "Body": "eyJfX3R5cGUiOiJJbnZhbGlkQ2lwaGVydGV4dEV4Y2VwdGlvbiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/awskms/testdata/TestConformance/TestDecryptMalformedError.replay b/go-cloud/secrets/awskms/testdata/TestConformance/TestDecryptMalformedError.replay new file mode 100644 index 000000000..d9c4d296f --- /dev/null +++ b/go-cloud/secrets/awskms/testdata/TestConformance/TestDecryptMalformedError.replay @@ -0,0 +1,367 @@ +{ + "Initial": "AQAAAA7gDMeINCRokgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "554eed04c5fd071d", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.ListAliases" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "e30=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "2035" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:01 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "cb733103-df1c-498a-b13c-ad5f7c0e0ab1" + ] + }, + "Body": "eyJBbGlhc0NvdW50IjoxNSwiQWxpYXNlcyI6W3siQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9keW5hbW9kYiIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9keW5hbW9kYiJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9lYnMiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZWJzIiwiQ3JlYXRpb25EYXRlIjoxLjU5MjQxMjAxODUyMUU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNTkyNDEyMDE4NTIxRTksIlRhcmdldEtleUlkIjoiZmI0NTdlOGUtNTQ2ZS00MDMzLWE1YWEtZThhZWRkYzlkODUxIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VzIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VzIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2dsdWUiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZ2x1ZSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9raW5lc2lzdmlkZW8iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mva2luZXNpc3ZpZGVvIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3JkcyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9yZHMifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnQiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvcmVkc2hpZnQifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnR0ZXN0IiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL3JlZHNoaWZ0dGVzdCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zMyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zMyJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkNyZWF0aW9uRGF0ZSI6MS43NDM0NTM4NDE2NjhFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc0MzQ1Mzg0MTY2OEU5LCJUYXJnZXRLZXlJZCI6ImY1NDQwMjcyLWEyYzktNGU3Ny05N2Y4LTdjYjE4NzA2NmViZCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zc20iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mvc3NtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3hyYXkiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MveHJheSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkFsaWFzTmFtZSI6ImFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkNyZWF0aW9uRGF0ZSI6MS43NTI4NzgxMjgwMzZFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc1Mjg3ODEyODAzNkU5LCJUYXJnZXRLZXlJZCI6IjgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0czIiLCJBbGlhc05hbWUiOiJhbGlhcy90ZXN0LXNlY3JldHMyIiwiQ3JlYXRpb25EYXRlIjoxLjc1Mjg3OTE3Nzc0NkU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNzUyODc5MTc3NzQ2RTksIlRhcmdldEtleUlkIjoiN2VkM2VkOTgtMDM2MS00ZWQyLWExN2EtOTE1YjBlZjJlOWJmIn1dLCJUcnVuY2F0ZWQiOmZhbHNlfQ==" + } + }, + { + "ID": "d8c8ecfed2f325eb", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Encrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJLZXlJZCI6ImFsaWFzL3Rlc3Qtc2VjcmV0cyIsIlBsYWludGV4dCI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "381" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:01 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "42bfefd0-bef1-43ba-bda9-7fa5a448b6b3" + ] + }, + "Body": "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGlSUHF2ZmE0SEVUOTUzbld2b21mcnN2YTJWUmxiTnl4bFNvSzVmRG84ZW5BRmRVclMydmx1em1jSllUQkFlRSsrdEFBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTUxPV1FLbHhEdlBkNU5LRGxBZ0VRZ0RDTDFoZjZUOXRIUU5aczFNbnI0ZkZxVXdVUmM2VFF2eWl6RTBWdUxVYW5EYjUxQUFQalJaODBJeU00QWJVbG9BZz0iLCJFbmNyeXB0aW9uQWxnb3JpdGhtIjoiU1lNTUVUUklDX0RFRkFVTFQiLCJLZXlJZCI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6a2V5LzgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCJ9" + } + }, + { + "ID": "0c68d0a1f2faf5fc", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Decrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFnSUNBSGlSUHF2ZmE0SEVUOTUzbld2b21mcnN2YTJWUmxiTnl4bFNvSzVmRG84ZW5BRmRVclMydmx1em1jSllUQkFlRSsrdEFBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTUxPV1FLbHhEdlBkNU5LRGxBZ0VRZ0RDTDFoZjZUOXRIUU5aczFNbnI0ZkZxVXdVUmM2VFF2eWl6RTBWdUxVYW5EYjUxQUFQalJaODBJeU00QWJVbG9BZz0ifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:01 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "5a762bf1-8236-40e7-b3f0-d20d9f879621" + ] + }, + "Body": "eyJfX3R5cGUiOiJJbnZhbGlkQ2lwaGVydGV4dEV4Y2VwdGlvbiJ9" + } + }, + { + "ID": "1fa16133eabd565c", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Decrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUFlSkUrcTk5cmdjUlAzbmVkYStpWit1eTlyWlZHVnMzTEdWS2dybDhPang2Y0FWMVN0TGErVzdPWndsaE1FQjRUNzYwQUFBQnpNSEVHQ1NxR1NJYjNEUUVIQnFCa01HSUNBUUF3WFFZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF3czVaQXFYRU84OTNrMG9PVUNBUkNBTUl2V0YvcFAyMGRBMW16VXlldmg4V3BUQlJGenBOQy9LTE1UUlc0dFJxY052blVBQStORm56UWpJemdCdFNXZ0NBPT0ifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:01 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "f70463c6-01f3-4a1f-815b-7cfc3186e0a0" + ] + }, + "Body": "eyJfX3R5cGUiOiJJbnZhbGlkQ2lwaGVydGV4dEV4Y2VwdGlvbiJ9" + } + }, + { + "ID": "ffa47d398d3d6c78", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Decrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGlSUHF2ZmE0SEVUOTUzbld2b21mcnN2YTJWUmxiTnl4bFNvSzVmRG84ZW5BRmRVclMydmx1em1jSllUQkFlRSsrdEFBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTUxPV1FLbHhEdlBkNU5LRGxBZ0VRZ0RDTDFoZjZUOXRIUU5aczFNbnI0ZkZxVXdVUmM2VFF2eWl6RTBWdUxVYW5EYjUxQUFQalJaODBJeU00QWJVbEJ3PT0ifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "39" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:01 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "c28d1f3a-7d97-44fe-908f-dfaff24ad7b3" + ] + }, + "Body": "eyJfX3R5cGUiOiJJbnZhbGlkQ2lwaGVydGV4dEV4Y2VwdGlvbiJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/awskms/testdata/TestConformance/TestEncryptDecrypt.replay b/go-cloud/secrets/awskms/testdata/TestConformance/TestEncryptDecrypt.replay new file mode 100644 index 000000000..bb04c7829 --- /dev/null +++ b/go-cloud/secrets/awskms/testdata/TestConformance/TestEncryptDecrypt.replay @@ -0,0 +1,239 @@ +{ + "Initial": "AQAAAA7gDMeGJ1x3gAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "67d000061d855d6e", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.ListAliases" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "e30=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "2035" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:53:59 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "9003baad-df43-4a7b-a81d-c1c94b554bab" + ] + }, + "Body": "eyJBbGlhc0NvdW50IjoxNSwiQWxpYXNlcyI6W3siQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9keW5hbW9kYiIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9keW5hbW9kYiJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9lYnMiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZWJzIiwiQ3JlYXRpb25EYXRlIjoxLjU5MjQxMjAxODUyMUU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNTkyNDEyMDE4NTIxRTksIlRhcmdldEtleUlkIjoiZmI0NTdlOGUtNTQ2ZS00MDMzLWE1YWEtZThhZWRkYzlkODUxIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VzIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VzIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2dsdWUiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZ2x1ZSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9raW5lc2lzdmlkZW8iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mva2luZXNpc3ZpZGVvIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3JkcyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9yZHMifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnQiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvcmVkc2hpZnQifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnR0ZXN0IiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL3JlZHNoaWZ0dGVzdCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zMyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zMyJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkNyZWF0aW9uRGF0ZSI6MS43NDM0NTM4NDE2NjhFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc0MzQ1Mzg0MTY2OEU5LCJUYXJnZXRLZXlJZCI6ImY1NDQwMjcyLWEyYzktNGU3Ny05N2Y4LTdjYjE4NzA2NmViZCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zc20iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mvc3NtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3hyYXkiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MveHJheSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkFsaWFzTmFtZSI6ImFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkNyZWF0aW9uRGF0ZSI6MS43NTI4NzgxMjgwMzZFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc1Mjg3ODEyODAzNkU5LCJUYXJnZXRLZXlJZCI6IjgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0czIiLCJBbGlhc05hbWUiOiJhbGlhcy90ZXN0LXNlY3JldHMyIiwiQ3JlYXRpb25EYXRlIjoxLjc1Mjg3OTE3Nzc0NkU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNzUyODc5MTc3NzQ2RTksIlRhcmdldEtleUlkIjoiN2VkM2VkOTgtMDM2MS00ZWQyLWExN2EtOTE1YjBlZjJlOWJmIn1dLCJUcnVuY2F0ZWQiOmZhbHNlfQ==" + } + }, + { + "ID": "d756684dfc922032", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Encrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJLZXlJZCI6ImFsaWFzL3Rlc3Qtc2VjcmV0cyIsIlBsYWludGV4dCI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "381" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:53:59 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "866a7804-d1d3-4e68-9b7e-1561914561fe" + ] + }, + "Body": "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGlSUHF2ZmE0SEVUOTUzbld2b21mcnN2YTJWUmxiTnl4bFNvSzVmRG84ZW5BRTlydDFqbG9RTUVXeWtzV0VsbGlyakFBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTVFIMXc5SXk2Q1VkL0ZCK2NBZ0VRZ0RDekJaK3gyYmZ3VlhiQ096NC83eVpmYlhHVmpCbEdteU5aS1dpOUdjQ21TRnVXV0dwV3ZPczQzZng4U2x6MnZFMD0iLCJFbmNyeXB0aW9uQWxnb3JpdGhtIjoiU1lNTUVUUklDX0RFRkFVTFQiLCJLZXlJZCI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6a2V5LzgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCJ9" + } + }, + { + "ID": "06bc6b070fd5938e", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Decrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGlSUHF2ZmE0SEVUOTUzbld2b21mcnN2YTJWUmxiTnl4bFNvSzVmRG84ZW5BRTlydDFqbG9RTUVXeWtzV0VsbGlyakFBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTVFIMXc5SXk2Q1VkL0ZCK2NBZ0VRZ0RDekJaK3gyYmZ3VlhiQ096NC83eVpmYlhHVmpCbEdteU5aS1dpOUdjQ21TRnVXV0dwV3ZPczQzZng4U2x6MnZFMD0ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:53:59 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "ee06e0a3-1e23-447c-b641-d406fc3f25fc" + ] + }, + "Body": "eyJFbmNyeXB0aW9uQWxnb3JpdGhtIjoiU1lNTUVUUklDX0RFRkFVTFQiLCJLZXlJZCI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6a2V5LzgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCIsIktleU1hdGVyaWFsSWQiOiI5MTNlYWJkZjZiODFjNDRmZGU3NzlkNmJlODk5ZmFlY2JkYWQ5NTQ2NTZjZGNiMTk1MmEwYWU1ZjBlOGYxZTljIiwiS2V5T3JpZ2luIjoiQVdTX0tNUyIsIlBsYWludGV4dCI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/awskms/testdata/TestConformance/TestMultipleEncryptionsNotEqual.replay b/go-cloud/secrets/awskms/testdata/TestConformance/TestMultipleEncryptionsNotEqual.replay new file mode 100644 index 000000000..d9621ca25 --- /dev/null +++ b/go-cloud/secrets/awskms/testdata/TestConformance/TestMultipleEncryptionsNotEqual.replay @@ -0,0 +1,367 @@ +{ + "Initial": "AQAAAA7gDMeHO5GM6wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "d9cf8f3163b67433", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.ListAliases" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "e30=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "2035" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:00 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "fe4f5a49-a051-4eab-93be-4c11aee007d6" + ] + }, + "Body": "eyJBbGlhc0NvdW50IjoxNSwiQWxpYXNlcyI6W3siQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9keW5hbW9kYiIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9keW5hbW9kYiJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9lYnMiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZWJzIiwiQ3JlYXRpb25EYXRlIjoxLjU5MjQxMjAxODUyMUU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNTkyNDEyMDE4NTIxRTksIlRhcmdldEtleUlkIjoiZmI0NTdlOGUtNTQ2ZS00MDMzLWE1YWEtZThhZWRkYzlkODUxIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VzIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VzIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2dsdWUiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZ2x1ZSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9raW5lc2lzdmlkZW8iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mva2luZXNpc3ZpZGVvIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3JkcyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9yZHMifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnQiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvcmVkc2hpZnQifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnR0ZXN0IiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL3JlZHNoaWZ0dGVzdCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zMyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zMyJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkNyZWF0aW9uRGF0ZSI6MS43NDM0NTM4NDE2NjhFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc0MzQ1Mzg0MTY2OEU5LCJUYXJnZXRLZXlJZCI6ImY1NDQwMjcyLWEyYzktNGU3Ny05N2Y4LTdjYjE4NzA2NmViZCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zc20iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mvc3NtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3hyYXkiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MveHJheSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkFsaWFzTmFtZSI6ImFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkNyZWF0aW9uRGF0ZSI6MS43NTI4NzgxMjgwMzZFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc1Mjg3ODEyODAzNkU5LCJUYXJnZXRLZXlJZCI6IjgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0czIiLCJBbGlhc05hbWUiOiJhbGlhcy90ZXN0LXNlY3JldHMyIiwiQ3JlYXRpb25EYXRlIjoxLjc1Mjg3OTE3Nzc0NkU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNzUyODc5MTc3NzQ2RTksIlRhcmdldEtleUlkIjoiN2VkM2VkOTgtMDM2MS00ZWQyLWExN2EtOTE1YjBlZjJlOWJmIn1dLCJUcnVuY2F0ZWQiOmZhbHNlfQ==" + } + }, + { + "ID": "fb3be06aef866222", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Encrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJLZXlJZCI6ImFsaWFzL3Rlc3Qtc2VjcmV0cyIsIlBsYWludGV4dCI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "381" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:00 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "aa84ab1a-cfcb-4882-b9ab-b97e5b80358d" + ] + }, + "Body": "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGlSUHF2ZmE0SEVUOTUzbld2b21mcnN2YTJWUmxiTnl4bFNvSzVmRG84ZW5BSHBubW1mVlgrNk0xbXRNenM0WkNqaEFBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTUZxR3FuazdZZmUyd2xZb1BBZ0VRZ0RBVGZEc1BIcDM3alpTQVVhU2RkRUdpT3cwdmp0a2J1UnhoZzF2S2VncEw1QVdaZnVsQXJvMStrZk81MHhHdzM2MD0iLCJFbmNyeXB0aW9uQWxnb3JpdGhtIjoiU1lNTUVUUklDX0RFRkFVTFQiLCJLZXlJZCI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6a2V5LzgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCJ9" + } + }, + { + "ID": "2e67660d5561703b", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Encrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJLZXlJZCI6ImFsaWFzL3Rlc3Qtc2VjcmV0cyIsIlBsYWludGV4dCI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "381" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:00 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "f0a41452-9ea2-43b3-981e-bc29a15b32e3" + ] + }, + "Body": "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGlSUHF2ZmE0SEVUOTUzbld2b21mcnN2YTJWUmxiTnl4bFNvSzVmRG84ZW5BSDRlSGFRZUt4M2svOHlQOXoxVk5CMUFBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTVRjY1BVOEMwN1EyQVNDZHZBZ0VRZ0RETWRYcW82VXdkZDkrS2oxemx5OE9iQlVncTBYU0REbFk5ZVFjVm1oNHl6dGplWitXU0ZMZ1NhVkhaZEVWMVZuST0iLCJFbmNyeXB0aW9uQWxnb3JpdGhtIjoiU1lNTUVUUklDX0RFRkFVTFQiLCJLZXlJZCI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6a2V5LzgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCJ9" + } + }, + { + "ID": "36ca9909fe4e34e4", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Decrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGlSUHF2ZmE0SEVUOTUzbld2b21mcnN2YTJWUmxiTnl4bFNvSzVmRG84ZW5BSHBubW1mVlgrNk0xbXRNenM0WkNqaEFBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTUZxR3FuazdZZmUyd2xZb1BBZ0VRZ0RBVGZEc1BIcDM3alpTQVVhU2RkRUdpT3cwdmp0a2J1UnhoZzF2S2VncEw1QVdaZnVsQXJvMStrZk81MHhHdzM2MD0ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:00 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "3d6ba3cd-6e75-42f5-9305-16f095041c0c" + ] + }, + "Body": "eyJFbmNyeXB0aW9uQWxnb3JpdGhtIjoiU1lNTUVUUklDX0RFRkFVTFQiLCJLZXlJZCI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6a2V5LzgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCIsIktleU1hdGVyaWFsSWQiOiI5MTNlYWJkZjZiODFjNDRmZGU3NzlkNmJlODk5ZmFlY2JkYWQ5NTQ2NTZjZGNiMTk1MmEwYWU1ZjBlOGYxZTljIiwiS2V5T3JpZ2luIjoiQVdTX0tNUyIsIlBsYWludGV4dCI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + } + }, + { + "ID": "82bb662a52e98536", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Decrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGlSUHF2ZmE0SEVUOTUzbld2b21mcnN2YTJWUmxiTnl4bFNvSzVmRG84ZW5BSDRlSGFRZUt4M2svOHlQOXoxVk5CMUFBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTVRjY1BVOEMwN1EyQVNDZHZBZ0VRZ0RETWRYcW82VXdkZDkrS2oxemx5OE9iQlVncTBYU0REbFk5ZVFjVm1oNHl6dGplWitXU0ZMZ1NhVkhaZEVWMVZuST0ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:00 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "a70f54c4-62b7-40de-9c63-1e97a5122b96" + ] + }, + "Body": "eyJFbmNyeXB0aW9uQWxnb3JpdGhtIjoiU1lNTUVUUklDX0RFRkFVTFQiLCJLZXlJZCI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6a2V5LzgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCIsIktleU1hdGVyaWFsSWQiOiI5MTNlYWJkZjZiODFjNDRmZGU3NzlkNmJlODk5ZmFlY2JkYWQ5NTQ2NTZjZGNiMTk1MmEwYWU1ZjBlOGYxZTljIiwiS2V5T3JpZ2luIjoiQVdTX0tNUyIsIlBsYWludGV4dCI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/awskms/testdata/TestConformance/TestMultipleKeys.replay b/go-cloud/secrets/awskms/testdata/TestConformance/TestMultipleKeys.replay new file mode 100644 index 000000000..4f4461be8 --- /dev/null +++ b/go-cloud/secrets/awskms/testdata/TestConformance/TestMultipleKeys.replay @@ -0,0 +1,367 @@ +{ + "Initial": "AQAAAA7gDMeIGYAfkAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": [ + "MessageAttributes.*" + ], + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^Amz-Sdk-Invocation-Id$", + "^X-Amz-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$", + "^Authorization$", + "^Duration$", + "^X-Amz-Security-Token$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": [ + "^X-Amz-Date$" + ], + "RemoveParams": [ + "^X-Amz-Credential$", + "^X-Amz-Signature$", + "^X-Amz-Security-Token$" + ] + }, + "Entries": [ + { + "ID": "eed082620ae7488f", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "2" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.ListAliases" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "e30=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "2035" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:00 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "29b2eee0-a2e3-46a5-adc4-c14e909be720" + ] + }, + "Body": "eyJBbGlhc0NvdW50IjoxNSwiQWxpYXNlcyI6W3siQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9keW5hbW9kYiIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9keW5hbW9kYiJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9lYnMiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZWJzIiwiQ3JlYXRpb25EYXRlIjoxLjU5MjQxMjAxODUyMUU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNTkyNDEyMDE4NTIxRTksIlRhcmdldEtleUlkIjoiZmI0NTdlOGUtNTQ2ZS00MDMzLWE1YWEtZThhZWRkYzlkODUxIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VsYXN0aWNmaWxlc3lzdGVtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2VzIiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL2VzIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL2dsdWUiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvZ2x1ZSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9raW5lc2lzdmlkZW8iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mva2luZXNpc3ZpZGVvIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3JkcyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9yZHMifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnQiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MvcmVkc2hpZnQifSx7IkFsaWFzQXJuIjoiYXJuOmF3czprbXM6dXMtZWFzdC0yOjQ1Njc1MjY2NTU3NjphbGlhcy9hd3MvcmVkc2hpZnR0ZXN0IiwiQWxpYXNOYW1lIjoiYWxpYXMvYXdzL3JlZHNoaWZ0dGVzdCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zMyIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zMyJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkFsaWFzTmFtZSI6ImFsaWFzL2F3cy9zZWNyZXRzbWFuYWdlciIsIkNyZWF0aW9uRGF0ZSI6MS43NDM0NTM4NDE2NjhFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc0MzQ1Mzg0MTY2OEU5LCJUYXJnZXRLZXlJZCI6ImY1NDQwMjcyLWEyYzktNGU3Ny05N2Y4LTdjYjE4NzA2NmViZCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL2F3cy9zc20iLCJBbGlhc05hbWUiOiJhbGlhcy9hd3Mvc3NtIn0seyJBbGlhc0FybiI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6YWxpYXMvYXdzL3hyYXkiLCJBbGlhc05hbWUiOiJhbGlhcy9hd3MveHJheSJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkFsaWFzTmFtZSI6ImFsaWFzL3Rlc3Qtc2VjcmV0cyIsIkNyZWF0aW9uRGF0ZSI6MS43NTI4NzgxMjgwMzZFOSwiTGFzdFVwZGF0ZWREYXRlIjoxLjc1Mjg3ODEyODAzNkU5LCJUYXJnZXRLZXlJZCI6IjgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCJ9LHsiQWxpYXNBcm4iOiJhcm46YXdzOmttczp1cy1lYXN0LTI6NDU2NzUyNjY1NTc2OmFsaWFzL3Rlc3Qtc2VjcmV0czIiLCJBbGlhc05hbWUiOiJhbGlhcy90ZXN0LXNlY3JldHMyIiwiQ3JlYXRpb25EYXRlIjoxLjc1Mjg3OTE3Nzc0NkU5LCJMYXN0VXBkYXRlZERhdGUiOjEuNzUyODc5MTc3NzQ2RTksIlRhcmdldEtleUlkIjoiN2VkM2VkOTgtMDM2MS00ZWQyLWExN2EtOTE1YjBlZjJlOWJmIn1dLCJUcnVuY2F0ZWQiOmZhbHNlfQ==" + } + }, + { + "ID": "6a5ee5e571393ce3", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "73" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Encrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJLZXlJZCI6ImFsaWFzL3Rlc3Qtc2VjcmV0cyIsIlBsYWludGV4dCI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "381" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:00 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "b354a604-b7c9-4b04-a803-e3dcc8a1ff10" + ] + }, + "Body": "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGlSUHF2ZmE0SEVUOTUzbld2b21mcnN2YTJWUmxiTnl4bFNvSzVmRG84ZW5BRkF6Y2sxUlhXUkVmWUlQczhxMUF1dkFBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTSt0Qkttb2drTmkxd1hENW9BZ0VRZ0RDbTcra2IxcEhTeHptaks5Qjc4M25EWU1meEs1TDMzUENsRWEwMmpXY1FxTlhLdk5UcnRGbWgvbENkMVhQSmN0Zz0iLCJFbmNyeXB0aW9uQWxnb3JpdGhtIjoiU1lNTUVUUklDX0RFRkFVTFQiLCJLZXlJZCI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6a2V5LzgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCJ9" + } + }, + { + "ID": "96029cd39bc0c1ab", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "74" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Encrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJLZXlJZCI6ImFsaWFzL3Rlc3Qtc2VjcmV0czIiLCJQbGFpbnRleHQiOiJTU2R0SUdFZ2MyVmpjbVYwSUcxbGMzTmhaMlVoIn0=" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "381" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:00 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "f6d7eaff-54e8-46af-9324-016b3c95e386" + ] + }, + "Body": "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGcvbmJCVWlrTjYyREZrMzlDcDUxVW1jaVhXbXJVNlB5d3JQck5lU2k4b0xBRWcrVUtuZUtJQ25jNXlKRG44dHdEL0FBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTUZwS0h4NnNSbTNld0t2V1JBZ0VRZ0RCTzlYNnBnWEZTbGI3WUxJYjZ6Z3gwWXhjcVR3NnZkZHlBYW1rcTJqS2sxMERWVGpKekpiejlla1VROFIvZy9tST0iLCJFbmNyeXB0aW9uQWxnb3JpdGhtIjoiU1lNTUVUUklDX0RFRkFVTFQiLCJLZXlJZCI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6a2V5LzdlZDNlZDk4LTAzNjEtNGVkMi1hMTdhLTkxNWIwZWYyZTliZiJ9" + } + }, + { + "ID": "98ca6b89125e8f36", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Decrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGlSUHF2ZmE0SEVUOTUzbld2b21mcnN2YTJWUmxiTnl4bFNvSzVmRG84ZW5BRkF6Y2sxUlhXUkVmWUlQczhxMUF1dkFBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTSt0Qkttb2drTmkxd1hENW9BZ0VRZ0RDbTcra2IxcEhTeHptaks5Qjc4M25EWU1meEs1TDMzUENsRWEwMmpXY1FxTlhLdk5UcnRGbWgvbENkMVhQSmN0Zz0ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:00 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "121cfedc-88e0-466f-b890-a61b250eb0b9" + ] + }, + "Body": "eyJFbmNyeXB0aW9uQWxnb3JpdGhtIjoiU1lNTUVUUklDX0RFRkFVTFQiLCJLZXlJZCI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6a2V5LzgxOThmNTM2LTI2YjEtNDU3MS1hNDE1LTAxYzA0NTBlNmMxNCIsIktleU1hdGVyaWFsSWQiOiI5MTNlYWJkZjZiODFjNDRmZGU3NzlkNmJlODk5ZmFlY2JkYWQ5NTQ2NTZjZGNiMTk1MmEwYWU1ZjBlOGYxZTljIiwiS2V5T3JpZ2luIjoiQVdTX0tNUyIsIlBsYWludGV4dCI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + } + }, + { + "ID": "d5774ca905918cd6", + "Request": { + "Method": "POST", + "URL": "https://kms.us-east-2.amazonaws.com/", + "Header": { + "Accept-Encoding": [ + "gzip" + ], + "Amz-Sdk-Invocation-Id": [ + "CLEARED" + ], + "Amz-Sdk-Request": [ + "attempt=1; max=1" + ], + "Content-Length": [ + "253" + ], + "User-Agent": [ + "CLEARED" + ], + "X-Amz-Date": [ + "CLEARED" + ], + "X-Amz-Target": [ + "TrentService.Decrypt" + ] + }, + "MediaType": "application/x-amz-json-1.1", + "BodyParts": [ + "eyJDaXBoZXJ0ZXh0QmxvYiI6IkFRSUNBSGcvbmJCVWlrTjYyREZrMzlDcDUxVW1jaVhXbXJVNlB5d3JQck5lU2k4b0xBRWcrVUtuZUtJQ25jNXlKRG44dHdEL0FBQUFjekJ4QmdrcWhraUc5dzBCQndhZ1pEQmlBZ0VBTUYwR0NTcUdTSWIzRFFFSEFUQWVCZ2xnaGtnQlpRTUVBUzR3RVFRTUZwS0h4NnNSbTNld0t2V1JBZ0VRZ0RCTzlYNnBnWEZTbGI3WUxJYjZ6Z3gwWXhjcVR3NnZkZHlBYW1rcTJqS2sxMERWVGpKekpiejlla1VROFIvZy9tST0ifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache, no-store, must-revalidate, private" + ], + "Content-Length": [ + "277" + ], + "Content-Type": [ + "application/x-amz-json-1.1" + ], + "Date": [ + "Fri, 18 Jul 2025 22:54:00 GMT" + ], + "Expires": [ + "0" + ], + "Pragma": [ + "no-cache" + ], + "X-Amzn-Requestid": [ + "eaf69805-b7c9-4e22-9165-74be4c6aeb8d" + ] + }, + "Body": "eyJFbmNyeXB0aW9uQWxnb3JpdGhtIjoiU1lNTUVUUklDX0RFRkFVTFQiLCJLZXlJZCI6ImFybjphd3M6a21zOnVzLWVhc3QtMjo0NTY3NTI2NjU1NzY6a2V5LzdlZDNlZDk4LTAzNjEtNGVkMi1hMTdhLTkxNWIwZWYyZTliZiIsIktleU1hdGVyaWFsSWQiOiIzZjlkYjA1NDhhNDM3YWQ4MzE2NGRmZDBhOWU3NTUyNjcyMjVkNjlhYjUzYTNmMmMyYjNlYjM1ZTRhMmYyODJjIiwiS2V5T3JpZ2luIjoiQVdTX0tNUyIsIlBsYWludGV4dCI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/azurekeyvault/akv.go b/go-cloud/secrets/azurekeyvault/akv.go new file mode 100644 index 000000000..e509c913b --- /dev/null +++ b/go-cloud/secrets/azurekeyvault/akv.go @@ -0,0 +1,262 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 azurekeyvault provides a secrets implementation backed by Azure KeyVault. +// See https://docs.microsoft.com/en-us/azure/key-vault/key-vault-whatis for more information. +// Use OpenKeeper to construct a *secrets.Keeper. +// +// # URLs +// +// For secrets.OpenKeeper, azurekeyvault registers for the scheme "azurekeyvault". +// The default URL opener will use azidentity.DefaultAzureCredential to get credentials. +// +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// azurekeyvault exposes the following type for As: +// - Error: *azcore.ResponseError. +package azurekeyvault + +import ( + "context" + "errors" + "fmt" + "net/url" + "path" + "regexp" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/useragent" + "github.com/DataDog/iceberg-go/go-cloud/secrets" +) + +// Map of HTTP Status Code to go-cloud ErrorCode +var errorCodeMap = map[int]gcerrors.ErrorCode{ + 200: gcerrors.OK, + 400: gcerrors.InvalidArgument, + 401: gcerrors.PermissionDenied, + 403: gcerrors.PermissionDenied, + 404: gcerrors.NotFound, + 408: gcerrors.DeadlineExceeded, + 429: gcerrors.ResourceExhausted, + 500: gcerrors.Internal, + 501: gcerrors.Unimplemented, +} + +func init() { + secrets.DefaultURLMux().RegisterKeeper(Scheme, new(defaultDialer)) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + DefaultClientMaker, + wire.Struct(new(URLOpener), "Client"), +) + +// ClientMakerT is the type of a function used to generate a Client. +type ClientMakerT func(keyVaultURI string) (*azkeys.Client, error) + +// defaultDialer dials Azure KeyVault using DefaultClientMaker. +type defaultDialer struct{} + +func (o *defaultDialer) OpenKeeperURL(ctx context.Context, u *url.URL) (*secrets.Keeper, error) { + opener := &URLOpener{ClientMaker: DefaultClientMaker} + return opener.OpenKeeperURL(ctx, u) +} + +// Scheme is the URL scheme azurekeyvault registers its URLOpener under on secrets.DefaultMux. +const Scheme = "azurekeyvault" + +// URLOpener opens Azure KeyVault URLs like +// "azurekeyvault://{keyvault-name}.vault.azure.net/keys/{key-name}/{key-version}?algorithm=RSA-OAEP-256". +// +// The "azurekeyvault" URL scheme is replaced with "https" to construct an Azure +// Key Vault keyID, as described in https://docs.microsoft.com/en-us/azure/key-vault/about-keys-secrets-and-certificates. +// The "/{key-version}"" suffix is optional; it defaults to the latest version. +// +// The "algorithm" query parameter sets the algorithm to use; see +// https://docs.microsoft.com/en-us/rest/api/keyvault/encrypt/encrypt#jsonwebkeyencryptionalgorithm +// for supported algorithms. It defaults to "RSA-OAEP-256". +// +// No other query parameters are supported. +type URLOpener struct { + // ClientMaker defaults to DefaultClientMaker. + ClientMaker ClientMakerT + + // Options specifies the options to pass to OpenKeeper. + Options KeeperOptions +} + +// OpenKeeperURL opens an Azure KeyVault Keeper based on u. +func (o *URLOpener) OpenKeeperURL(ctx context.Context, u *url.URL) (*secrets.Keeper, error) { + q := u.Query() + algorithm := q.Get("algorithm") + if algorithm != "" { + o.Options.Algorithm = azkeys.JSONWebKeyEncryptionAlgorithm(algorithm) + q.Del("algorithm") + } + for param := range q { + return nil, fmt.Errorf("open keeper %v: invalid query parameter %q", u, param) + } + keyID := "https://" + path.Join(u.Host, u.Path) + return OpenKeeper(o.ClientMaker, keyID, &o.Options) +} + +type keeper struct { + client *azkeys.Client + keyVaultURI string // unused, but for validation in tests + keyName string + keyVersion string + options *KeeperOptions +} + +// KeeperOptions provides configuration options for encryption/decryption operations. +type KeeperOptions struct { + // Algorithm sets the encryption algorithm used. + // Defaults to "RSA-OAEP-256". + // See https://docs.microsoft.com/en-us/rest/api/keyvault/encrypt/encrypt#jsonwebkeyencryptionalgorithm + // for more details. + Algorithm azkeys.JSONWebKeyEncryptionAlgorithm + + // EncryptOptions are passed through to Encrypt. + EncryptOptions *azkeys.EncryptOptions + + // DecryptOptions are passed through to Decrypt. + DecryptOptions *azkeys.DecryptOptions +} + +// DefaultClientMaker returns a function that constructs a KeyVault Client. +// By default it uses credentials from the environment; +// See https://docs.microsoft.com/en-us/go/azure/azure-sdk-go-authorization#use-environment-based-authentication. +// If the environment variable AZURE_KEYVAULT_AUTH_VIA_CLI is set to a truthy value, it +// uses credentials from the Azure CLI instead. +func DefaultClientMaker(keyVaultURI string) (*azkeys.Client, error) { + creds, err := azidentity.NewDefaultAzureCredential(nil) + if err != nil { + return nil, err + } + return azkeys.NewClient(keyVaultURI, creds, &azkeys.ClientOptions{ + ClientOptions: policy.ClientOptions{ + Telemetry: policy.TelemetryOptions{ + ApplicationID: useragent.AzureUserAgentPrefix("secrets"), + }, + }, + }) +} + +// Note that the last binding may be just a key, or key/version. +var keyIDRE = regexp.MustCompile(`^(https://.+\.vault\.(?:[a-z\d-.]+)/)keys/(.+)$`) + +// OpenKeeper returns a *secrets.Keeper that uses Azure keyVault. +// +// clientMaker is used to construct an azkeys.Client. +// +// keyID is a Azure Key Vault key identifier like "https://{keyvault-name}.vault.azure.net/keys/{key-name}/{key-version}". +// The "/{key-version}" suffix is optional; it defaults to the latest version. +// See https://docs.microsoft.com/en-us/azure/key-vault/about-keys-secrets-and-certificates +// for more details. +func OpenKeeper(clientMaker ClientMakerT, keyID string, opts *KeeperOptions) (*secrets.Keeper, error) { + drv, err := openKeeper(clientMaker, keyID, opts) + if err != nil { + return nil, err + } + return secrets.NewKeeper(drv), nil +} + +func openKeeper(clientMaker ClientMakerT, keyID string, opts *KeeperOptions) (*keeper, error) { + if opts == nil { + opts = &KeeperOptions{} + } + if opts.Algorithm == "" { + opts.Algorithm = azkeys.JSONWebKeyEncryptionAlgorithmRSAOAEP256 + } + matches := keyIDRE.FindStringSubmatch(keyID) + if len(matches) != 3 { + return nil, fmt.Errorf("invalid keyID %q; must match %v %v", keyID, keyIDRE, matches) + } + // matches[0] is the whole keyID, [1] is the keyVaultURI, and [2] is the key or the key/version. + keyVaultURI := matches[1] + parts := strings.SplitN(matches[2], "/", 2) + keyName := parts[0] + var keyVersion string + if len(parts) > 1 { + keyVersion = parts[1] + } + client, err := clientMaker(keyVaultURI) + if err != nil { + return nil, err + } + return &keeper{ + client: client, + keyVaultURI: keyVaultURI, + keyName: keyName, + keyVersion: keyVersion, + options: opts, + }, nil +} + +// Encrypt encrypts the plaintext into a ciphertext. +func (k *keeper) Encrypt(ctx context.Context, plaintext []byte) ([]byte, error) { + keyOpsResult, err := k.client.Encrypt(ctx, k.keyName, k.keyVersion, azkeys.KeyOperationsParameters{ + Algorithm: &k.options.Algorithm, + Value: plaintext, + }, k.options.EncryptOptions) + if err != nil { + return nil, err + } + return keyOpsResult.Result, nil +} + +// Decrypt decrypts the ciphertext into a plaintext. +func (k *keeper) Decrypt(ctx context.Context, ciphertext []byte) ([]byte, error) { + keyOpsResult, err := k.client.Decrypt(ctx, k.keyName, k.keyVersion, azkeys.KeyOperationsParameters{ + Algorithm: &k.options.Algorithm, + Value: ciphertext, + }, k.options.DecryptOptions) + if err != nil { + return nil, err + } + return keyOpsResult.Result, nil +} + +// Close implements driver.Keeper.Close. +func (k *keeper) Close() error { return nil } + +// ErrorAs implements driver.Keeper.ErrorAs. +func (k *keeper) ErrorAs(err error, i any) bool { + return errors.As(err, i) +} + +// ErrorCode implements driver.ErrorCode. +func (k *keeper) ErrorCode(err error) gcerrors.ErrorCode { + re, ok := err.(*azcore.ResponseError) + if !ok { + return gcerr.Unknown + } + ec, ok := errorCodeMap[re.StatusCode] + if !ok { + return gcerr.Unknown + } + return ec +} diff --git a/go-cloud/secrets/azurekeyvault/akv_test.go b/go-cloud/secrets/azurekeyvault/akv_test.go new file mode 100644 index 000000000..d5fe2dd33 --- /dev/null +++ b/go-cloud/secrets/azurekeyvault/akv_test.go @@ -0,0 +1,262 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 azurekeyvault + +import ( + "context" + "errors" + "log" + "os" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/internal/useragent" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "github.com/DataDog/iceberg-go/go-cloud/secrets/driver" + "github.com/DataDog/iceberg-go/go-cloud/secrets/drivertest" +) + +// Prerequisites for --record mode +// +// 1. Sign-in to your Azure Subscription at http://portal.azure.com. +// +// 2. Create a KeyVault, see +// https://docs.microsoft.com/en-us/azure/key-vault/quick-create-portal. +// +// 3. Choose an authentication model. This test uses Service Principal, see +// https://docs.microsoft.com/en-us/rest/api/azure/index#register-your-client-application-with-azure-ad. +// For documentation on acceptable auth models, see +// https://docs.microsoft.com/en-us/azure/key-vault/key-vault-whatis. +// +// 4. Set your environment variables depending on the auth model selection. +// Modify helper initEnv() as needed. +// For Service Principal, please set the following, see +// https://docs.microsoft.com/en-us/go/azure/azure-sdk-go-authorization. +// +// - AZURE_TENANT_ID: Go to "Azure Active Directory", then "Properties". The +// "Directory ID" property is your AZURE_TENANT_ID. +// - AZURE_CLIENT_ID: Go to "Azure Active Directory", then "App Registrations", +// then "View all applications". The "Application ID" column shows your +// AZURE_CLIENT_ID. +// - AZURE_CLIENT_SECRET: Click on the application from the previous step, +// then "Settings" and then "Keys". Create a key and use it as your +// AZURE_CLIENT_SECRET. Make sure to save the value as it's hidden after +// the initial creation. +// - AZURE_ENVIRONMENT: (optional). +// - AZURE_AD_RESOURCE: (optional). +// +// 5. Create/Import a Key. This can be done in the Azure Portal under "Key vaults". +// +// 6. Update constants below to match your Azure KeyVault settings. + +const ( + keyID1 = "https://go-cdk.vault.azure.net/keys/test1" + keyID2 = "https://go-cdk.vault.azure.net/keys/test2" +) + +type harness struct { + clientMaker ClientMakerT + close func() +} + +func (h *harness) MakeDriver(ctx context.Context) (driver.Keeper, driver.Keeper, error) { + keeper1, err := openKeeper(h.clientMaker, keyID1, nil) + if err != nil { + return nil, nil, err + } + keeper2, err := openKeeper(h.clientMaker, keyID2, nil) + if err != nil { + return nil, nil, err + } + return keeper1, keeper2, nil +} + +func (h *harness) Close() { + h.close() +} + +type dummyToken struct{} + +func (*dummyToken) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) { + return azcore.AccessToken{}, nil +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + httpClient, done := setup.NewAzureKeyVaultTestClient(ctx, t) + clientMaker := func(keyVaultURI string) (*azkeys.Client, error) { + var creds azcore.TokenCredential + var err error + if *setup.Record { + initEnv() + creds, err = azidentity.NewEnvironmentCredential(nil) + } else { + creds = &dummyToken{} + } + if err != nil { + return nil, err + } + return azkeys.NewClient(keyVaultURI, creds, &azkeys.ClientOptions{ + ClientOptions: policy.ClientOptions{ + Transport: httpClient, + Telemetry: policy.TelemetryOptions{ + ApplicationID: useragent.AzureUserAgentPrefix("secrets"), + }, + }, + }) + } + return &harness{ + clientMaker: clientMaker, + close: done, + }, nil +} + +func initEnv() { + // For Client Credentials authorization, set AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET + // For Client Certificate and Azure Managed Service Identity, see doc below for help + // https://github.com/Azure/azure-sdk-for-go + if os.Getenv("AZURE_TENANT_ID") == "" || + os.Getenv("AZURE_CLIENT_ID") == "" || + os.Getenv("AZURE_CLIENT_SECRET") == "" { + log.Fatal("Missing environment for recording tests, set AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET") + } + os.Setenv("AZURE_ENVIRONMENT", "AzurePublicCloud") + os.Setenv("AZURE_AD_RESOURCE", "https://vault.azure.net") +} + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct{} + +func (v verifyAs) Name() string { + return "verify As function" +} + +func (v verifyAs) ErrorCheck(k *secrets.Keeper, err error) error { + var e *azcore.ResponseError + if !k.ErrorAs(err, &e) { + return errors.New("Keeper.ErrorAs failed") + } + return nil +} + +// Key Vault-specific tests. + +func dummyClientMaker(s string) (*azkeys.Client, error) { + return &azkeys.Client{}, nil +} + +func TestOpenKeeper(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"azurekeyvaultdummy://mykeyvault.vault.azure.net/keys/mykey/myversion", false}, + // No version -> OK. + {"azurekeyvaultdummy://mykeyvault.vault.azure.net/keys/mykey", false}, + // Setting algorithm query param -> OK. + {"azurekeyvaultdummy://mykeyvault.vault.azure.net/keys/mykey/myversion?algorithm=RSA-OAEP", false}, + // Invalid query parameter. + {"azurekeyvaultdummy://mykeyvault.vault.azure.net/keys/mykey/myversion?param=value", true}, + // Missing key vault name. + {"azurekeyvaultdummy:///vault.azure.net/keys/mykey/myversion", true}, + // Missing "keys". + {"azurekeyvaultdummy://mykeyvault.vault.azure.net/mykey/myversion", true}, + } + + secrets.DefaultURLMux().RegisterKeeper(Scheme+"dummy", &URLOpener{ClientMaker: dummyClientMaker}) + ctx := context.Background() + for _, test := range tests { + keeper, err := secrets.OpenKeeper(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if err == nil { + if err = keeper.Close(); err != nil { + t.Errorf("%s: got error during close: %v", test.URL, err) + } + } + } +} + +func TestKeyIDRE(t *testing.T) { + testCases := []struct { + // input + keyID string + + // output + keyVaultURI string + keyName string + keyVersion string + }{ + { + keyID: keyID1, + keyVaultURI: "https://go-cdk.vault.azure.net/", + keyName: "test1", + }, + { + keyID: keyID2, + keyVaultURI: "https://go-cdk.vault.azure.net/", + keyName: "test2", + }, + { + keyID: "https://mykeyvault.vault.azure.net/keys/mykey/myversion", + keyVaultURI: "https://mykeyvault.vault.azure.net/", + keyName: "mykey", + keyVersion: "myversion", + }, + { + keyID: "https://mykeyvault.vault.usgovcloudapi.net/keys/mykey/myversion", + keyVaultURI: "https://mykeyvault.vault.usgovcloudapi.net/", + keyName: "mykey", + keyVersion: "myversion", + }, + { + keyID: "https://mykeyvault.vault.region01.external.com/keys/mykey/myversion", + keyVaultURI: "https://mykeyvault.vault.region01.external.com/", + keyName: "mykey", + keyVersion: "myversion", + }, + } + for _, testCase := range testCases { + t.Run(testCase.keyID, func(t *testing.T) { + k, err := openKeeper(dummyClientMaker, testCase.keyID, nil) + if err != nil { + t.Fatal(err) + } + defer k.Close() + + if k.keyVaultURI != testCase.keyVaultURI { + t.Errorf("got key vault URI %s, want key vault URI %s", k.keyVaultURI, testCase.keyVaultURI) + } + + if k.keyName != testCase.keyName { + t.Errorf("got key name %s, want key name %s", k.keyName, testCase.keyName) + } + + if k.keyVersion != testCase.keyVersion { + t.Errorf("got key version %s, want key version %s", k.keyVersion, testCase.keyVersion) + } + }) + } +} diff --git a/go-cloud/secrets/azurekeyvault/example_test.go b/go-cloud/secrets/azurekeyvault/example_test.go new file mode 100644 index 000000000..555bc0a1f --- /dev/null +++ b/go-cloud/secrets/azurekeyvault/example_test.go @@ -0,0 +1,55 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 azurekeyvault_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "github.com/DataDog/iceberg-go/go-cloud/secrets/azurekeyvault" +) + +func ExampleOpenKeeper() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // Makes a client to use with the Azure KeyVault API, using default + // authorization from the environment. + clientMaker := azurekeyvault.DefaultClientMaker + + // Construct a *secrets.Keeper. + keeper, err := azurekeyvault.OpenKeeper(clientMaker, "https://mykeyvaultname.vault.azure.net/keys/mykeyname", nil) + if err != nil { + log.Fatal(err) + } + defer keeper.Close() +} + +func Example_openFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/secrets/azurekeyvault" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // The "azurekeyvault" URL scheme is replaced with "https" to construct an Azure + // Key Vault keyID, as described in https://docs.microsoft.com/en-us/azure/key-vault/about-keys-secrets-and-certificates. + // You can add an optional "/{key-version}" to the path to use a specific + // version of the key; it defaults to the latest version. + keeper, err := secrets.OpenKeeper(ctx, "azurekeyvault://mykeyvaultname.vault.azure.net/keys/mykeyname") + if err != nil { + log.Fatal(err) + } + defer keeper.Close() +} diff --git a/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestAs/verify_As_function.replay b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestAs/verify_As_function.replay new file mode 100644 index 000000000..55da5a7a3 --- /dev/null +++ b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestAs/verify_As_function.replay @@ -0,0 +1,182 @@ +{ + "Initial": "AQAAAA7dVMEbCwTv+wAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": null, + "RemoveParams": [ + "^se$", + "^sig$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "58fd13a457084159", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 401, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "97" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:59 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "Www-Authenticate": [ + "Bearer authorization=\"https://login.microsoftonline.com/db44ed8f-85f7-4f22-b378-3bb9fa3d62ff\", resource=\"https://vault.azure.net\"" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "9199ed18-249b-4b1d-9bf4-bf5325597cc5" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiVW5hdXRob3JpemVkIiwibWVzc2FnZSI6IkFLVjEwMDAwOiBSZXF1ZXN0IGlzIG1pc3NpbmcgYSBCZWFyZXIgb3IgUG9QIHRva2VuLiJ9fQ==" + } + }, + { + "ID": "daaa1dffe23cbf74", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6ImJXRnNabTl5YldWa0lHTnBjR2hsY2lCdFpYTnpZV2RsIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "77" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:59 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "17e84fbb-bf5d-4938-b791-7b6db9f054ce" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiQmFkUGFyYW1ldGVyIiwibWVzc2FnZSI6IlRoZSBwYXJhbWV0ZXIgaXMgaW5jb3JyZWN0LlxyXG4ifX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..719ac8fec --- /dev/null +++ b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay @@ -0,0 +1,182 @@ +{ + "Initial": "AQAAAA7dVMEbM63tVgAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": null, + "RemoveParams": [ + "^se$", + "^sig$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "4058cc12804ced9d", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 401, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "97" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:59 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "Www-Authenticate": [ + "Bearer authorization=\"https://login.microsoftonline.com/db44ed8f-85f7-4f22-b378-3bb9fa3d62ff\", resource=\"https://vault.azure.net\"" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "dcc99886-c4e7-4b3f-aa9c-d4b9a697ca73" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiVW5hdXRob3JpemVkIiwibWVzc2FnZSI6IkFLVjEwMDAwOiBSZXF1ZXN0IGlzIG1pc3NpbmcgYSBCZWFyZXIgb3IgUG9QIHRva2VuLiJ9fQ==" + } + }, + { + "ID": "245836b218a7f2f0", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "65" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6ImJXRnNabTl5YldWa0lHTnBjR2hsY2lCdFpYTnpZV2RsIn0=" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "77" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:09:00 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "f60eed33-6ebd-4096-8693-52221073c614" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiQmFkUGFyYW1ldGVyIiwibWVzc2FnZSI6IlRoZSBwYXJhbWV0ZXIgaXMgaW5jb3JyZWN0LlxyXG4ifX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestDecryptMalformedError.replay b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestDecryptMalformedError.replay new file mode 100644 index 000000000..8412c9a9f --- /dev/null +++ b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestDecryptMalformedError.replay @@ -0,0 +1,392 @@ +{ + "Initial": "AQAAAA7dVMEaFcsrgQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": null, + "RemoveParams": [ + "^se$", + "^sig$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "d7ee2ce4ed097975", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/encrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 401, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "97" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:57 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "Www-Authenticate": [ + "Bearer authorization=\"https://login.microsoftonline.com/db44ed8f-85f7-4f22-b378-3bb9fa3d62ff\", resource=\"https://vault.azure.net\"" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "80fd7f85-dbd3-4324-b2a7-9f18da51ca71" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiVW5hdXRob3JpemVkIiwibWVzc2FnZSI6IkFLVjEwMDAwOiBSZXF1ZXN0IGlzIG1pc3NpbmcgYSBCZWFyZXIgb3IgUG9QIHRva2VuLiJ9fQ==" + } + }, + { + "ID": "929b5a4aac22a498", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/encrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "61" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "437" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:58 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "1da28445-d926-47ed-9b22-f5c6e223408c" + ] + }, + "Body": "eyJraWQiOiJodHRwczovL2dvLWNkay52YXVsdC5henVyZS5uZXQva2V5cy90ZXN0MS9iM2IzMWYyOTIyNjI0ZTFkYTdhNDJlNGQwNGQ0NDExMCIsInZhbHVlIjoiUlNOSjdlMGpvVjNiMkQwSXBUdVEzTERZUnYxQW5tVFFHa2E3NXR0emp4QXVqLURXSlFkSVNnVnhiMTZtYzYxZ1RwYVdLaFlfZWxGaGdJNkRjR0pzVXpCN20wYmpHR1pzbG5veG1oci0wV1Qtc1RZN3JCY1JNRGNwc3gybFdfZVpmZVh1YkNGbkN0Ym16TUlCNzczZlRMekJxT1JQbHRVX3IzVmEtM2liWW1Xdl9QNjNmdUpXUl9kMzQ0MGtjTmN6ZDFobk1YYkZjMks0MjdZU1Z3Sm52aXh0a1cwVnF3WnJZLXJLdkgwc2cyQ2xPWVlSOGlLTXlLb3JvSk9OUENnWXlMRVhiMzR4ZjJxNVBVNWlYQ2F4MUVIei1uQlhBQkFGb3p1R1JGVWl2TnlzU3RxOTk3R1pjWXphbUJjam1CeER6Q0w0OUNieFdfQUZqR2FHd2R3Y213In0=" + } + }, + { + "ID": "e27b45f1d82345a0", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "375" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IlJpTko3ZTBqb1YzYjJEMElwVHVRM0xEWVJ2MUFubVRRR2thNzV0dHpqeEF1ai1EV0pRZElTZ1Z4YjE2bWM2MWdUcGFXS2hZX2VsRmhnSTZEY0dKc1V6QjdtMGJqR0dac2xub3htaHItMFdULXNUWTdyQmNSTURjcHN4MmxXX2VaZmVYdWJDRm5DdGJtek1JQjc3M2ZUTHpCcU9SUGx0VV9yM1ZhLTNpYlltV3ZfUDYzZnVKV1JfZDM0NDBrY05jemQxaG5NWGJGYzJLNDI3WVNWd0pudml4dGtXMFZxd1pyWS1yS3ZIMHNnMkNsT1lZUjhpS015S29yb0pPTlBDZ1l5TEVYYjM0eGYycTVQVTVpWENheDFFSHotbkJYQUJBRm96dUdSRlVpdk55c1N0cTk5N0daY1l6YW1CY2ptQnhEekNMNDlDYnhXX0FGakdhR3dkd2NtdyJ9" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "77" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:58 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "d1dc95e0-b0ba-445d-b206-51b66a946688" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiQmFkUGFyYW1ldGVyIiwibWVzc2FnZSI6IlRoZSBwYXJhbWV0ZXIgaXMgaW5jb3JyZWN0LlxyXG4ifX0=" + } + }, + { + "ID": "eaca3d529096aec8", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "373" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IlJVbnQ3U09oWGR2WVBRaWxPNURjc05oR19VQ2VaTkFhUnJ2bTIzT1BFQzZQNE5ZbEIwaEtCWEZ2WHFaenJXQk9scFlxRmo5NlVXR0Fqb053WW14VE1IdWJSdU1ZWm15V2VqR2FHdjdSWlA2eE5qdXNGeEV3TnltekhhVmI5NWw5NWU1c0lXY0sxdWJNd2dIdnZkOU12TUdvNUUtVzFULXZkVnI3ZUp0aVphXzhfcmQtNGxaSDkzZmpqU1J3MXpOM1dHY3hkc1Z6WXJqYnRoSlhBbWUtTEcyUmJSV3JCbXRqNnNxOGZTeURZS1U1aGhIeUlveklxaXVnazQwOEtCaklzUmR2ZmpGX2FyazlUbUpjSnJIVVFmUDZjRmNBRUFXak80WkVWU0s4M0t4SzJyMzNzWmx4ak5xWUZ5T1lIRVBNSXZqMEp2RmI4QVdNWm9iQjNCeWIifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "77" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:58 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "07916469-dbeb-4cfb-829b-4f7a8c14b74d" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiQmFkUGFyYW1ldGVyIiwibWVzc2FnZSI6IlRoZSBwYXJhbWV0ZXIgaXMgaW5jb3JyZWN0LlxyXG4ifX0=" + } + }, + { + "ID": "b4a4e6b6b5166004", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "373" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IlJTTko3ZTBqb1YzYjJEMElwVHVRM0xEWVJ2MUFubVRRR2thNzV0dHpqeEF1ai1EV0pRZElTZ1Z4YjE2bWM2MWdUcGFXS2hZX2VsRmhnSTZEY0dKc1V6QjdtMGJqR0dac2xub3htaHItMFdULXNUWTdyQmNSTURjcHN4MmxXX2VaZmVYdWJDRm5DdGJtek1JQjc3M2ZUTHpCcU9SUGx0VV9yM1ZhLTNpYlltV3ZfUDYzZnVKV1JfZDM0NDBrY05jemQxaG5NWGJGYzJLNDI3WVNWd0pudml4dGtXMFZxd1pyWS1yS3ZIMHNnMkNsT1lZUjhpS015S29yb0pPTlBDZ1l5TEVYYjM0eGYycTVQVTVpWENheDFFSHotbkJYQUJBRm96dUdSRlVpdk55c1N0cTk5N0daY1l6YW1CY2ptQnhEekNMNDlDYnhXX0FGakdhR3dkeWEifQ==" + ] + }, + "Response": { + "StatusCode": 400, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "77" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:58 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "cbaae157-d70e-456e-a0ff-e28ef920417d" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiQmFkUGFyYW1ldGVyIiwibWVzc2FnZSI6IlRoZSBwYXJhbWV0ZXIgaXMgaW5jb3JyZWN0LlxyXG4ifX0=" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestEncryptDecrypt.replay b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestEncryptDecrypt.replay new file mode 100644 index 000000000..5f87a16ac --- /dev/null +++ b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestEncryptDecrypt.replay @@ -0,0 +1,252 @@ +{ + "Initial": "AQAAAA7dVMEWMy+KVQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": null, + "RemoveParams": [ + "^se$", + "^sig$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "4a0fc5db318bcea5", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/encrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 401, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "97" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:55 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "Www-Authenticate": [ + "Bearer authorization=\"https://login.microsoftonline.com/db44ed8f-85f7-4f22-b378-3bb9fa3d62ff\", resource=\"https://vault.azure.net\"" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "e00ef750-5277-4136-b0d8-c1056ada6a49" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiVW5hdXRob3JpemVkIiwibWVzc2FnZSI6IkFLVjEwMDAwOiBSZXF1ZXN0IGlzIG1pc3NpbmcgYSBCZWFyZXIgb3IgUG9QIHRva2VuLiJ9fQ==" + } + }, + { + "ID": "7b07511562d59aa4", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/encrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "61" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "437" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:55 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "30d1805f-2f50-4365-b90f-917a30072462" + ] + }, + "Body": "eyJraWQiOiJodHRwczovL2dvLWNkay52YXVsdC5henVyZS5uZXQva2V5cy90ZXN0MS9iM2IzMWYyOTIyNjI0ZTFkYTdhNDJlNGQwNGQ0NDExMCIsInZhbHVlIjoiTG41dVZ5VHY1dHhmdF9wWE80cFJKbklBQXJ5eVZYazF2N21jUzdoSkpvTW0wTGg0NEg2UnREczVXcDZvazQzTXpRdW1DbEhDZnJQSGhqQ0xIZEIyWVl5X2tPWFhNRUdMTDVGdEJCOWJEeThZN0RZVkZsUzhTUnJKTVZ0YjJYTm5TMjZyZEF6d1dWVU1rQ2V0VDIzamNxZ1NhRHUxSHZwV1BYZUhRLUZMWW5ubHlpd0lheldoQkU5b2FoNjVLRUROaDFFclBZQXpETzA1bWtucVJsUVRJaE5faFVKRFRyMFZ1Ukl2cWJVeWp1Z3dwNi1tSjdNd0R4dDBjVDExcHk2WkJwdk1BMTZxV09PTV8yZWFjTi1pM3E1NlRsdElQQ2FMVFZvUTUxcXdTSTd4TzZWTnAxTTl4d1hRN282M0tsQzIyZWpUNl9XTTdEQ1ZlR09rbFVGalN3In0=" + } + }, + { + "ID": "0e4fac0d75eabb41", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "375" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IkxuNXVWeVR2NXR4ZnRfcFhPNHBSSm5JQUFyeXlWWGsxdjdtY1M3aEpKb01tMExoNDRINlJ0RHM1V3A2b2s0M016UXVtQ2xIQ2ZyUEhoakNMSGRCMllZeV9rT1hYTUVHTEw1RnRCQjliRHk4WTdEWVZGbFM4U1JySk1WdGIyWE5uUzI2cmRBendXVlVNa0NldFQyM2pjcWdTYUR1MUh2cFdQWGVIUS1GTFlubmx5aXdJYXpXaEJFOW9haDY1S0VETmgxRXJQWUF6RE8wNW1rbnFSbFFUSWhOX2hVSkRUcjBWdVJJdnFiVXlqdWd3cDYtbUo3TXdEeHQwY1QxMXB5NlpCcHZNQTE2cVdPT01fMmVhY04taTNxNTZUbHRJUENhTFRWb1E1MXF3U0k3eE82Vk5wMU05eHdYUTdvNjNLbEMyMmVqVDZfV003RENWZUdPa2xVRmpTdyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "123" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:55 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "c9a6d604-8e08-4626-a5fb-81fa1e501ae0" + ] + }, + "Body": "eyJraWQiOiJodHRwczovL2dvLWNkay52YXVsdC5henVyZS5uZXQva2V5cy90ZXN0MS9iM2IzMWYyOTIyNjI0ZTFkYTdhNDJlNGQwNGQ0NDExMCIsInZhbHVlIjoiU1NkdElHRWdjMlZqY21WMElHMWxjM05oWjJVaCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestMultipleEncryptionsNotEqual.replay b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestMultipleEncryptionsNotEqual.replay new file mode 100644 index 000000000..ff3a04811 --- /dev/null +++ b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestMultipleEncryptionsNotEqual.replay @@ -0,0 +1,392 @@ +{ + "Initial": "AQAAAA7dVMEYB0xRvAAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": null, + "RemoveParams": [ + "^se$", + "^sig$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "87cfa126e83fba4c", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/encrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 401, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "97" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:55 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "Www-Authenticate": [ + "Bearer authorization=\"https://login.microsoftonline.com/db44ed8f-85f7-4f22-b378-3bb9fa3d62ff\", resource=\"https://vault.azure.net\"" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "5c7b2556-617c-467c-bfd1-ec29f132c664" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiVW5hdXRob3JpemVkIiwibWVzc2FnZSI6IkFLVjEwMDAwOiBSZXF1ZXN0IGlzIG1pc3NpbmcgYSBCZWFyZXIgb3IgUG9QIHRva2VuLiJ9fQ==" + } + }, + { + "ID": "595c75ecf07ca8fe", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/encrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "61" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "437" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:56 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "7cdc50ec-abcb-4714-86e1-f7e4f7cb6f81" + ] + }, + "Body": "eyJraWQiOiJodHRwczovL2dvLWNkay52YXVsdC5henVyZS5uZXQva2V5cy90ZXN0MS9iM2IzMWYyOTIyNjI0ZTFkYTdhNDJlNGQwNGQ0NDExMCIsInZhbHVlIjoiSkNlZEhqVGtQNXl3aUgzTk1tNGZ6M1ljX25sdEtyTzlTOFI3eEl2OUU1blJvOWg0a21vR09QQ3FoMEVlT1ZhMGNVa1VfOTZtVVg0U3hjQnR5OWQ1SHBCNUJydHo3cnNpaTVMVEpfanhkMEdIWVhZbXotVnVvcDRzdUZ3eTI2NjF4N0xfX1E1eURVTWpQUGtna1dkRGFzZUJCLWxjRHcyN0poY1pCUFRicHhtRUVaS21kbzdkcDVRVVkzeV9LVEJkR3hycEJyRDBMaE1xNWU0ZEVYZWhDVzRoa21kSTdrZktQTTRzLTA3RThPRXNPbUwwUlZNZTFCNFRqOW5Nemp1NVNKMzVIWl9hUXAxWlBGOWlGMzFNM2dUbFZFOUtINmF5U3B2QTZhWHZTZ0JtQWhFeXZKbklVbGU2Y1d4VXUyVzVnZDVvSW5tT0VUVFVQbXA2NzlHOGVBIn0=" + } + }, + { + "ID": "ff577dc86a621d92", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/encrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "61" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "437" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:56 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "e9384d4a-16b6-4ba9-b135-9ccb9af324c3" + ] + }, + "Body": "eyJraWQiOiJodHRwczovL2dvLWNkay52YXVsdC5henVyZS5uZXQva2V5cy90ZXN0MS9iM2IzMWYyOTIyNjI0ZTFkYTdhNDJlNGQwNGQ0NDExMCIsInZhbHVlIjoiVXBVTmZFbV83VVNEdGNWMW96ZDNkemhfT2hwQ0VuRXpsZ3p6SVo0Z0dIVHd5MWNkWEt1MHRLc2cxYncySDFfSDIyR3llLTd6dW9aTWlRbEZyRnFBUFpBZ3BIUlFZMzFzRENqU01uN1NKdXRVczFqcjc3WERtdWZoS3IzY2tzMUd0UjRfbjhvbF94OGpxZnAwc3ZkczFuMzBDWVduSVV0YlFXY1AzVWRXZmhRMzBZNTJ3WU1kN3NHdmxucU0wNUo1b0M1cUNtX1h1dklCQ09pVTNkYUV0R1VfbzNaT1pHbnZjREdfOW9HaC1sOHBoUWpMRUkydjc1bGtscDg2ajJsMjZ3MnNZLXc2M3p6UGR0MFBvS2lmdGVJRGU5Y1BlYXdLV2gxTkhjb2lWQXhGWFUxUkpKbUplNjlZLTdXNklJTGg1SjFfMzVTR2h5emVHVThiNVl5QnlRIn0=" + } + }, + { + "ID": "f888049dd84a6e09", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "375" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IkpDZWRIalRrUDV5d2lIM05NbTRmejNZY19ubHRLck85UzhSN3hJdjlFNW5SbzloNGttb0dPUENxaDBFZU9WYTBjVWtVXzk2bVVYNFN4Y0J0eTlkNUhwQjVCcnR6N3JzaWk1TFRKX2p4ZDBHSFlYWW16LVZ1b3A0c3VGd3kyNjYxeDdMX19RNXlEVU1qUFBrZ2tXZERhc2VCQi1sY0R3MjdKaGNaQlBUYnB4bUVFWkttZG83ZHA1UVVZM3lfS1RCZEd4cnBCckQwTGhNcTVlNGRFWGVoQ1c0aGttZEk3a2ZLUE00cy0wN0U4T0VzT21MMFJWTWUxQjRUajluTXpqdTVTSjM1SFpfYVFwMVpQRjlpRjMxTTNnVGxWRTlLSDZheVNwdkE2YVh2U2dCbUFoRXl2Sm5JVWxlNmNXeFV1Mlc1Z2Q1b0lubU9FVFRVUG1wNjc5RzhlQSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "123" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:56 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "0c05d67a-d0ad-4f77-bcc8-dfacdb1fd02c" + ] + }, + "Body": "eyJraWQiOiJodHRwczovL2dvLWNkay52YXVsdC5henVyZS5uZXQva2V5cy90ZXN0MS9iM2IzMWYyOTIyNjI0ZTFkYTdhNDJlNGQwNGQ0NDExMCIsInZhbHVlIjoiU1NkdElHRWdjMlZqY21WMElHMWxjM05oWjJVaCJ9" + } + }, + { + "ID": "172910236683587b", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "375" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IlVwVU5mRW1fN1VTRHRjVjFvemQzZHpoX09ocENFbkV6bGd6eklaNGdHSFR3eTFjZFhLdTB0S3NnMWJ3MkgxX0gyMkd5ZS03enVvWk1pUWxGckZxQVBaQWdwSFJRWTMxc0RDalNNbjdTSnV0VXMxanI3N1hEbXVmaEtyM2NrczFHdFI0X244b2xfeDhqcWZwMHN2ZHMxbjMwQ1lXbklVdGJRV2NQM1VkV2ZoUTMwWTUyd1lNZDdzR3ZsbnFNMDVKNW9DNXFDbV9YdXZJQkNPaVUzZGFFdEdVX28zWk9aR252Y0RHXzlvR2gtbDhwaFFqTEVJMnY3NWxrbHA4NmoybDI2dzJzWS13NjN6elBkdDBQb0tpZnRlSURlOWNQZWF3S1doMU5IY29pVkF4RlhVMVJKSm1KZTY5WS03VzZJSUxoNUoxXzM1U0doeXplR1U4YjVZeUJ5USJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "123" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:56 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "3134cd8b-3b02-44c9-a9d0-848d32fbe3ba" + ] + }, + "Body": "eyJraWQiOiJodHRwczovL2dvLWNkay52YXVsdC5henVyZS5uZXQva2V5cy90ZXN0MS9iM2IzMWYyOTIyNjI0ZTFkYTdhNDJlNGQwNGQ0NDExMCIsInZhbHVlIjoiU1NkdElHRWdjMlZqY21WMElHMWxjM05oWjJVaCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestMultipleKeys.replay b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestMultipleKeys.replay new file mode 100644 index 000000000..6d4118cad --- /dev/null +++ b/go-cloud/secrets/azurekeyvault/testdata/TestConformance/TestMultipleKeys.replay @@ -0,0 +1,465 @@ +{ + "Initial": "AQAAAA7dVMEZA4bkdQAA", + "Version": "0.2", + "Converter": { + "ScrubBody": null, + "ClearHeaders": [ + "^X-Goog-.*Encryption-Key$", + "^X-Ms-Date$", + "^User-Agent$" + ], + "RemoveRequestHeaders": [ + "^Authorization$", + "^Proxy-Authorization$", + "^Connection$", + "^Content-Type$", + "^Date$", + "^Host$", + "^Transfer-Encoding$", + "^Via$", + "^X-Forwarded-.*$", + "^X-Cloud-Trace-Context$", + "^X-Goog-Api-Client$", + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "RemoveResponseHeaders": [ + "^X-Google-.*$", + "^X-Gfe-.*$" + ], + "ClearParams": null, + "RemoveParams": [ + "^se$", + "^sig$", + "^X-Ms-Date$" + ] + }, + "Entries": [ + { + "ID": "2a2bedfe2e265a6c", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/encrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 401, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "97" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:56 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "Www-Authenticate": [ + "Bearer authorization=\"https://login.microsoftonline.com/db44ed8f-85f7-4f22-b378-3bb9fa3d62ff\", resource=\"https://vault.azure.net\"" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "ac6b5a19-0c4f-4571-b782-8cfe5771dcc1" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiVW5hdXRob3JpemVkIiwibWVzc2FnZSI6IkFLVjEwMDAwOiBSZXF1ZXN0IGlzIG1pc3NpbmcgYSBCZWFyZXIgb3IgUG9QIHRva2VuLiJ9fQ==" + } + }, + { + "ID": "80675cb8a4aabf46", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/encrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "61" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "437" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:56 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "7fed2c8f-2c9b-4449-b157-578c1fd73408" + ] + }, + "Body": "eyJraWQiOiJodHRwczovL2dvLWNkay52YXVsdC5henVyZS5uZXQva2V5cy90ZXN0MS9iM2IzMWYyOTIyNjI0ZTFkYTdhNDJlNGQwNGQ0NDExMCIsInZhbHVlIjoiRWZWeFBXU1VFMGZuWTg1aXBsak5NT3I0eHJDLXUtbDFtUzFpMk9zNVU4eHdHTDBLOVNjakM5YUs0T0JXdXFiVVJnOVZwNnZpTXVUcWM2cUlGTFZILXFiUkQ4SE80d3F6eXBfNjlacW1aSWdKREF2NGd3a290b2phWWJCT3RTdnF1S1Bma1NRN05pR2UycXlxRjRYVkR5SWl2ODlxY2dlTmtPcnhMam9yVlN4ZU5ZZnBpNXlvdFRiRFh2Sk1IMGpUMXljaWlSZ1pEUDdqMXI1MHhmODIxdUc4aUlxcmtYRzJPTUxDNE04Sy1wUW9tSTVxa24xVF8wRjc2ckdXTzBuR3lFdXZhcE1qZEkwNEw0d29OS0VENDdzRVBiVUxQQUNmY0g2bVFwWno1YmlvUFNGMXpFN0FZc194blFJNmRmSlJMNmZ4bTQ4LU53VlJ5QlRqajZiUmt3In0=" + } + }, + { + "ID": "bb023a17c51d046d", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test2/encrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "0" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "", + "BodyParts": [ + "" + ] + }, + "Response": { + "StatusCode": 401, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "97" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:56 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "Www-Authenticate": [ + "Bearer authorization=\"https://login.microsoftonline.com/db44ed8f-85f7-4f22-b378-3bb9fa3d62ff\", resource=\"https://vault.azure.net\"" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "9988f05d-9995-4eaf-ae5f-bb97a28ba9d9" + ] + }, + "Body": "eyJlcnJvciI6eyJjb2RlIjoiVW5hdXRob3JpemVkIiwibWVzc2FnZSI6IkFLVjEwMDAwOiBSZXF1ZXN0IGlzIG1pc3NpbmcgYSBCZWFyZXIgb3IgUG9QIHRva2VuLiJ9fQ==" + } + }, + { + "ID": "e98f74283d9dac54", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test2/encrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "61" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IlNTZHRJR0VnYzJWamNtVjBJRzFsYzNOaFoyVWgifQ==" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "437" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:57 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "3ea39fde-30c8-4d06-b48c-f891b372e9d7" + ] + }, + "Body": "eyJraWQiOiJodHRwczovL2dvLWNkay52YXVsdC5henVyZS5uZXQva2V5cy90ZXN0Mi9mNDFiOWI4ZDU4NmU0MGI5YjFhNDVjZTZiN2VjN2Q2YyIsInZhbHVlIjoiRURpYmJzQ2pVOUtTYXpYU2M3RTlRa0F6RUtmajdkQ0Y4R0JWRjg4R01LMDRZRmJwVW5ObzdtSU9YaU5zYy1lbTZIYWh4ZDJMcDJaMlVKTWszcVVqSmREZDlYZFk0TUNpdFNyX3NPSjFncHVCNjNSM0ZhM3N2WEpnaFltdFp4UFU4U2c1RFRuV2hlMWRXSkVtRExqMDBqTDZCZURjY2dZNkFJNlFwS2d4Y01VbFVxQTlPQ2dsamh2Q1dEaW5QVVB6R2pXYkFleE5CZFgyZkhuRzBwYm8zWFA4RVYzcUI3N05QUnVSZjdjMmJ1cFZ4aUI5OGtHY1ZCSjljRWNBQ1VrYm9Jc3hONm96SlRFYkxHSWxfU2ZBN0Flb3k1b0RQM2NiN21GZHRvZXhLVi0zSDJ5emFRd0JHTWJkSWtzVlctTHNVQm1jclpydTVGMlZNMUhLSEFDRHFBIn0=" + } + }, + { + "ID": "81c335517a88fdea", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test1/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "375" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IkVmVnhQV1NVRTBmblk4NWlwbGpOTU9yNHhyQy11LWwxbVMxaTJPczVVOHh3R0wwSzlTY2pDOWFLNE9CV3VxYlVSZzlWcDZ2aU11VHFjNnFJRkxWSC1xYlJEOEhPNHdxenlwXzY5WnFtWklnSkRBdjRnd2tvdG9qYVliQk90U3ZxdUtQZmtTUTdOaUdlMnF5cUY0WFZEeUlpdjg5cWNnZU5rT3J4TGpvclZTeGVOWWZwaTV5b3RUYkRYdkpNSDBqVDF5Y2lpUmdaRFA3ajFyNTB4ZjgyMXVHOGlJcXJrWEcyT01MQzRNOEstcFFvbUk1cWtuMVRfMEY3NnJHV08wbkd5RXV2YXBNamRJMDRMNHdvTktFRDQ3c0VQYlVMUEFDZmNINm1RcFp6NWJpb1BTRjF6RTdBWXNfeG5RSTZkZkpSTDZmeG00OC1Od1ZSeUJUamo2YlJrdyJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "123" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:57 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "3798e708-9f81-484a-a71f-ed5ee78358ad" + ] + }, + "Body": "eyJraWQiOiJodHRwczovL2dvLWNkay52YXVsdC5henVyZS5uZXQva2V5cy90ZXN0MS9iM2IzMWYyOTIyNjI0ZTFkYTdhNDJlNGQwNGQ0NDExMCIsInZhbHVlIjoiU1NkdElHRWdjMlZqY21WMElHMWxjM05oWjJVaCJ9" + } + }, + { + "ID": "914b2c2d27098f6e", + "Request": { + "Method": "POST", + "URL": "https://go-cdk.vault.azure.net/keys/test2/decrypt?api-version=7.4", + "Header": { + "Accept": [ + "application/json" + ], + "Accept-Encoding": [ + "gzip" + ], + "Content-Length": [ + "375" + ], + "User-Agent": [ + "CLEARED" + ] + }, + "MediaType": "application/json", + "BodyParts": [ + "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJ2YWx1ZSI6IkVEaWJic0NqVTlLU2F6WFNjN0U5UWtBekVLZmo3ZENGOEdCVkY4OEdNSzA0WUZicFVuTm83bUlPWGlOc2MtZW02SGFoeGQyTHAyWjJVSk1rM3FVakpkRGQ5WGRZNE1DaXRTcl9zT0oxZ3B1QjYzUjNGYTNzdlhKZ2hZbXRaeFBVOFNnNURUbldoZTFkV0pFbURMajAwakw2QmVEY2NnWTZBSTZRcEtneGNNVWxVcUE5T0NnbGpodkNXRGluUFVQekdqV2JBZXhOQmRYMmZIbkcwcGJvM1hQOEVWM3FCNzdOUFJ1UmY3YzJidXBWeGlCOThrR2NWQko5Y0VjQUNVa2JvSXN4TjZvekpURWJMR0lsX1NmQTdBZW95NW9EUDNjYjdtRmR0b2V4S1YtM0gyeXphUXdCR01iZElrc1ZXLUxzVUJtY3JacnU1RjJWTTFIS0hBQ0RxQSJ9" + ] + }, + "Response": { + "StatusCode": 200, + "Proto": "HTTP/1.1", + "ProtoMajor": 1, + "ProtoMinor": 1, + "Header": { + "Cache-Control": [ + "no-cache" + ], + "Content-Length": [ + "123" + ], + "Content-Type": [ + "application/json; charset=utf-8" + ], + "Date": [ + "Wed, 07 Feb 2024 00:08:57 GMT" + ], + "Expires": [ + "-1" + ], + "Pragma": [ + "no-cache" + ], + "Strict-Transport-Security": [ + "max-age=31536000;includeSubDomains" + ], + "X-Content-Type-Options": [ + "nosniff" + ], + "X-Ms-Keyvault-Network-Info": [ + "conn_type=Ipv4;addr=34.125.120.109;act_addr_fam=InterNetwork;" + ], + "X-Ms-Keyvault-Region": [ + "centralus" + ], + "X-Ms-Keyvault-Service-Version": [ + "1.9.1222.3" + ], + "X-Ms-Request-Id": [ + "e11f07cc-0e34-4353-8f22-89c168368eb5" + ] + }, + "Body": "eyJraWQiOiJodHRwczovL2dvLWNkay52YXVsdC5henVyZS5uZXQva2V5cy90ZXN0Mi9mNDFiOWI4ZDU4NmU0MGI5YjFhNDVjZTZiN2VjN2Q2YyIsInZhbHVlIjoiU1NkdElHRWdjMlZqY21WMElHMWxjM05oWjJVaCJ9" + } + } + ] +} \ No newline at end of file diff --git a/go-cloud/secrets/driver/driver.go b/go-cloud/secrets/driver/driver.go new file mode 100644 index 000000000..3f5b86dfc --- /dev/null +++ b/go-cloud/secrets/driver/driver.go @@ -0,0 +1,51 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 driver defines interfaces to be implemented by secrets drivers, which +// will be used by the secrets package to interact with the underlying services. +// Application code should use package secrets. +package driver // import "gocloud.dev/secrets/driver" + +import ( + "context" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" +) + +// Keeper holds the key information to encrypt a plain text message into a +// cipher message, as well as decrypt a cipher message into a plain text +// message. +type Keeper interface { + // Decrypt decrypts the ciphertext and returns the plaintext or an error. + // Decrypt *may* decrypt ciphertexts that were encrypted using a different + // key than the one provided to Keeper; some drivers encode the key used + // in the ciphertext. + Decrypt(ctx context.Context, ciphertext []byte) ([]byte, error) + + // Encrypt encrypts the plaintext using the key, and returns the ciphertext. + Encrypt(ctx context.Context, plaintext []byte) ([]byte, error) + + // Close releases any resources used for the Keeper. + Close() error + + // ErrorAs allows drivers to expose driver-specific types for returned + // errors. + // + // See https://gocloud.dev/concepts/as/ for background information. + ErrorAs(err error, i any) bool + + // ErrorCode should return a code that describes the error, which was returned + // by one of the other methods in this interface. + ErrorCode(error) gcerrors.ErrorCode +} diff --git a/go-cloud/secrets/drivertest/drivertest.go b/go-cloud/secrets/drivertest/drivertest.go new file mode 100644 index 000000000..53c7b9aee --- /dev/null +++ b/go-cloud/secrets/drivertest/drivertest.go @@ -0,0 +1,314 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 drivertest provides a conformance test for implementations of +// the secrets driver. +package drivertest // import "gocloud.dev/secrets/drivertest" + +import ( + "bytes" + "context" + "errors" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "github.com/DataDog/iceberg-go/go-cloud/secrets/driver" +) + +// Harness descibes the functionality test harnesses must provide to run +// conformance tests. +type Harness interface { + // MakeDriver returns a pair of driver.Keeper, each backed by a different key. + MakeDriver(ctx context.Context) (driver.Keeper, driver.Keeper, error) + + // Close is called when the test is complete. + Close() +} + +// HarnessMaker describes functions that construct a harness for running tests. +// It is called exactly once per test. +type HarnessMaker func(ctx context.Context, t *testing.T) (Harness, error) + +// AsTest represents a test of As functionality. +// The conformance test: +// 1. Tries to decrypt malformed message, and calls ErrorCheck with the error. +type AsTest interface { + // Name returns a descriptive name for the test. + Name() string + // ErrorCheck is called to allow verification of Keeper.ErrorAs. + ErrorCheck(k *secrets.Keeper, err error) error +} + +type verifyAsFailsOnNil struct{} + +func (v verifyAsFailsOnNil) Name() string { + return "verify As returns false when passed nil" +} + +func (v verifyAsFailsOnNil) ErrorCheck(k *secrets.Keeper, err error) (ret error) { + defer func() { + if recover() == nil { + ret = errors.New("want ErrorAs to panic when passed nil") + } + }() + k.ErrorAs(err, nil) + return nil +} + +// RunConformanceTests runs conformance tests for driver implementations of secret management. +func RunConformanceTests(t *testing.T, newHarness HarnessMaker, asTests []AsTest) { + t.Helper() + + t.Run("TestEncryptDecrypt", func(t *testing.T) { + testEncryptDecrypt(t, newHarness) + }) + t.Run("TestMultipleEncryptionsNotEqual", func(t *testing.T) { + testMultipleEncryptionsNotEqual(t, newHarness) + }) + t.Run("TestMultipleKeys", func(t *testing.T) { + testMultipleKeys(t, newHarness) + }) + t.Run("TestDecryptMalformedError", func(t *testing.T) { + testDecryptMalformedError(t, newHarness) + }) + asTests = append(asTests, verifyAsFailsOnNil{}) + t.Run("TestAs", func(t *testing.T) { + for _, tc := range asTests { + if tc.Name() == "" { + t.Fatal("AsTest.Name is required") + } + t.Run(tc.Name(), func(t *testing.T) { + testAs(t, newHarness, tc) + }) + } + }) +} + +// testEncryptDecrypt tests the functionality of encryption and decryption +func testEncryptDecrypt(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + ctx := context.Background() + harness, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer harness.Close() + + drv, _, err := harness.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + keeper := secrets.NewKeeper(drv) + defer keeper.Close() + + msg := []byte("I'm a secret message!") + encryptedMsg, err := keeper.Encrypt(ctx, msg) + if err != nil { + t.Fatal(err) + } + if cmp.Equal(msg, encryptedMsg) { + t.Errorf("Got encrypted message %v, want it to differ from original message %v", string(msg), string(encryptedMsg)) + } + decryptedMsg, err := keeper.Decrypt(ctx, encryptedMsg) + if err != nil { + t.Fatal(err) + } + if !cmp.Equal(msg, decryptedMsg) { + t.Errorf("Got decrypted message %v, want it to match original message %v", string(msg), string(decryptedMsg)) + } +} + +// testMultipleEncryptionsNotEqual tests that encrypting a plaintext multiple +// times with the same key works, and that the encrypted bytes are different. +func testMultipleEncryptionsNotEqual(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + ctx := context.Background() + harness, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer harness.Close() + + drv, _, err := harness.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + keeper := secrets.NewKeeper(drv) + defer keeper.Close() + + msg := []byte("I'm a secret message!") + encryptedMsg1, err := keeper.Encrypt(ctx, msg) + if err != nil { + t.Fatal(err) + } + encryptedMsg2, err := keeper.Encrypt(ctx, msg) + if err != nil { + t.Fatal(err) + } + if cmp.Equal(encryptedMsg1, encryptedMsg2) { + t.Errorf("Got same encrypted messages from multiple encryptions %v, want them to be different", string(encryptedMsg1)) + } + decryptedMsg, err := keeper.Decrypt(ctx, encryptedMsg1) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(decryptedMsg, msg) { + t.Errorf("got decrypted %q want %q", string(decryptedMsg), string(msg)) + } + decryptedMsg, err = keeper.Decrypt(ctx, encryptedMsg2) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(decryptedMsg, msg) { + t.Errorf("got decrypted %q want %q", string(decryptedMsg), string(msg)) + } +} + +// testMultipleKeys tests that encrypting the same text with different +// keys works, and that the encrypted bytes are different. +func testMultipleKeys(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + ctx := context.Background() + harness, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer harness.Close() + + drv1, drv2, err := harness.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + keeper1 := secrets.NewKeeper(drv1) + defer keeper1.Close() + keeper2 := secrets.NewKeeper(drv2) + defer keeper2.Close() + + msg := []byte("I'm a secret message!") + encryptedMsg1, err := keeper1.Encrypt(ctx, msg) + if err != nil { + t.Fatal(err) + } + encryptedMsg2, err := keeper2.Encrypt(ctx, msg) + if err != nil { + t.Fatal(err) + } + if cmp.Equal(encryptedMsg1, encryptedMsg2) { + t.Errorf("Got same encrypted messages from multiple encryptions %v, want them to be different", string(encryptedMsg1)) + } + + // We cannot assert that decrypting encryptedMsg1 with keeper2 fails, + // or that decrypting encryptedMsg2 with keeper1 fails, as Decrypt is allowed + // to decrypt using a different key than the one given to Keeper. + + decryptedMsg, err := keeper1.Decrypt(ctx, encryptedMsg1) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(decryptedMsg, msg) { + t.Errorf("got decrypted %q want %q", string(decryptedMsg), string(msg)) + } + + decryptedMsg, err = keeper2.Decrypt(ctx, encryptedMsg2) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(decryptedMsg, msg) { + t.Errorf("got decrypted %q want %q", string(decryptedMsg), string(msg)) + } +} + +// testDecryptMalformedError tests decryption returns an error when the +// ciphertext is malformed. +func testDecryptMalformedError(t *testing.T, newHarness HarnessMaker) { + t.Helper() + + ctx := context.Background() + harness, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer harness.Close() + + drv, _, err := harness.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + keeper := secrets.NewKeeper(drv) + defer keeper.Close() + + msg := []byte("I'm a secret message!") + encryptedMsg, err := keeper.Encrypt(ctx, msg) + if err != nil { + t.Fatal(err) + } + copyEncryptedMsg := func() []byte { + return append([]byte{}, encryptedMsg...) + } + + l := len(encryptedMsg) + for _, tc := range []struct { + name string + malformed []byte + }{ + { + name: "wrong first byte", + malformed: append([]byte{encryptedMsg[0] + 1}, encryptedMsg[1:]...), + }, + { + name: "missing second byte", + malformed: append(copyEncryptedMsg()[:1], encryptedMsg[2:]...), + }, + { + name: "wrong last byte", + malformed: append(copyEncryptedMsg()[:l-2], encryptedMsg[l-1]-1), + }, + } { + t.Run(tc.name, func(t *testing.T) { + if _, err := keeper.Decrypt(ctx, []byte(tc.malformed)); err == nil { + t.Error("Got nil, want decrypt error") + } + }) + } +} + +func testAs(t *testing.T, newHarness HarnessMaker, tc AsTest) { + t.Helper() + + ctx := context.Background() + harness, err := newHarness(ctx, t) + if err != nil { + t.Fatal(err) + } + defer harness.Close() + + drv, _, err := harness.MakeDriver(ctx) + if err != nil { + t.Fatal(err) + } + keeper := secrets.NewKeeper(drv) + defer keeper.Close() + + _, gotErr := keeper.Decrypt(ctx, []byte("malformed cipher message")) + if gotErr == nil { + t.Error("Got nil, want decrypt error") + } + if err := tc.ErrorCheck(keeper, gotErr); err != nil { + t.Error(err) + } +} diff --git a/go-cloud/secrets/example_openkeeper_test.go b/go-cloud/secrets/example_openkeeper_test.go new file mode 100644 index 000000000..f26bfa2c2 --- /dev/null +++ b/go-cloud/secrets/example_openkeeper_test.go @@ -0,0 +1,58 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 secrets_test + +import ( + "context" + "fmt" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/secrets" + _ "github.com/DataDog/iceberg-go/go-cloud/secrets/localsecrets" +) + +func Example_openFromURL() { + ctx := context.Background() + + // Create a Keeper using a URL. + // This example uses "localsecrets", the in-memory implementation. + // We need to add a blank import line to register the localsecrets driver's + // URLOpener, which implements secrets.KeeperURLOpener: + // import _ "gocloud.dev/secrets/localsecrets" + // localsecrets registers for the "base64key" scheme. + // All secrets.OpenKeeper URLs also work with "secrets+" or "secrets+keeper+" prefixes, + // e.g., "secrets+base64key://..." or "secrets+variable+base64key://...". + // All secrets URLs also work with the "secrets+" prefix, e.g., "secrets+base64key://". + k, err := secrets.OpenKeeper(ctx, "base64key://smGbjm71Nxd1Ig5FS0wj9SlbzAIrnolCz9bQQ6uAhl4=") + if err != nil { + log.Fatal(err) + } + defer k.Close() + + // Now we can use k to encrypt/decrypt. + plaintext := []byte("Go CDK Secrets") + ciphertext, err := k.Encrypt(ctx, plaintext) + if err != nil { + log.Fatal(err) + } + decrypted, err := k.Decrypt(ctx, ciphertext) + if err != nil { + log.Fatal(err) + } + fmt.Println(string(decrypted)) + + // Output: + // Go CDK Secrets +} diff --git a/go-cloud/secrets/example_test.go b/go-cloud/secrets/example_test.go new file mode 100644 index 000000000..145fdb17a --- /dev/null +++ b/go-cloud/secrets/example_test.go @@ -0,0 +1,113 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 secrets_test + +import ( + "context" + "fmt" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/secrets" + _ "github.com/DataDog/iceberg-go/go-cloud/secrets/gcpkms" + "github.com/DataDog/iceberg-go/go-cloud/secrets/localsecrets" + "google.golang.org/grpc/status" +) + +func Example() { + ctx := context.Background() + + // Construct a *secrets.Keeper from one of the secrets subpackages. + // This example uses localsecrets. + sk, err := localsecrets.NewRandomKey() + if err != nil { + log.Fatal(err) + } + keeper := localsecrets.NewKeeper(sk) + defer keeper.Close() + + // Now we can use keeper to Encrypt. + plaintext := []byte("Go CDK Secrets") + ciphertext, err := keeper.Encrypt(ctx, plaintext) + if err != nil { + log.Fatal(err) + } + + // And/or Decrypt. + decrypted, err := keeper.Decrypt(ctx, ciphertext) + if err != nil { + log.Fatal(err) + } + fmt.Println(string(decrypted)) + + // Output: + // Go CDK Secrets +} + +func Example_errorAs() { + // This example is specific to the gcpkms implementation; it + // demonstrates access to the underlying google.golang.org/grpc/status.Status + // type. + // The types exposed for As by gcpkms are documented in + // https://godoc.org/gocloud.dev/secrets/gcpkms#hdr-As + ctx := context.Background() + + const url = "gcpkms://projects/proj/locations/global/keyRings/test/ring/wrongkey" + keeper, err := secrets.OpenKeeper(ctx, url) + if err != nil { + log.Fatal(err) + } + defer keeper.Close() + + plaintext := []byte("Go CDK secrets") + _, err = keeper.Encrypt(ctx, plaintext) + if err != nil { + var s *status.Status + if keeper.ErrorAs(err, &s) { + fmt.Println(s.Code()) + } + } +} + +func ExampleKeeper_Encrypt() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var keeper *secrets.Keeper + + plainText := []byte("Secrets secrets...") + cipherText, err := keeper.Encrypt(ctx, plainText) + if err != nil { + log.Fatal(err) + } + + // PRAGMA: On gocloud.dev, hide the rest of the function. + _ = cipherText +} + +func ExampleKeeper_Decrypt() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + var keeper *secrets.Keeper + + var cipherText []byte // obtained from elsewhere and random-looking + plainText, err := keeper.Decrypt(ctx, cipherText) + if err != nil { + log.Fatal(err) + } + + // PRAGMA: On gocloud.dev, hide the rest of the function. + _ = plainText +} diff --git a/go-cloud/secrets/gcpkms/example_test.go b/go-cloud/secrets/gcpkms/example_test.go new file mode 100644 index 000000000..f3a32b4ac --- /dev/null +++ b/go-cloud/secrets/gcpkms/example_test.go @@ -0,0 +1,64 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcpkms_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "github.com/DataDog/iceberg-go/go-cloud/secrets/gcpkms" +) + +func ExampleOpenKeeper() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Get a client to use with the KMS API. + client, done, err := gcpkms.Dial(ctx, nil) + if err != nil { + log.Fatal(err) + } + // Close the connection when done. + defer done() + + // You can also use gcpkms.KeyResourceID to construct this string. + const keyID = "projects/MYPROJECT/" + + "locations/MYLOCATION/" + + "keyRings/MYKEYRING/" + + "cryptoKeys/MYKEY" + + // Construct a *secrets.Keeper. + keeper := gcpkms.OpenKeeper(client, keyID, nil) + defer keeper.Close() +} + +func Example_openFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/secrets/gcpkms" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + keeper, err := secrets.OpenKeeper(ctx, + "gcpkms://projects/MYPROJECT/"+ + "locations/MYLOCATION/"+ + "keyRings/MYKEYRING/"+ + "cryptoKeys/MYKEY") + if err != nil { + log.Fatal(err) + } + defer keeper.Close() +} diff --git a/go-cloud/secrets/gcpkms/kms.go b/go-cloud/secrets/gcpkms/kms.go new file mode 100644 index 000000000..08d5f97b7 --- /dev/null +++ b/go-cloud/secrets/gcpkms/kms.go @@ -0,0 +1,203 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcpkms provides a secrets implementation backed by Google Cloud KMS. +// Use OpenKeeper to construct a *secrets.Keeper. +// +// # URLs +// +// For secrets.OpenKeeper, gcpkms registers for the scheme "gcpkms". +// The default URL opener will create a connection using use default +// credentials from the environment, as described in +// https://cloud.google.com/docs/authentication/production. +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// gcpkms exposes the following type for As: +// - Error: *google.golang.org/grpc/status.Status +package gcpkms // import "gocloud.dev/secrets/gcpkms" + +import ( + "context" + "fmt" + "net/url" + "path" + "sync" + + cloudkms "cloud.google.com/go/kms/apiv1" + "cloud.google.com/go/kms/apiv1/kmspb" + "github.com/google/wire" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/useragent" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "google.golang.org/api/option" + "google.golang.org/grpc/status" +) + +// endPoint is the address to access Google Cloud KMS API. +const endPoint = "cloudkms.googleapis.com:443" + +// Dial returns a client to use with Cloud KMS and a clean-up function to close +// the client after used. +func Dial(ctx context.Context, ts gcp.TokenSource) (*cloudkms.KeyManagementClient, func(), error) { + c, err := cloudkms.NewKeyManagementClient(ctx, option.WithTokenSource(ts), useragent.ClientOption("secrets")) + return c, func() { c.Close() }, err +} + +func init() { + secrets.DefaultURLMux().RegisterKeeper(Scheme, new(lazyCredsOpener)) +} + +// Set holds Wire providers for this package. +var Set = wire.NewSet( + Dial, + wire.Struct(new(URLOpener), "Client"), +) + +// lazyCredsOpener obtains Application Default Credentials on the first call +// lazyCredsOpener obtains Application Default Credentials on the first call +// to OpenKeeperURL. +type lazyCredsOpener struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *lazyCredsOpener) OpenKeeperURL(ctx context.Context, u *url.URL) (*secrets.Keeper, error) { + o.init.Do(func() { + creds, err := gcp.DefaultCredentials(ctx) + if err != nil { + o.err = err + return + } + client, _, err := Dial(ctx, creds.TokenSource) + if err != nil { + o.err = err + return + } + o.opener = &URLOpener{Client: client} + }) + if o.err != nil { + return nil, fmt.Errorf("open keeper %v: %v", u, o.err) + } + return o.opener.OpenKeeperURL(ctx, u) +} + +// Scheme is the URL scheme gcpkms registers its URLOpener under on secrets.DefaultMux. +const Scheme = "gcpkms" + +// URLOpener opens GCP KMS URLs like +// "gcpkms://projects/[PROJECT_ID]/locations/[LOCATION]/keyRings/[KEY_RING]/cryptoKeys/[KEY]". +// +// The URL host+path are used as the key resource ID; see +// https://cloud.google.com/kms/docs/object-hierarchy#key for more details. +// +// No query parameters are supported. +type URLOpener struct { + // Client must be non-nil and be authenticated with "cloudkms" scope or equivalent. + Client *cloudkms.KeyManagementClient + + // Options specifies the default options to pass to OpenKeeper. + Options KeeperOptions +} + +// OpenKeeperURL opens the GCP KMS URLs. +func (o *URLOpener) OpenKeeperURL(ctx context.Context, u *url.URL) (*secrets.Keeper, error) { + for param := range u.Query() { + return nil, fmt.Errorf("open keeper %v: invalid query parameter %q", u, param) + } + return OpenKeeper(o.Client, path.Join(u.Host, u.Path), &o.Options), nil +} + +// OpenKeeper returns a *secrets.Keeper that uses Google Cloud KMS. +// You can use KeyResourceID to construct keyResourceID from its parts, +// or provide the whole string if you have it (e.g., from the GCP console). +// See https://cloud.google.com/kms/docs/object-hierarchy#key for more details. +// See the package documentation for an example. +func OpenKeeper(client *cloudkms.KeyManagementClient, keyResourceID string, opts *KeeperOptions) *secrets.Keeper { + return secrets.NewKeeper(&keeper{ + keyResourceID: keyResourceID, + client: client, + }) +} + +// KeyResourceID constructs a key resourceID for GCP KMS. +// See https://cloud.google.com/kms/docs/object-hierarchy#key for more details. +func KeyResourceID(projectID, location, keyRing, key string) string { + return fmt.Sprintf("projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", + projectID, location, keyRing, key) +} + +// keeper implements driver.Keeper. +type keeper struct { + keyResourceID string + client *cloudkms.KeyManagementClient +} + +// Decrypt decrypts the ciphertext using the key constructed from ki. +func (k *keeper) Decrypt(ctx context.Context, ciphertext []byte) ([]byte, error) { + req := &kmspb.DecryptRequest{ + Name: k.keyResourceID, + Ciphertext: ciphertext, + } + resp, err := k.client.Decrypt(ctx, req) + if err != nil { + return nil, err + } + return resp.GetPlaintext(), nil +} + +// Encrypt encrypts the plaintext into a ciphertext. +func (k *keeper) Encrypt(ctx context.Context, plaintext []byte) ([]byte, error) { + req := &kmspb.EncryptRequest{ + Name: k.keyResourceID, + Plaintext: plaintext, + } + resp, err := k.client.Encrypt(ctx, req) + if err != nil { + return nil, err + } + return resp.GetCiphertext(), nil +} + +// Close implements driver.Keeper.Close. +func (k *keeper) Close() error { return nil } + +// ErrorAs implements driver.Keeper.ErrorAs. +func (k *keeper) ErrorAs(err error, i any) bool { + s, ok := status.FromError(err) + if !ok { + return false + } + p, ok := i.(**status.Status) + if !ok { + return false + } + *p = s + return true +} + +// ErrorCode implements driver.ErrorCode. +func (k *keeper) ErrorCode(err error) gcerrors.ErrorCode { + return gcerr.GRPCCode(err) +} + +// KeeperOptions controls Keeper behaviors. +// It is provided for future extensibility. +type KeeperOptions struct{} diff --git a/go-cloud/secrets/gcpkms/kms_test.go b/go-cloud/secrets/gcpkms/kms_test.go new file mode 100644 index 000000000..71ae593ea --- /dev/null +++ b/go-cloud/secrets/gcpkms/kms_test.go @@ -0,0 +1,140 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 gcpkms + +import ( + "context" + "errors" + "testing" + + cloudkms "cloud.google.com/go/kms/apiv1" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "github.com/DataDog/iceberg-go/go-cloud/secrets/driver" + "github.com/DataDog/iceberg-go/go-cloud/secrets/drivertest" + "golang.org/x/oauth2" + "google.golang.org/api/option" + "google.golang.org/grpc/status" +) + +// These constants capture values that were used during the last --record. +// If you want to use --record mode, +// 1. Update projectID to your GCP project name (not number!) +// 2. Enable the Cloud KMS API. +// 3. Create a key ring and a key, change their name below accordingly. +const ( + project = "go-cloud-test-216917" + location = "global" + keyRing = "test" + keyID1 = "password" + keyID2 = "password2" +) + +type harness struct { + client *cloudkms.KeyManagementClient + close func() +} + +func (h *harness) MakeDriver(ctx context.Context) (driver.Keeper, driver.Keeper, error) { + return &keeper{KeyResourceID(project, location, keyRing, keyID1), h.client}, + &keeper{KeyResourceID(project, location, keyRing, keyID2), h.client}, nil +} + +func (h *harness) Close() { + h.close() +} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + conn, done := setup.NewGCPgRPCConn(ctx, t, endPoint, "secrets") + client, err := cloudkms.NewKeyManagementClient(ctx, option.WithGRPCConn(conn)) + if err != nil { + return nil, err + } + return &harness{ + client: client, + close: func() { + client.Close() + done() + }, + }, nil +} + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct{} + +func (v verifyAs) Name() string { + return "verify As function" +} + +func (v verifyAs) ErrorCheck(k *secrets.Keeper, err error) error { + var s *status.Status + if !k.ErrorAs(err, &s) { + return errors.New("Keeper.ErrorAs failed") + } + return nil +} + +// KMS-specific tests. + +func TestNoConnectionError(t *testing.T) { + ctx := context.Background() + client, done, err := Dial(ctx, oauth2.StaticTokenSource(&oauth2.Token{ + AccessToken: "fake", + })) + if err != nil { + t.Fatal(err) + } + defer done() + + keeper := OpenKeeper(client, "", nil) + defer keeper.Close() + + if _, err := keeper.Encrypt(ctx, []byte("test")); err == nil { + t.Error("got nil, want rpc error") + } +} + +func TestOpenKeeper(t *testing.T) { + cleanup := setup.FakeGCPDefaultCredentials(t) + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"gcpkms://projects/MYPROJECT/locations/MYLOCATION/keyRings/MYKEYRING/cryptoKeys/MYKEY", false}, + // Invalid query parameter. + {"gcpkms://projects/MYPROJECT/locations/MYLOCATION/keyRings/MYKEYRING/cryptoKeys/MYKEY?param=val", true}, + } + + ctx := context.Background() + for _, test := range tests { + keeper, err := secrets.OpenKeeper(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if err == nil { + if err = keeper.Close(); err != nil { + t.Errorf("%s: got error during close: %v", test.URL, err) + } + } + } +} diff --git a/go-cloud/secrets/gcpkms/testdata/TestConformance/TestAs/verify_As_function.replay b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestAs/verify_As_function.replay new file mode 100644 index 000000000..6de6e306a Binary files /dev/null and b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestAs/verify_As_function.replay differ diff --git a/go-cloud/secrets/gcpkms/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay new file mode 100644 index 000000000..6de6e306a Binary files /dev/null and b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestAs/verify_As_returns_false_when_passed_nil.replay differ diff --git a/go-cloud/secrets/gcpkms/testdata/TestConformance/TestDecryptMalformedError.replay b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestDecryptMalformedError.replay new file mode 100644 index 000000000..7cec80994 Binary files /dev/null and b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestDecryptMalformedError.replay differ diff --git a/go-cloud/secrets/gcpkms/testdata/TestConformance/TestEncryptDecrypt.replay b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestEncryptDecrypt.replay new file mode 100644 index 000000000..39b3d1cd3 Binary files /dev/null and b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestEncryptDecrypt.replay differ diff --git a/go-cloud/secrets/gcpkms/testdata/TestConformance/TestMultipleEncryptionsNotEqual.replay b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestMultipleEncryptionsNotEqual.replay new file mode 100644 index 000000000..1b348d71e Binary files /dev/null and b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestMultipleEncryptionsNotEqual.replay differ diff --git a/go-cloud/secrets/gcpkms/testdata/TestConformance/TestMultipleKeys.replay b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestMultipleKeys.replay new file mode 100644 index 000000000..79f743f33 Binary files /dev/null and b/go-cloud/secrets/gcpkms/testdata/TestConformance/TestMultipleKeys.replay differ diff --git a/go-cloud/secrets/hashivault/example_test.go b/go-cloud/secrets/hashivault/example_test.go new file mode 100644 index 000000000..e197f13f1 --- /dev/null +++ b/go-cloud/secrets/hashivault/example_test.go @@ -0,0 +1,58 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 hashivault_test + +import ( + "context" + "log" + + "github.com/hashicorp/vault/api" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "github.com/DataDog/iceberg-go/go-cloud/secrets/hashivault" +) + +func ExampleOpenKeeper() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Get a client to use with the Vault API. + client, err := hashivault.Dial(ctx, &hashivault.Config{ + Token: "CLIENT_TOKEN", + APIConfig: api.Config{ + Address: "http://127.0.0.1:8200", + }, + }) + if err != nil { + log.Fatal(err) + } + + // Construct a *secrets.Keeper. + keeper := hashivault.OpenKeeper(client, "my-key", nil) + defer keeper.Close() +} + +func Example_openFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/secrets/hashivault" + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + keeper, err := secrets.OpenKeeper(ctx, "hashivault://mykey") + if err != nil { + log.Fatal(err) + } + defer keeper.Close() +} diff --git a/go-cloud/secrets/hashivault/go.mod b/go-cloud/secrets/hashivault/go.mod new file mode 100644 index 000000000..ad3c94e2f --- /dev/null +++ b/go-cloud/secrets/hashivault/go.mod @@ -0,0 +1,88 @@ +// Copyright 2018-2019 The Go Cloud Development Kit 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 +// +// https://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. + +module gocloud.dev/secrets/hashivault + +go 1.24 + +require ( + github.com/hashicorp/vault/api v1.20.0 + gocloud.dev v0.43.0 +) + +require ( + cloud.google.com/go/auth v0.16.3 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect + cloud.google.com/go/compute/metadata v0.7.0 // indirect + github.com/aws/aws-sdk-go v1.55.7 // indirect + github.com/aws/aws-sdk-go-v2 v1.36.5 // indirect + github.com/aws/aws-sdk-go-v2/config v1.29.17 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.70 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 // indirect + github.com/aws/smithy-go v1.22.4 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-jose/go-jose/v4 v4.1.1 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/go-replayers/grpcreplay v1.3.0 // indirect + github.com/google/go-replayers/httpreplay v1.2.0 // indirect + github.com/google/martian/v3 v3.3.3 // indirect + github.com/google/s2a-go v0.1.9 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/google/wire v0.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/gax-go/v2 v2.15.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.8 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.7 // indirect + github.com/hashicorp/hcl v1.0.1-vault-7 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect + go.opentelemetry.io/otel v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/otel/sdk v1.37.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect + go.opentelemetry.io/otel/trace v1.37.0 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/net v0.42.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/time v0.12.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + google.golang.org/api v0.242.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 // indirect + google.golang.org/grpc v1.73.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect +) diff --git a/go-cloud/secrets/hashivault/go.sum b/go-cloud/secrets/hashivault/go.sum new file mode 100644 index 000000000..a19555b80 --- /dev/null +++ b/go-cloud/secrets/hashivault/go.sum @@ -0,0 +1,713 @@ +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +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.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= +cloud.google.com/go v0.121.4 h1:cVvUiY0sX0xwyxPwdSU2KsF9knOVmtRyAMt8xou0iTs= +cloud.google.com/go v0.121.4/go.mod h1:XEBchUiHFJbz4lKBZwYBDHV/rSyfFktk737TLDU089s= +cloud.google.com/go/auth v0.16.3 h1:kabzoQ9/bobUmnseYnBO6qQG7q4a/CffFRlJSxv2wCc= +cloud.google.com/go/auth v0.16.3/go.mod h1:NucRGjaXfzP1ltpcQ7On/VTZ0H4kWB5Jy+Y9Dnm76fA= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/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/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU= +cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +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/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= +cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk= +cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8= +cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= +cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= +cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM= +cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U= +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= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.55.0 h1:NESjdAToN9u1tmhVqhXCaCwYBuvEhZLLv0gBr+2znf0= +cloud.google.com/go/storage v1.55.0/go.mod h1:ztSmTTwzsdXe5syLVS0YsbFxXuvEmEyZj7v7zChEmuY= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 h1:UQUsRi8WTzhZntp5313l+CHIAT95ojUI2lpP/ExlZa4= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo= +github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= +github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0= +github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2/config v1.29.17 h1:jSuiQ5jEe4SAMH6lLRMY9OVC+TqJLP5655pBGjmnjr0= +github.com/aws/aws-sdk-go-v2/config v1.29.17/go.mod h1:9P4wwACpbeXs9Pm9w1QTh6BwWwJjwYvJ1iCt5QbCXh8= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70 h1:ONnH5CM16RTXRkS8Z1qg7/s2eDOhHhaXVd72mmyv4/0= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70/go.mod h1:M+lWhhmomVGgtuPOhO85u4pEa3SmssPTdcYpP/5J/xc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 h1:KAXP9JSHO1vKGCr5f4O6WmlVKLFFXgWYAGoJosorxzU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32/go.mod h1:h4Sg6FQdexC1yYG9RDnOvLbW1a/P986++/Y/a+GyEM8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 h1:t0E6FzREdtCsiLIoLCWsYliNsRBgyGD/MCK571qk4MI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17/go.mod h1:ygpklyoaypuyDvOM5ujWGrYWpAK3h7ugnmKCU/76Ys4= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 h1:AIRJ3lfb2w/1/8wOOSqYb9fUKGwQbtysJ2H1MofRUPg= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5/go.mod h1:b7SiVprpU+iGazDUqvRSLf5XmCdn+JtT1on7uNL6Ipc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 h1:BpOxT3yhLwSJ77qIY3DoHAQjZsc4HEGfMCE4NGy3uFg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3/go.mod h1:vq/GQR1gOFLquZMSrxUK/cpvKCNVYibNyJ1m7JrU88E= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 h1:NFOJ/NXEGV4Rq//71Hs1jC/NvPs1ezajK+yQmkwnPV0= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0/go.mod h1:7ph2tGpfQvwzgistp2+zga9f+bCjlQJPkPUmMgDSD7w= +github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= +github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +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= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +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/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= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.1.1 h1:JYhSgy4mXXzAdF3nUx3ygx347LRXJRrpgyU3adRmkAI= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= +github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +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= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-replayers/grpcreplay v1.3.0 h1:1Keyy0m1sIpqstQmgz307zhiJ1pV4uIlFds5weTmxbo= +github.com/google/go-replayers/grpcreplay v1.3.0/go.mod h1:v6NgKtkijC0d3e3RW8il6Sy5sqRVUwoQa4mHOGEy8DI= +github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk= +github.com/google/go-replayers/httpreplay v1.2.0/go.mod h1:WahEFFZZ7a1P4VM1qEeHy+tME4bwyqPcwWbNlUI1Mcg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= +github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +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.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= +github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +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 v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +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.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= +github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw= +github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw= +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/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I= +github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/hashicorp/vault/api v1.20.0 h1:KQMHElgudOsr+IbJgmbjHnCTxEpKs9LnozA1D3nozU4= +github.com/hashicorp/vault/api v1.20.0/go.mod h1:GZ4pcjfzoOWpkJ3ijHNpEoAxKEsBJnVljyTe3jM2Sms= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0 h1:B+WbN9RPsvobe6q4vP6KgM8/9plR/HNjgGBrfcOlweA= +go.opentelemetry.io/contrib/detectors/gcp v1.37.0/go.mod h1:K5zQ3TT7p2ru9Qkzk0bKtCql0RGkPj9pRjpXgZJZ+rU= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0 h1:rbRJ8BBoVMsQShESYZ0FkvcITu8X8QNwJogcLUmDNNw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0/go.mod h1:ru6KHrNtNHxM4nD/vd6QrLVWgKhxPYgblq4VAtNawTQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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/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= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +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-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= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/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.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-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/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.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.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +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-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +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.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.242.0 h1:7Lnb1nfnpvbkCiZek6IXKdJ0MFuAZNAJKQfA1ws62xg= +google.golang.org/api v0.242.0/go.mod h1:cOVEm2TpdAGHL2z+UwyS+kmlGr3bVWQQ6sYEqkKje50= +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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +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= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 h1:Nt6z9UHqSlIdIGJdz6KhTIs2VRx/iOsA5iE8bmQNcxs= +google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79/go.mod h1:kTmlBHMPqR5uCZPBvwa2B18mvubkjyY3CRLI0c6fj0s= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79 h1:iOye66xuaAK0WnkPuhQPUFy8eJcmwUXqGGP3om6IxX8= +google.golang.org/genproto/googleapis/api v0.0.0-20250715232539-7130f93afb79/go.mod h1:HKJDgKsFUnv5VAGeQjz8kxcgDP0HoE0iZNp0OdZNlhE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 h1:1ZwqphdOdWYXsUHgMpU/101nCtf/kSp9hOrcvFsnl10= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +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.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/go-cloud/secrets/hashivault/localvault.sh b/go-cloud/secrets/hashivault/localvault.sh new file mode 100755 index 000000000..ffa26662e --- /dev/null +++ b/go-cloud/secrets/hashivault/localvault.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Copyright 2019 The Go Cloud Development Kit 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 +# +# https://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. + +# Starts a local Vault instance via Docker. + +# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail +set -euo pipefail + +echo "Starting Vault Server..." +docker rm -f dev-vault &> /dev/null || : +docker run --cap-add=IPC_LOCK -d --name=dev-vault -e 'VAULT_DEV_ROOT_TOKEN_ID=faketoken' -p 8200:8200 vault:1.6.0 &> /dev/null +echo "...done. Run \"docker rm -f dev-vault\" to clean up the container." +echo + diff --git a/go-cloud/secrets/hashivault/vault.go b/go-cloud/secrets/hashivault/vault.go new file mode 100644 index 000000000..696a72a13 --- /dev/null +++ b/go-cloud/secrets/hashivault/vault.go @@ -0,0 +1,246 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 +// limtations under the License. + +// Package hashivault provides a secrets implementation using the Transit +// Secrets Engine of Vault by Hashicorp. +// Use OpenKeeper to construct a *secrets.Keeper. +// +// # URLs +// +// For secrets.OpenKeeper, hashivault registers for the scheme "hashivault". +// The default URL opener will dial a Vault server using the environment variables +// "VAULT_SERVER_URL" (or "VAULT_ADDR") and "VAULT_SERVER_TOKEN" (or "VAULT_TOKEN"). +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// hashivault does not support any types for As. +package hashivault + +import ( + "context" + "encoding/base64" + "errors" + "fmt" + "net/url" + "os" + "path" + "sync" + + "github.com/hashicorp/vault/api" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/secrets" +) + +// Config is the authentication configurations of the Vault server. +type Config struct { + // Token is the access token the Vault client uses to talk to the server. + // See https://www.vaultproject.io/docs/concepts/tokens.html for more + // information. + Token string + // APIConfig is used to configure the creation of the client. + APIConfig api.Config +} + +// Dial gets a Vault client. +func Dial(ctx context.Context, cfg *Config) (*api.Client, error) { + if cfg == nil { + return nil, errors.New("no auth Config provided") + } + c, err := api.NewClient(&cfg.APIConfig) + if err != nil { + return nil, err + } + if cfg.Token != "" { + c.SetToken(cfg.Token) + } + return c, nil +} + +func init() { + secrets.DefaultURLMux().RegisterKeeper(Scheme, new(defaultDialer)) +} + +// getVaultURL ensures that we check both VAULT_SERVER_URL and VAULT_ADDR environment +// variables for the API address for vault. VAULT_SERVER_URL takes precedence over VAULT_ADDR. +func getVaultURL() (string, error) { + serverURL := os.Getenv("VAULT_SERVER_URL") + if serverURL != "" { + return serverURL, nil + } + + vaultAddr := os.Getenv("VAULT_ADDR") + if vaultAddr != "" { + return vaultAddr, nil + } + + return "", errors.New("neither VAULT_SERVER_URL nor VAULT_ADDR environment variables are set") +} + +// getVaultToken ensures that we check both VAULT_SERVER_TOKEN and VAULT_TOKEN environment +// variables for the API token for vault. VAULT_SERVER_TOKEN takes precedence over VAULT_TOKEN. +// If neither environment variables are found, then we return an empty string as token is not required. +func getVaultToken() string { + serverToken := os.Getenv("VAULT_SERVER_TOKEN") + if serverToken != "" { + return serverToken + } + + vaultToken := os.Getenv("VAULT_TOKEN") + if vaultToken != "" { + return vaultToken + } + + return "" +} + +// defaultDialer dials a default Vault server based on the environment variables +// VAULT_SERVER_URL / VAULT_ADDR and VAULT_SERVER_TOKEN / VAULT_TOKEN +type defaultDialer struct { + init sync.Once + opener *URLOpener + err error +} + +func (o *defaultDialer) OpenKeeperURL(ctx context.Context, u *url.URL) (*secrets.Keeper, error) { + o.init.Do(func() { + serverURL, err := getVaultURL() + if err != nil { + o.err = err + return + } + token := getVaultToken() + cfg := Config{Token: token, APIConfig: api.Config{Address: serverURL}} + client, err := Dial(ctx, &cfg) + if err != nil { + o.err = fmt.Errorf("failed to Dial default Vault server at %q: %v", serverURL, err) + return + } + o.opener = &URLOpener{Client: client} + }) + if o.err != nil { + return nil, fmt.Errorf("open keeper %v: %v", u, o.err) + } + return o.opener.OpenKeeperURL(ctx, u) +} + +// Scheme is the URL scheme hashivault registers its URLOpener under on secrets.DefaultMux. +const Scheme = "hashivault" + +// URLOpener opens Vault URLs like "hashivault://mykey". +// +// The URL Host + Path are used as the keyID. +// +// The following query parameters are supported: +// - engine: The secrets engine to use; defaults to "transit". +type URLOpener struct { + // Client must be non-nil. + Client *api.Client + + // Options specifies the options to pass to OpenKeeper. + Options KeeperOptions +} + +// OpenKeeperURL opens the Keeper URL. +func (o *URLOpener) OpenKeeperURL(ctx context.Context, u *url.URL) (*secrets.Keeper, error) { + for param, vals := range u.Query() { + switch param { + case "engine": + o.Options.Engine = vals[0] + default: + return nil, fmt.Errorf("open keeper %v: invalid query parameter %q", u, param) + } + } + return OpenKeeper(o.Client, path.Join(u.Host, u.Path), &o.Options), nil +} + +func newKeeper(client *api.Client, keyID string, opts *KeeperOptions) *keeper { + if opts == nil { + opts = &KeeperOptions{} + } + if opts.Engine == "" { + opts.Engine = "transit" + } + return &keeper{ + keyID: keyID, + client: client, + opts: *opts, + } +} + +// OpenKeeper returns a *secrets.Keeper that uses the Transit Secrets Engine of +// Vault by Hashicorp. +// See the package documentation for an example. +func OpenKeeper(client *api.Client, keyID string, opts *KeeperOptions) *secrets.Keeper { + return secrets.NewKeeper(newKeeper(client, keyID, opts)) +} + +type keeper struct { + // keyID is an encryption key ring name used by the Vault's transit API. + keyID string + client *api.Client + opts KeeperOptions +} + +// Decrypt decrypts the ciphertext into a plaintext. +func (k *keeper) Decrypt(ctx context.Context, ciphertext []byte) ([]byte, error) { + out, err := k.client.Logical().Write( + path.Join(k.opts.Engine+"/decrypt", k.keyID), + map[string]any{ + "ciphertext": string(ciphertext), + }, + ) + if err != nil { + return nil, err + } + return base64.StdEncoding.DecodeString(out.Data["plaintext"].(string)) +} + +// Encrypt encrypts a plaintext into a ciphertext. +func (k *keeper) Encrypt(ctx context.Context, plaintext []byte) ([]byte, error) { + secret, err := k.client.Logical().Write( + path.Join(k.opts.Engine+"/encrypt", k.keyID), + map[string]any{ + "plaintext": plaintext, + }, + ) + if err != nil { + return nil, err + } + return []byte(secret.Data["ciphertext"].(string)), nil +} + +// Close implements driver.Keeper.Close. +func (k *keeper) Close() error { return nil } + +// ErrorAs implements driver.Keeper.ErrorAs. +func (k *keeper) ErrorAs(err error, i any) bool { + return false +} + +// ErrorCode implements driver.ErrorCode. +func (k *keeper) ErrorCode(error) gcerrors.ErrorCode { + // TODO(shantuo): try to classify vault error codes + return gcerrors.Unknown +} + +// KeeperOptions controls Keeper behaviors. +// It is provided for future extensibility. +type KeeperOptions struct { + // Engine is the name of the secrets engine to use. + // It defaults to "transit". + Engine string +} diff --git a/go-cloud/secrets/hashivault/vault_test.go b/go-cloud/secrets/hashivault/vault_test.go new file mode 100644 index 000000000..3fd998c54 --- /dev/null +++ b/go-cloud/secrets/hashivault/vault_test.go @@ -0,0 +1,255 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 +// limtations under the License. + +package hashivault + +import ( + "context" + "errors" + "os" + "sync" + "testing" + "time" + + "github.com/hashicorp/vault/api" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/setup" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "github.com/DataDog/iceberg-go/go-cloud/secrets/driver" + "github.com/DataDog/iceberg-go/go-cloud/secrets/drivertest" +) + +// To run these tests against a real Vault server, first run ./localvault.sh. +// Then wait a few seconds for the server to be ready. + +const ( + keyID1 = "test-secrets" + keyID2 = "test-secrets2" + apiAddress = "http://127.0.0.1:8200" + testToken = "faketoken" +) + +// enableTransit checks and makes sure the Transit API is enabled only once. +var enableTransit sync.Once + +type harness struct { + client *api.Client + close func() +} + +func (h *harness) MakeDriver(ctx context.Context) (driver.Keeper, driver.Keeper, error) { + return newKeeper(h.client, keyID1, nil), newKeeper(h.client, keyID2, nil), nil +} + +func (h *harness) Close() {} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + if !setup.HasDockerTestEnvironment() { + t.Skip("Skipping Vault tests since the Vault server is not available") + } + c, err := Dial(ctx, &Config{ + Token: testToken, + APIConfig: api.Config{ + Address: apiAddress, + }, + }) + if err != nil { + return nil, err + } + c.SetClientTimeout(3 * time.Second) + // Enable the Transit Secrets Engine to use Vault as an Encryption as a Service. + enableTransit.Do(func() { + s, err := c.Logical().Read("sys/mounts") + if err != nil { + t.Fatal(err, "; run secrets/hashivault/localvault.sh to start a dev vault container") + } + if _, ok := s.Data["transit/"]; !ok { + if _, err := c.Logical().Write("sys/mounts/transit", map[string]any{"type": "transit"}); err != nil { + t.Fatal(err, "; run secrets/hashivault/localvault.sh to start a dev vault container") + } + } + }) + + return &harness{ + client: c, + }, nil +} + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct{} + +func (v verifyAs) Name() string { + return "verify As function" +} + +func (v verifyAs) ErrorCheck(k *secrets.Keeper, err error) error { + var s string + if k.ErrorAs(err, &s) { + return errors.New("Keeper.ErrorAs expected to fail") + } + return nil +} + +// Vault-specific tests. + +func TestNoSessionProvidedError(t *testing.T) { + if _, err := Dial(context.Background(), nil); err == nil { + t.Error("got nil, want no auth Config provided") + } +} + +func TestNoConnectionError(t *testing.T) { + ctx := context.Background() + + // Dial calls vault's NewClient method, which doesn't make the connection. Try + // doing encryption which should fail by no connection. + client, err := Dial(ctx, &Config{ + Token: "<Client (Root) Token>", + APIConfig: api.Config{ + Address: apiAddress, + }, + }) + if err != nil { + t.Fatal(err) + } + + keeper := OpenKeeper(client, "my-key", nil) + defer keeper.Close() + if _, err := keeper.Encrypt(ctx, []byte("test")); err == nil { + t.Error("got nil, want connection refused") + } +} + +func fakeConnectionStringInEnv() func() { + oldURLVal := os.Getenv("VAULT_SERVER_URL") + oldTokenVal := os.Getenv("VAULT_SERVER_TOKEN") + os.Setenv("VAULT_SERVER_URL", "http://myvaultserver") + os.Setenv("VAULT_SERVER_TOKEN", "faketoken") + return func() { + os.Setenv("VAULT_SERVER_URL", oldURLVal) + os.Setenv("VAULT_SERVER_TOKEN", oldTokenVal) + } +} + +func alternativeConnectionStringEnvVars() func() { + oldURLVal := os.Getenv("VAULT_ADDR") + oldTokenVal := os.Getenv("VAULT_TOKEN") + os.Setenv("VAULT_ADDR", "http://myalternativevaultserver") + os.Setenv("VAULT_TOKEN", "faketoken2") + return func() { + os.Setenv("VAULT_ADDR", oldURLVal) + os.Setenv("VAULT_TOKEN", oldTokenVal) + } +} + +func unsetConnectionStringEnvVars() func() { + oldURLVal := os.Getenv("VAULT_ADDR") + oldTokenVal := os.Getenv("VAULT_TOKEN") + oldServerURLVal := os.Getenv("VAULT_SERVER_URL") + oldServerTokenVal := os.Getenv("VAULT_SERVER_TOKEN") + os.Unsetenv("VAULT_ADDR") + os.Unsetenv("VAULT_TOKEN") + os.Unsetenv("VAULT_SERVER_URL") + os.Unsetenv("VAULT_SERVER_TOKEN") + return func() { + os.Setenv("VAULT_ADDR", oldURLVal) + os.Setenv("VAULT_SERVER_URL", oldServerURLVal) + os.Setenv("VAULT_TOKEN", oldTokenVal) + os.Setenv("VAULT_SERVER_TOKEN", oldServerTokenVal) + } +} + +func TestOpenKeeper(t *testing.T) { + cleanup := fakeConnectionStringInEnv() + defer cleanup() + + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"hashivault://mykey", false}, + // OK, setting engine. + {"hashivault://mykey?engine=foo", false}, + // Invalid parameter. + {"hashivault://mykey?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + keeper, err := secrets.OpenKeeper(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if err == nil { + if err = keeper.Close(); err != nil { + t.Errorf("%s: got error during close: %v", test.URL, err) + } + } + } +} + +func TestGetVaultConnectionDetails(t *testing.T) { + t.Run("Test Current Env Vars", func(t *testing.T) { + cleanup := fakeConnectionStringInEnv() + defer cleanup() + + serverUrl, err := getVaultURL() + if err != nil { + t.Errorf("got unexpected error: %v", err) + } + if serverUrl != "http://myvaultserver" { + t.Errorf("expected 'http://myvaultserver': got %q", serverUrl) + } + + vaultToken := getVaultToken() + if vaultToken != "faketoken" { + t.Errorf("export 'faketoken': got %q", vaultToken) + } + }) + + t.Run("Test Alternative Env Vars", func(t *testing.T) { + cleanup := alternativeConnectionStringEnvVars() + defer cleanup() + + serverUrl, err := getVaultURL() + if err != nil { + t.Errorf("got unexpected error: %v", err) + } + if serverUrl != "http://myalternativevaultserver" { + t.Errorf("export '': got %q", serverUrl) + } + + vaultToken := getVaultToken() + if vaultToken != "faketoken2" { + t.Errorf("export 'faketoken2': got %q", vaultToken) + } + }) + t.Run("Test Unset Env Vars Throws Error", func(t *testing.T) { + cleanup := unsetConnectionStringEnvVars() + defer cleanup() + + serverUrl, err := getVaultURL() + if err == nil { + t.Errorf("expected error but got a url: %s", serverUrl) + } + + vaultToken := getVaultToken() + if vaultToken != "" { + t.Errorf("export '': got %q", vaultToken) + } + }) +} diff --git a/go-cloud/secrets/localsecrets/example_test.go b/go-cloud/secrets/localsecrets/example_test.go new file mode 100644 index 000000000..1ec9941e7 --- /dev/null +++ b/go-cloud/secrets/localsecrets/example_test.go @@ -0,0 +1,58 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 localsecrets_test + +import ( + "context" + "log" + + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "github.com/DataDog/iceberg-go/go-cloud/secrets/localsecrets" +) + +func ExampleNewKeeper() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + secretKey, err := localsecrets.NewRandomKey() + if err != nil { + log.Fatal(err) + } + keeper := localsecrets.NewKeeper(secretKey) + defer keeper.Close() +} + +func Example_openFromURL() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // PRAGMA: On gocloud.dev, add a blank import: _ "gocloud.dev/secrets/localsecrets" + + // PRAGMA: On gocloud.dev, hide lines until the next blank line. + ctx := context.Background() + + // Using "base64key://", a new random key will be generated. + randomKeyKeeper, err := secrets.OpenKeeper(ctx, "base64key://") + if err != nil { + log.Fatal(err) + } + defer randomKeyKeeper.Close() + + // Otherwise, the URL hostname must be a base64-encoded key, of length 32 bytes when decoded. + // Note that base64.URLEncode should be used, to avoid URL-unsafe characters. + savedKeyKeeper, err := secrets.OpenKeeper(ctx, "base64key://smGbjm71Nxd1Ig5FS0wj9SlbzAIrnolCz9bQQ6uAhl4=") + if err != nil { + log.Fatal(err) + } + defer savedKeyKeeper.Close() +} diff --git a/go-cloud/secrets/localsecrets/localsecrets.go b/go-cloud/secrets/localsecrets/localsecrets.go new file mode 100644 index 000000000..d20d9bd10 --- /dev/null +++ b/go-cloud/secrets/localsecrets/localsecrets.go @@ -0,0 +1,177 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 localsecrets provides a secrets implementation using a locally +// provided symmetric key. +// Use NewKeeper to construct a *secrets.Keeper. +// +// # URLs +// +// For secrets.OpenKeeper, localsecrets registers for the scheme "base64key". +// To customize the URL opener, or for more details on the URL format, +// see URLOpener. +// See https://gocloud.dev/concepts/urls/ for background information. +// +// # As +// +// localsecrets does not support any types for As. +package localsecrets // import "gocloud.dev/secrets/localsecrets" + +import ( + "context" + "crypto/rand" + "encoding/base64" + "errors" + "fmt" + "io" + "net/url" + + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "golang.org/x/crypto/nacl/secretbox" +) + +func init() { + secrets.DefaultURLMux().RegisterKeeper(Scheme, &URLOpener{}) +} + +// Scheme is the URL scheme localsecrets registers its URLOpener under on +// secrets.DefaultMux. +// See the package documentation and/or URLOpener for details. +const ( + Scheme = "base64key" +) + +// URLOpener opens localsecrets URLs like "base64key://smGbjm71Nxd1Ig5FS0wj9SlbzAIrnolCz9bQQ6uAhl4=". +// +// The URL host must be base64 encoded, and must decode to exactly 32 bytes. +// Note that base64.URLEncoding should be used to avoid URL-unsafe character in the hostname. +// If the URL host is empty (e.g., "base64key://"), a new random key is generated. +// +// No query parameters are supported. +type URLOpener struct{} + +// OpenKeeperURL opens Keeper URLs. +func (o *URLOpener) OpenKeeperURL(ctx context.Context, u *url.URL) (*secrets.Keeper, error) { + for param := range u.Query() { + return nil, fmt.Errorf("open keeper %v: invalid query parameter %q", u, param) + } + var sk [32]byte + var err error + if u.Host == "" { + sk, err = NewRandomKey() + } else { + sk, err = Base64Key(u.Host) + } + if err != nil { + return nil, fmt.Errorf("open keeper %v: failed to get key: %v", u, err) + } + return NewKeeper(sk), nil +} + +// keeper holds a secret for use in symmetric encryption, +// and implements driver.Keeper. +type keeper struct { + secretKey [32]byte // secretbox key size +} + +// NewKeeper returns a *secrets.Keeper that uses the given symmetric +// key. See the package documentation for an example. +func NewKeeper(sk [32]byte) *secrets.Keeper { + return secrets.NewKeeper( + &keeper{secretKey: sk}, + ) +} + +// Base64KeyStd takes a secret key as a base64 string and converts it +// to a [32]byte, erroring if the decoded data is not 32 bytes. +// It uses base64.StdEncoding. +func Base64KeyStd(base64str string) ([32]byte, error) { + return base64Key(base64str, base64.StdEncoding) +} + +// Base64Key takes a secret key as a base64 string and converts it +// to a [32]byte, erroring if the decoded data is not 32 bytes. +// It uses base64.URLEncoding. +func Base64Key(base64str string) ([32]byte, error) { + return base64Key(base64str, base64.URLEncoding) +} + +func base64Key(base64str string, encoding *base64.Encoding) ([32]byte, error) { + var sk32 [32]byte + key, err := encoding.DecodeString(base64str) + if err != nil { + return sk32, err + } + keySize := len([]byte(key)) + if keySize != 32 { + return sk32, fmt.Errorf("Base64Key: secret key material is %v bytes, want 32 bytes", keySize) + } + copy(sk32[:], key) + return sk32, nil +} + +// NewRandomKey will generate random secret key material suitable to be +// used as the secret key argument to NewKeeper. +func NewRandomKey() ([32]byte, error) { + var sk32 [32]byte + // Read random numbers into the passed slice until it's full. + _, err := rand.Read(sk32[:]) + if err != nil { + return sk32, err + } + return sk32, nil +} + +const nonceSize = 24 + +// Encrypt encrypts a message using a per-message generated nonce and +// the secret held in the Keeper. +func (k *keeper) Encrypt(ctx context.Context, message []byte) ([]byte, error) { + var nonce [nonceSize]byte + if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil { + return nil, err + } + // secretbox.Seal appends the encrypted message to its first argument and returns + // the result; using a slice on top of the nonce array for this "out" arg allows reading + // the nonce out of the first nonceSize bytes when the message is decrypted. + return secretbox.Seal(nonce[:], message, &nonce, &k.secretKey), nil +} + +// Decrypt decrypts a message using a nonce that is read out of the first nonceSize bytes +// of the message and a secret held in the Keeper. +func (k *keeper) Decrypt(ctx context.Context, message []byte) ([]byte, error) { + if len(message) < nonceSize { + return nil, fmt.Errorf("localsecrets: invalid message length (%d, expected at least %d)", len(message), nonceSize) + } + var decryptNonce [nonceSize]byte + copy(decryptNonce[:], message[:nonceSize]) + + decrypted, ok := secretbox.Open(nil, message[nonceSize:], &decryptNonce, &k.secretKey) + if !ok { + return nil, errors.New("localsecrets: Decrypt failed") + } + return decrypted, nil +} + +// Close implements driver.Keeper.Close. +func (k *keeper) Close() error { return nil } + +// ErrorAs implements driver.Keeper.ErrorAs. +func (k *keeper) ErrorAs(err error, i any) bool { + return false +} + +// ErrorCode implements driver.ErrorCode. +func (k *keeper) ErrorCode(error) gcerrors.ErrorCode { return gcerrors.Unknown } diff --git a/go-cloud/secrets/localsecrets/localsecrets_test.go b/go-cloud/secrets/localsecrets/localsecrets_test.go new file mode 100644 index 000000000..45a0aaa9d --- /dev/null +++ b/go-cloud/secrets/localsecrets/localsecrets_test.go @@ -0,0 +1,153 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 localsecrets + +import ( + "context" + "errors" + "log" + "strings" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/secrets" + "github.com/DataDog/iceberg-go/go-cloud/secrets/driver" + "github.com/DataDog/iceberg-go/go-cloud/secrets/drivertest" +) + +type harness struct{} + +func (h *harness) MakeDriver(ctx context.Context) (driver.Keeper, driver.Keeper, error) { + secret1, err := NewRandomKey() + if err != nil { + log.Fatal(err) + } + secret2, err := NewRandomKey() + if err != nil { + log.Fatal(err) + } + return &keeper{secretKey: secret1}, &keeper{secretKey: secret2}, nil +} + +func (h *harness) Close() {} + +func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { + t.Helper() + + return &harness{}, nil +} + +func TestConformance(t *testing.T) { + drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) +} + +type verifyAs struct{} + +func (v verifyAs) Name() string { + return "verify As function" +} + +func (v verifyAs) ErrorCheck(k *secrets.Keeper, err error) error { + var s string + if k.ErrorAs(err, &s) { + return errors.New("Keeper.ErrorAs expected to fail") + } + return nil +} + +func TestSmallData(t *testing.T) { + key, err := NewRandomKey() + if err != nil { + t.Fatal(err) + } + keeper := NewKeeper(key) + defer keeper.Close() + + ctx := context.Background() + const plaintext = "hello world" + ciphertext, err := keeper.Encrypt(ctx, []byte(plaintext)) + if err != nil { + t.Fatal(err) + } + + tests := []struct { + Ciphertext []byte + Want string + WantErr bool + WantInvalidLengthErr bool // true if we want the error to be that the ciphertext length is invalid + }{ + {nil, "", true, true}, + {[]byte{}, "", true, true}, + {[]byte{0}, "", true, true}, + {ciphertext[:1], "", true, true}, + {ciphertext[:nonceSize-1], "", true, true}, + {ciphertext[:nonceSize], "", true, false}, // not invalid, but Decrypt will fail + {ciphertext, plaintext, false, false}, // works + } + + for _, test := range tests { + got, err := keeper.Decrypt(ctx, test.Ciphertext) + if (err != nil) != test.WantErr { + t.Errorf("got err %v from Decrypt, want error? %v", err, test.WantErr) + } + if err == nil { + if gotStr := string(got); gotStr != test.Want { + t.Errorf("got %s want %s", gotStr, test.Want) + } + } else { + if gotInvalid := strings.Contains(err.Error(), "invalid message length"); gotInvalid != test.WantInvalidLengthErr { + t.Errorf("got invalid message length error? %v want %v", gotInvalid, test.WantInvalidLengthErr) + } + } + // Encrypt should always work. + if _, err := keeper.Encrypt(ctx, test.Ciphertext); err != nil { + t.Errorf("got error %v from Encrypt, want nil", err) + } + } +} + +func TestOpenKeeper(t *testing.T) { + tests := []struct { + URL string + WantErr bool + }{ + // OK. + {"base64key://", false}, + // OK. + {"base64key://smGbjm71Nxd1Ig5FS0wj9SlbzAIrnolCz9bQQ6uAhl4=", false}, + // Valid base64, but < 32 bytes. + {"base64key://c2VjcmV0", true}, + // Valid base64, but > 32 bytes. + {"base64key://c2VjcmV0c2VjcmV0c2VjcmV0c2VjcmV0c2VjcmV0c3NlY3JldHNlY3JldHNlY3JldHNlY3JldHNlY3JldHM=", true}, + // Invalid base64 key. + {"base64key://not-valid-base64", true}, + // Valid base64 key (but invalid if using Std encoding instead of URL encoding). + {"base64Key://UKcmEoZW7nKl0uPHr8yV__KJm0ANhiFz8PzDN-gYWq8=", false}, + // Invalid parameter. + {"base64key://?param=value", true}, + } + + ctx := context.Background() + for _, test := range tests { + keeper, err := secrets.OpenKeeper(ctx, test.URL) + if (err != nil) != test.WantErr { + t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) + } + if err == nil { + if err = keeper.Close(); err != nil { + t.Errorf("%s: got error during close: %v", test.URL, err) + } + } + } +} diff --git a/go-cloud/secrets/secrets.go b/go-cloud/secrets/secrets.go new file mode 100644 index 000000000..7dcdf2485 --- /dev/null +++ b/go-cloud/secrets/secrets.go @@ -0,0 +1,224 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 secrets provides an easy and portable way to encrypt and decrypt +// messages. Subpackages contain driver implementations of +// secrets for supported services. +// +// See https://gocloud.dev/howto/secrets/ for a detailed how-to guide. +// +// # OpenTelemetry Integration +// +// OpenTelemetry supports tracing and metric collection for multiple languages and +// backend providers. See https://opentelemetry.io. +// +// This API collects OpenTelemetry traces and metrics for the following methods: +// - Encrypt +// - Decrypt +// +// All trace and metric names begin with the package import path. +// The traces add the method name. +// For example, "gocloud.dev/secrets/Encrypt". +// The metrics are "completed_calls", a count of completed method calls by driver, +// method and status (error code); and "latency", a distribution of method latency +// by driver and method. +// For example, "gocloud.dev/secrets/latency". +// +// To enable trace collection in your application, see the OpenTelemetry documentation at +// https://opentelemetry.io/docs/instrumentation/go/getting-started/. +package secrets // import "gocloud.dev/secrets" + +import ( + "context" + "net/url" + "sync" + + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/openurl" + gcdkotel "github.com/DataDog/iceberg-go/go-cloud/internal/otel" + "github.com/DataDog/iceberg-go/go-cloud/secrets/driver" +) + +// Keeper does encryption and decryption. To create a Keeper, use constructors +// found in driver subpackages. +type Keeper struct { + k driver.Keeper + tracer *gcdkotel.Tracer + + // mu protects the closed variable. + // Read locks are kept to allow holding a read lock for long-running calls, + // and thereby prevent closing until a call finishes. + mu sync.RWMutex + closed bool +} + +// NewKeeper is intended for use by drivers only. Do not use in application code. +var NewKeeper = newKeeper + +// newKeeper creates a Keeper. +func newKeeper(k driver.Keeper) *Keeper { + return &Keeper{ + k: k, + tracer: gcdkotel.NewTracer(pkgName, gcdkotel.ProviderName(k)), + } +} + +const pkgName = "gocloud.dev/secrets" + +var ( + + // OpenTelemetryViews are predefined views for OpenTelemetry metrics. + // The views include counts and latency distributions for API method calls. + // See the explanations at https://opentelemetry.io/docs/specs/otel/metrics/data-model/ for usage. + OpenTelemetryViews = gcdkotel.Views(pkgName) +) + +// Encrypt encrypts the plaintext and returns the cipher message. +func (k *Keeper) Encrypt(ctx context.Context, plaintext []byte) (ciphertext []byte, err error) { + ctx, span := k.tracer.Start(ctx, "Encrypt") + defer func() { k.tracer.End(ctx, span, err) }() + + k.mu.RLock() + defer k.mu.RUnlock() + if k.closed { + return nil, errClosed + } + + b, err := k.k.Encrypt(ctx, plaintext) + if err != nil { + return nil, wrapError(k, err) + } + return b, nil +} + +// Decrypt decrypts the ciphertext and returns the plaintext. +func (k *Keeper) Decrypt(ctx context.Context, ciphertext []byte) (plaintext []byte, err error) { + ctx, span := k.tracer.Start(ctx, "Decrypt") + defer func() { k.tracer.End(ctx, span, err) }() + + k.mu.RLock() + defer k.mu.RUnlock() + if k.closed { + return nil, errClosed + } + + b, err := k.k.Decrypt(ctx, ciphertext) + if err != nil { + return nil, wrapError(k, err) + } + return b, nil +} + +var errClosed = gcerr.Newf(gcerr.FailedPrecondition, nil, "secrets: Keeper has been closed") + +// Close releases any resources used for the Keeper. +func (k *Keeper) Close() error { + k.mu.Lock() + prev := k.closed + k.closed = true + k.mu.Unlock() + if prev { + return errClosed + } + return wrapError(k, k.k.Close()) +} + +// ErrorAs converts i to driver-specific types. See +// https://gocloud.dev/concepts/as/ for background information and the +// driver package documentation for the specific types supported for +// that driver. +// +// ErrorAs panics if i is nil or not a pointer. +// ErrorAs returns false if err == nil. +func (k *Keeper) ErrorAs(err error, i any) bool { + return gcerr.ErrorAs(err, i, k.k.ErrorAs) +} + +func wrapError(k *Keeper, err error) error { + if err == nil { + return nil + } + if gcerr.DoNotWrap(err) { + return err + } + return gcerr.New(k.k.ErrorCode(err), err, 2, "secrets") +} + +// KeeperURLOpener represents types that can open Keepers based on a URL. +// The opener must not modify the URL argument. OpenKeeperURL must be safe to +// call from multiple goroutines. +// +// This interface is generally implemented by types in driver packages. +type KeeperURLOpener interface { + OpenKeeperURL(ctx context.Context, u *url.URL) (*Keeper, error) +} + +// URLMux is a URL opener multiplexer. It matches the scheme of the URLs +// against a set of registered schemes and calls the opener that matches the +// URL's scheme. +// See https://gocloud.dev/concepts/urls/ for more information. +// +// The zero value is a multiplexer with no registered schemes. +type URLMux struct { + schemes openurl.SchemeMap +} + +// KeeperSchemes returns a sorted slice of the registered Keeper schemes. +func (mux *URLMux) KeeperSchemes() []string { return mux.schemes.Schemes() } + +// ValidKeeperScheme returns true iff scheme has been registered for Keepers. +func (mux *URLMux) ValidKeeperScheme(scheme string) bool { return mux.schemes.ValidScheme(scheme) } + +// RegisterKeeper registers the opener with the given scheme. If an opener +// already exists for the scheme, RegisterKeeper panics. +func (mux *URLMux) RegisterKeeper(scheme string, opener KeeperURLOpener) { + mux.schemes.Register("secrets", "Keeper", scheme, opener) +} + +// OpenKeeper calls OpenKeeperURL with the URL parsed from urlstr. +// OpenKeeper is safe to call from multiple goroutines. +func (mux *URLMux) OpenKeeper(ctx context.Context, urlstr string) (*Keeper, error) { + opener, u, err := mux.schemes.FromString("Keeper", urlstr) + if err != nil { + return nil, err + } + return opener.(KeeperURLOpener).OpenKeeperURL(ctx, u) +} + +// OpenKeeperURL dispatches the URL to the opener that is registered with the +// URL's scheme. OpenKeeperURL is safe to call from multiple goroutines. +func (mux *URLMux) OpenKeeperURL(ctx context.Context, u *url.URL) (*Keeper, error) { + opener, err := mux.schemes.FromURL("Keeper", u) + if err != nil { + return nil, err + } + return opener.(KeeperURLOpener).OpenKeeperURL(ctx, u) +} + +var defaultURLMux = new(URLMux) + +// DefaultURLMux returns the URLMux used by OpenKeeper. +// +// Driver packages can use this to register their KeeperURLOpener on the mux. +func DefaultURLMux() *URLMux { + return defaultURLMux +} + +// OpenKeeper opens the Keeper identified by the URL given. +// See the URLOpener documentation in driver subpackages for +// details on supported URL formats, and https://gocloud.dev/concepts/urls +// for more information. +func OpenKeeper(ctx context.Context, urlstr string) (*Keeper, error) { + return defaultURLMux.OpenKeeper(ctx, urlstr) +} diff --git a/go-cloud/secrets/secrets_test.go b/go-cloud/secrets/secrets_test.go new file mode 100644 index 000000000..2354d2726 --- /dev/null +++ b/go-cloud/secrets/secrets_test.go @@ -0,0 +1,241 @@ +// Copyright 2019-2025 The Go Cloud Development Kit 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 +// +// https://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 secrets + +import ( + "context" + "errors" + "net/url" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" + "github.com/DataDog/iceberg-go/go-cloud/internal/gcerr" + "github.com/DataDog/iceberg-go/go-cloud/internal/testing/oteltest" + "github.com/DataDog/iceberg-go/go-cloud/secrets/driver" +) + +var errFake = errors.New("fake") + +type erroringKeeper struct { + driver.Keeper +} + +func (k *erroringKeeper) Decrypt(ctx context.Context, b []byte) ([]byte, error) { + return nil, errFake +} + +func (k *erroringKeeper) Encrypt(ctx context.Context, b []byte) ([]byte, error) { + return nil, errFake +} + +func (k *erroringKeeper) Close() error { return errFake } +func (k *erroringKeeper) ErrorCode(error) gcerrors.ErrorCode { return gcerrors.Internal } + +func TestErrorsAreWrapped(t *testing.T) { + ctx := context.Background() + k := NewKeeper(&erroringKeeper{}) + + // verifyWrap ensures that err is wrapped exactly once. + verifyWrap := func(description string, err error) { + if err == nil { + t.Errorf("%s: got nil error, wanted non-nil", description) + } else if unwrapped, ok := err.(*gcerr.Error); !ok { + t.Errorf("%s: not wrapped: %v", description, err) + } else if du, ok := unwrapped.Unwrap().(*gcerr.Error); ok { + t.Errorf("%s: double wrapped: %v", description, du) + } + if s := err.Error(); !strings.HasPrefix(s, "secrets ") { + t.Errorf("%s: Error() for wrapped error doesn't start with secrets: prefix: %s", description, s) + } + } + + _, err := k.Decrypt(ctx, nil) + verifyWrap("Decrypt", err) + + _, err = k.Encrypt(ctx, nil) + verifyWrap("Encrypt", err) + + err = k.Close() + verifyWrap("Close", err) +} + +// TestKeeperIsClosed tests that Keeper functions return an error when the +// Keeper is closed. +func TestKeeperIsClosed(t *testing.T) { + ctx := context.Background() + k := NewKeeper(&erroringKeeper{}) + k.Close() + + if _, err := k.Decrypt(ctx, nil); err != errClosed { + t.Error(err) + } + if _, err := k.Encrypt(ctx, nil); err != errClosed { + t.Error(err) + } + if err := k.Close(); err != errClosed { + t.Error(err) + } +} + +func TestOpenTelemetry(t *testing.T) { + + ctx := context.Background() + + te := oteltest.NewTestExporter(t, OpenTelemetryViews) + + k := NewKeeper(&erroringKeeper{}) + defer k.Close() + _, _ = k.Encrypt(ctx, nil) + + _, _ = k.Decrypt(ctx, nil) + _, _ = k.Decrypt(ctx, nil) + + // Check collected spans. + spanStubs := te.GetSpans() + metrics := te.GetMetrics(ctx) + diff := oteltest.Diff(spanStubs.Snapshots(), metrics, pkgName, "gocloud.dev/secrets", []oteltest.Call{ + {Method: "Encrypt", Code: gcerrors.Internal}, + {Method: "Decrypt", Code: gcerrors.Internal}, + {Method: "Decrypt", Code: gcerrors.Internal}, + }) + if diff != "" { + t.Error(diff) + } + + if err := te.Shutdown(ctx); err != nil { + // Just log and continue - not failing the test on shutdown errors. + t.Logf("OpenTelemetry shutdown error (non-fatal): %v", err) + } + +} + +func TestURLMux(t *testing.T) { + ctx := context.Background() + + mux := new(URLMux) + fake := &fakeOpener{} + mux.RegisterKeeper("foo", fake) + mux.RegisterKeeper("err", fake) + + if diff := cmp.Diff(mux.KeeperSchemes(), []string{"err", "foo"}); diff != "" { + t.Errorf("Schemes: %s", diff) + } + if !mux.ValidKeeperScheme("foo") || !mux.ValidKeeperScheme("err") { + t.Errorf("ValidKeeperScheme didn't return true for valid scheme") + } + if mux.ValidKeeperScheme("foo2") || mux.ValidKeeperScheme("http") { + t.Errorf("ValidKeeperScheme didn't return false for invalid scheme") + } + + for _, tc := range []struct { + name string + url string + wantErr bool + }{ + { + name: "empty URL", + wantErr: true, + }, + { + name: "invalid URL", + url: ":foo", + wantErr: true, + }, + { + name: "invalid URL no scheme", + url: "foo", + wantErr: true, + }, + { + name: "unregistered scheme", + url: "bar://mykeeper", + wantErr: true, + }, + { + name: "func returns error", + url: "err://mykeeper", + wantErr: true, + }, + { + name: "no query options", + url: "foo://mykeeper", + }, + { + name: "empty query options", + url: "foo://mykeeper?", + }, + { + name: "query options", + url: "foo://mykeeper?aAa=bBb&cCc=dDd", + }, + { + name: "multiple query options", + url: "foo://mykeeper?x=a&x=b&x=c", + }, + { + name: "fancy keeper name", + url: "foo:///foo/bar/baz", + }, + { + name: "using api scheme prefix", + url: "secrets+foo://mykeeper", + }, + { + name: "using api+type scheme prefix", + url: "secrets+keeper+foo://mykeeper", + }, + } { + t.Run(tc.name, func(t *testing.T) { + keeper, gotErr := mux.OpenKeeper(ctx, tc.url) + if (gotErr != nil) != tc.wantErr { + t.Fatalf("got err %v, want error %v", gotErr, tc.wantErr) + } + if gotErr != nil { + return + } + defer keeper.Close() + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + // Repeat with OpenKeeperURL. + parsed, err := url.Parse(tc.url) + if err != nil { + t.Fatal(err) + } + keeper, gotErr = mux.OpenKeeperURL(ctx, parsed) + if gotErr != nil { + t.Fatalf("got err %v, want nil", gotErr) + } + defer keeper.Close() + if got := fake.u.String(); got != tc.url { + t.Errorf("got %q want %q", got, tc.url) + } + }) + } +} + +type fakeOpener struct { + u *url.URL // last url passed to OpenKeeperURL. +} + +func (o *fakeOpener) OpenKeeperURL(ctx context.Context, u *url.URL) (*Keeper, error) { + if u.Scheme == "err" { + return nil, errors.New("fail") + } + o.u = u + return NewKeeper(&erroringKeeper{}), nil +} diff --git a/go-cloud/server/driver/driver.go b/go-cloud/server/driver/driver.go new file mode 100644 index 000000000..a4417c8e4 --- /dev/null +++ b/go-cloud/server/driver/driver.go @@ -0,0 +1,51 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 driver defines an interface for custom HTTP listeners. +// Application code should use package server. +package driver // import "gocloud.dev/server/driver" + +import ( + "context" + "net/http" +) + +// Server dispatches requests to an http.Handler. +type Server interface { + // ListenAndServe listens on the TCP network address addr and then + // calls Serve with handler to handle requests on incoming connections. + // The addr argument will be a non-empty string specifying "host:port". + // The http.Handler will always be non-nil. + // Drivers must block until serving is done (or + // return an error if serving can't occur for some reason), serve + // requests to the given http.Handler, and be interruptable by Shutdown. + // Drivers should use the given address if they serve using TCP directly. + ListenAndServe(addr string, h http.Handler) error + + // Shutdown gracefully shuts down the server without interrupting + // any active connections. If the provided context expires before + // the shutdown is complete, Shutdown returns the context's error, + // otherwise it returns any error returned from closing the Server's + // underlying Listener(s). + Shutdown(ctx context.Context) error +} + +// TLSServer is an optional interface for Server drivers, that adds support +// for serving TLS. +type TLSServer interface { + // ListenAndServeTLS is similar to Server.ListenAndServe, but should + // serve using TLS. + // See http://go/godoc/net/http/#Server.ListenAndServeTLS. + ListenAndServeTLS(addr, certFile, keyFile string, h http.Handler) error +} diff --git a/go-cloud/server/example_test.go b/go-cloud/server/example_test.go new file mode 100644 index 000000000..befe74efe --- /dev/null +++ b/go-cloud/server/example_test.go @@ -0,0 +1,166 @@ +// Copyright 2019 The Go Cloud Development Kit 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 +// +// https://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 server_test + +import ( + "context" + "errors" + "fmt" + "log" + "net/http" + "os" + "os/signal" + "sync" + "time" + + "github.com/DataDog/iceberg-go/go-cloud/server" + + "github.com/DataDog/iceberg-go/go-cloud/server/health" + "github.com/DataDog/iceberg-go/go-cloud/server/requestlog" +) + +func ExampleServer() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // Use the constructor function to create the server. + srv := server.New(http.DefaultServeMux, nil) + + // Register a route. + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "Hello, World!") + }) + + // Start the server. If ListenAndServe returns an error, print it and exit. + if err := srv.ListenAndServe(":8080"); err != nil { + log.Fatalf("%v", err) + } +} + +func ExampleServer_withRequestLogger() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // Create a logger, and assign it to the RequestLogger field of a + // server.Options struct. + srvOptions := &server.Options{ + RequestLogger: requestlog.NewNCSALogger(os.Stdout, func(error) {}), + } + + // Pass the options to the Server constructor. + srv := server.New(http.DefaultServeMux, srvOptions) + + // Register a route. + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "Hello, World!") + }) + + // Start the server. You will see requests logged to STDOUT. + if err := srv.ListenAndServe(":8080"); err != nil { + log.Fatalf("%v", err) + } +} + +// customHealthCheck is an example health check. It implements the +// health.Checker interface and reports the server is healthy when the healthy +// field is set to true. +type customHealthCheck struct { + mu sync.RWMutex + healthy bool +} + +// customHealthCheck implements the health.Checker interface because it has a +// CheckHealth method. Because each application may have a different definition +// of what it means to be "healthy", you will need to define a CheckHealth method +// specific to your application. +func (h *customHealthCheck) CheckHealth() error { + h.mu.RLock() + defer h.mu.RUnlock() + if !h.healthy { + return errors.New("not ready yet!") + } + return nil +} + +func ExampleServer_withHealthChecks() { + // PRAGMA: This example is used on gocloud.dev; PRAGMA comments adjust how it is shown and can be ignored. + + // Create a health.Checker from the type we defined for our application. + // In this example, healthCheck will report the server is unhealthy for 10 seconds + // after startup, and as healthy henceforth. Check the /healthz/readiness + // HTTP path to see readiness. + healthCheck := new(customHealthCheck) + time.AfterFunc(10*time.Second, func() { + healthCheck.mu.Lock() + defer healthCheck.mu.Unlock() + healthCheck.healthy = true + }) + + // The server.Options struct takes a slice of health checks, because you + // may need to check several things. + srvOptions := &server.Options{ + HealthChecks: []health.Checker{healthCheck}, + } + + // Pass the options to the Server constructor. + srv := server.New(http.DefaultServeMux, srvOptions) + + // Register a route. + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "Hello, World!") + }) + + // Start the server. You will see requests logged to STDOUT. + if err := srv.ListenAndServe(":8080"); err != nil { + log.Fatalf("%v", err) + } +} + +func ExampleServer_Shutdown() { + // OPTIONAL: Specify a driver in the options for the constructor. + // NewDefaultDriver will be used by default if it is not explicitly set, and + // uses http.Server with read, write, and idle timeouts set. When Shutdown + // is called on the server, it is called on the driver. + srvOptions := &server.Options{ + Driver: server.NewDefaultDriver(), + } + + // Pass the options to the Server constructor. + srv := server.New(http.DefaultServeMux, srvOptions) + + // If your application will be behind a load balancer that handles graceful + // shutdown of requests, you may not need to call Shutdown on the server + // directly. If you need to ensure graceful shutdown directly, it is important + // to have a separate goroutine, because ListenAndServe blocks indefinitely. + go func() { + interrupt := make(chan os.Signal, 1) + signal.Notify(interrupt, os.Interrupt) + // Receive off the chanel in a loop, because the interrupt could be sent + // before ListenAndServe starts. + for { + <-interrupt + srv.Shutdown(context.Background()) + } + }() + + // Register a route. + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "Hello, World!") + }) + + // Start the server. You will see requests logged to STDOUT. + // In the absence of an error, ListenAndServe blocks forever. + if err := srv.ListenAndServe(":8080"); err != nil { + log.Fatalf("%v", err) + } +} diff --git a/go-cloud/server/health/health.go b/go-cloud/server/health/health.go new file mode 100644 index 000000000..35476c21b --- /dev/null +++ b/go-cloud/server/health/health.go @@ -0,0 +1,96 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 health provides health check handlers. +package health // import "gocloud.dev/server/health" + +import ( + "io" + "net/http" +) + +// Handler is an HTTP handler that reports on the success of an +// aggregate of Checkers. The zero value is always healthy. +type Handler struct { + checkers []Checker +} + +// Add adds a new check to the handler. +func (h *Handler) Add(c Checker) { + h.checkers = append(h.checkers, c) +} + +// ServeHTTP returns 200 if it is healthy, 500 otherwise. +func (h *Handler) ServeHTTP(w http.ResponseWriter, _ *http.Request) { + for _, c := range h.checkers { + if err := c.CheckHealth(); err != nil { + writeUnhealthy(w) + return + } + } + writeHealthy(w) +} + +func writeHeaders(statusLen string, w http.ResponseWriter) { + w.Header().Set("Content-Length", statusLen) + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + w.Header().Set("X-Content-Type-Options", "nosniff") +} + +func writeUnhealthy(w http.ResponseWriter) { + const ( + status = "unhealthy" + statusLen = "9" + ) + + writeHeaders(statusLen, w) + w.WriteHeader(http.StatusInternalServerError) + io.WriteString(w, status) +} + +// HandleLive is an http.HandlerFunc that handles liveness checks by +// immediately responding with an HTTP 200 status. +func HandleLive(w http.ResponseWriter, _ *http.Request) { + writeHealthy(w) +} + +func writeHealthy(w http.ResponseWriter) { + const ( + status = "ok" + statusLen = "2" + ) + + writeHeaders(statusLen, w) + w.WriteHeader(http.StatusOK) + io.WriteString(w, status) +} + +// Checker wraps the CheckHealth method. +// +// CheckHealth returns nil if the resource is healthy, or a non-nil +// error if the resource is not healthy. CheckHealth must be safe to +// call from multiple goroutines. +type Checker interface { + CheckHealth() error +} + +// CheckerFunc is an adapter type to allow the use of ordinary functions as +// health checks. If f is a function with the appropriate signature, +// CheckerFunc(f) is a Checker that calls f. +type CheckerFunc func() error + +// CheckHealth calls f(). +func (f CheckerFunc) CheckHealth() error { + return f() +} diff --git a/go-cloud/server/health/health_test.go b/go-cloud/server/health/health_test.go new file mode 100644 index 000000000..40385cab5 --- /dev/null +++ b/go-cloud/server/health/health_test.go @@ -0,0 +1,101 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 health + +import ( + "errors" + "net/http" + "net/http/httptest" + "sync" + "testing" +) + +func TestNewHandler(t *testing.T) { + s := httptest.NewServer(new(Handler)) + defer s.Close() + code, err := check(s) + if err != nil { + t.Fatalf("GET %s: %v", s.URL, err) + } + if code != http.StatusOK { + t.Errorf("got HTTP status %d; want %d", code, http.StatusOK) + } +} + +func TestChecker(t *testing.T) { + c1 := &checker{err: errors.New("checker 1 down")} + c2 := &checker{err: errors.New("checker 2 down")} + h := new(Handler) + h.Add(c1) + h.Add(c2) + s := httptest.NewServer(h) + defer s.Close() + + t.Run("AllUnhealthy", func(t *testing.T) { + code, err := check(s) + if err != nil { + t.Fatalf("GET %s: %v", s.URL, err) + } + if code != http.StatusInternalServerError { + t.Errorf("got HTTP status %d; want %d", code, http.StatusInternalServerError) + } + }) + c1.set(nil) + t.Run("PartialHealthy", func(t *testing.T) { + code, err := check(s) + if err != nil { + t.Fatalf("GET %s: %v", s.URL, err) + } + if code != http.StatusInternalServerError { + t.Errorf("got HTTP status %d; want %d", code, http.StatusInternalServerError) + } + }) + c2.set(nil) + t.Run("AllHealthy", func(t *testing.T) { + code, err := check(s) + if err != nil { + t.Fatalf("GET %s: %v", s.URL, err) + } + if code != http.StatusOK { + t.Errorf("got HTTP status %d; want %d", code, http.StatusOK) + } + }) +} + +func check(s *httptest.Server) (code int, err error) { + resp, err := http.Get(s.URL) + if err != nil { + return 0, err + } + resp.Body.Close() + return resp.StatusCode, nil +} + +type checker struct { + mu sync.Mutex + err error +} + +func (c *checker) CheckHealth() error { + defer c.mu.Unlock() + c.mu.Lock() + return c.err +} + +func (c *checker) set(e error) { + defer c.mu.Unlock() + c.mu.Lock() + c.err = e +} diff --git a/go-cloud/server/health/sqlhealth/sqlhealth.go b/go-cloud/server/health/sqlhealth/sqlhealth.go new file mode 100644 index 000000000..379dd7743 --- /dev/null +++ b/go-cloud/server/health/sqlhealth/sqlhealth.go @@ -0,0 +1,100 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 sqlhealth provides a health check for a SQL database connection. +package sqlhealth // import "gocloud.dev/server/health/sqlhealth" + +import ( + "context" + "database/sql" + "errors" + "time" +) + +// Checker checks the health of a SQL database. +type Checker struct { + cancel context.CancelFunc + + stopped <-chan struct{} + healthy bool +} + +// New starts a new asynchronous ping of the SQL database. Pings will be sent +// until one succeeds or Stop is called, whichever comes first. +func New(db *sql.DB) *Checker { + // We create a context here because we are detaching. + ctx, cancel := context.WithCancel(context.Background()) + stopped := make(chan struct{}) + c := &Checker{ + cancel: cancel, + stopped: stopped, + } + go func() { + var timer *time.Timer + defer func() { + if timer != nil { + timer.Stop() + } + close(stopped) + }() + + wait := 250 * time.Millisecond + const maxWait = 30 * time.Second + for { + if err := db.PingContext(ctx); err == nil { + c.healthy = true + return + } + if timer == nil { + timer = time.NewTimer(wait) + } else { + // Timer already fired, so resetting does not race. + timer.Reset(wait) + } + select { + case <-timer.C: + if wait < maxWait { + // Back off next ping. + wait *= 2 + if wait > maxWait { + wait = maxWait + } + } + case <-ctx.Done(): + return + } + } + }() + return c +} + +// CheckHealth returns nil iff the ping started by New has returned +// success. +func (c *Checker) CheckHealth() error { + select { + case <-c.stopped: + if !c.healthy { + return errors.New("ping stopped before becoming healthy") + } + return nil + default: + return errors.New("still pinging database") + } +} + +// Stop stops any ongoing ping of the database. +func (c *Checker) Stop() { + c.cancel() + <-c.stopped +} diff --git a/go-cloud/server/health/sqlhealth/sqlhealth_test.go b/go-cloud/server/health/sqlhealth/sqlhealth_test.go new file mode 100644 index 000000000..7b5a1decc --- /dev/null +++ b/go-cloud/server/health/sqlhealth/sqlhealth_test.go @@ -0,0 +1,93 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 sqlhealth + +import ( + "context" + "database/sql" + "database/sql/driver" + "errors" + "sync" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/server/health" +) + +var _ = health.Checker((*Checker)(nil)) + +func TestCheck(t *testing.T) { + connector := new(stubConnector) + db := sql.OpenDB(connector) + defer db.Close() + + check := New(db) + defer check.Stop() + if err := check.CheckHealth(); err == nil { + t.Error("checker starts healthy") + } + connector.setHealthy(true) + + // Should eventually become healthy. Otherwise, stopped by test timeout. + for { + if err := check.CheckHealth(); err == nil { + break + } + } +} + +type stubConnector struct { + mu sync.RWMutex + healthy bool +} + +func (c *stubConnector) setHealthy(h bool) { + c.mu.Lock() + c.healthy = h + c.mu.Unlock() +} + +func (c *stubConnector) Connect(ctx context.Context) (driver.Conn, error) { + return &stubConn{c}, nil +} + +func (c *stubConnector) Driver() driver.Driver { + return nil +} + +type stubConn struct { + c *stubConnector +} + +func (conn *stubConn) Prepare(query string) (driver.Stmt, error) { + panic("not implemented") +} + +func (conn *stubConn) Close() error { + return nil +} + +func (conn *stubConn) Begin() (driver.Tx, error) { + panic("not implemented") +} + +func (conn *stubConn) Ping(ctx context.Context) error { + conn.c.mu.RLock() + healthy := conn.c.healthy + conn.c.mu.RUnlock() + if !healthy { + return errors.New("unhealthy") + } + return nil +} diff --git a/go-cloud/server/requestlog/ncsa.go b/go-cloud/server/requestlog/ncsa.go new file mode 100644 index 000000000..2bb0e52e4 --- /dev/null +++ b/go-cloud/server/requestlog/ncsa.go @@ -0,0 +1,85 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 requestlog + +import ( + "io" + "strconv" + "sync" +) + +// An NCSALogger writes log entries to an io.Writer in the +// Combined Log Format. +// +// Details at http://httpd.apache.org/docs/current/logs.html#combined +type NCSALogger struct { + onErr func(error) + + mu sync.Mutex + w io.Writer + buf []byte +} + +// NewNCSALogger returns a new logger that writes to w. +// A nil onErr is treated the same as func(error) {}. +func NewNCSALogger(w io.Writer, onErr func(error)) *NCSALogger { + return &NCSALogger{ + w: w, + onErr: onErr, + } +} + +// Log writes an entry line to its writer. Multiple concurrent calls +// will produce sequential writes to its writer. +func (l *NCSALogger) Log(ent *Entry) { + if err := l.log(ent); err != nil && l.onErr != nil { + l.onErr(err) + } +} + +func (l *NCSALogger) log(ent *Entry) error { + defer l.mu.Unlock() + l.mu.Lock() + l.buf = formatEntry(l.buf[:0], ent) + _, err := l.w.Write(l.buf) + return err +} + +func formatEntry(b []byte, ent *Entry) []byte { + const ncsaTime = "02/Jan/2006:15:04:05 -0700" + if ent.RemoteIP == "" { + b = append(b, '-') + } else { + b = append(b, ent.RemoteIP...) + } + b = append(b, " - - ["...) + b = ent.ReceivedTime.AppendFormat(b, ncsaTime) + b = append(b, "] \""...) + b = append(b, ent.RequestMethod...) + b = append(b, ' ') + b = append(b, ent.RequestURL...) + b = append(b, ' ') + b = append(b, ent.Proto...) + b = append(b, "\" "...) + b = strconv.AppendInt(b, int64(ent.Status), 10) + b = append(b, ' ') + b = strconv.AppendInt(b, int64(ent.ResponseBodySize), 10) + b = append(b, ' ') + b = strconv.AppendQuote(b, ent.Referer) + b = append(b, ' ') + b = strconv.AppendQuote(b, ent.UserAgent) + b = append(b, '\n') + return b +} diff --git a/go-cloud/server/requestlog/ncsa_test.go b/go-cloud/server/requestlog/ncsa_test.go new file mode 100644 index 000000000..3783f7650 --- /dev/null +++ b/go-cloud/server/requestlog/ncsa_test.go @@ -0,0 +1,112 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 requestlog + +import ( + "bytes" + "testing" + "time" +) + +var _ Logger = (*NCSALogger)(nil) + +func TestNCSALog(t *testing.T) { + const ( + startTime = 1507914000 + startTimeNanos = 512 + + latencySec = 5 + latencyNanos = 123456789 + + endTime = startTime + latencySec + endTimeNanos = startTimeNanos + latencyNanos + ) + tests := []struct { + name string + ent Entry + want string + }{ + { + name: "AllFields", + ent: Entry{ + ReceivedTime: time.Unix(startTime, startTimeNanos).UTC(), + RequestMethod: "POST", + RequestURL: "/foo/bar", + RequestHeaderSize: 456, + RequestBodySize: 123000, + UserAgent: "Chrome proxied through Firefox and Edge", + Referer: "http://www.example.com/", + Proto: "HTTP/1.1", + RemoteIP: "12.34.56.78", + ServerIP: "127.0.0.1", + Status: 404, + ResponseHeaderSize: 555, + ResponseBodySize: 789000, + Latency: latencySec*time.Second + latencyNanos*time.Nanosecond, + }, + want: `12.34.56.78 - - [13/Oct/2017:17:00:00 +0000] "POST /foo/bar HTTP/1.1" 404 789000 "http://www.example.com/" "Chrome proxied through Firefox and Edge"` + "\n", + }, + { + name: "OnlyRequiredFields", + ent: Entry{ + ReceivedTime: time.Unix(startTime, startTimeNanos).UTC(), + RequestMethod: "POST", + RequestURL: "/foo/bar", + Proto: "HTTP/1.1", + Status: 404, + }, + want: `- - - [13/Oct/2017:17:00:00 +0000] "POST /foo/bar HTTP/1.1" 404 0 "" ""` + "\n", + }, + { + name: "OnlyRequiredFieldsAndUserAgent", + ent: Entry{ + ReceivedTime: time.Unix(startTime, startTimeNanos).UTC(), + RequestMethod: "POST", + RequestURL: "/foo/bar", + Proto: "HTTP/1.1", + Status: 404, + UserAgent: "Chrome proxied through Firefox and Edge", + }, + want: `- - - [13/Oct/2017:17:00:00 +0000] "POST /foo/bar HTTP/1.1" 404 0 "" "Chrome proxied through Firefox and Edge"` + "\n", + }, + { + name: "DoubleQuotesInUserAgent", + ent: Entry{ + ReceivedTime: time.Unix(startTime, startTimeNanos).UTC(), + RequestMethod: "POST", + RequestURL: "/foo/bar", + Proto: "HTTP/1.1", + Status: 404, + UserAgent: "Chrome \"proxied\" through Firefox and Edge", + }, + want: `- - - [13/Oct/2017:17:00:00 +0000] "POST /foo/bar HTTP/1.1" 404 0 "" "Chrome \"proxied\" through Firefox and Edge"` + "\n", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + buf := new(bytes.Buffer) + var logErr error + l := NewNCSALogger(buf, func(e error) { logErr = e }) + l.Log(&test.ent) + if logErr != nil { + t.Error("Logger called error callback:", logErr) + } + got := buf.String() + if got != test.want { + t.Errorf("Log(...) wrote %q; want %q", got, test.want) + } + }) + } +} diff --git a/go-cloud/server/requestlog/requestlog.go b/go-cloud/server/requestlog/requestlog.go new file mode 100644 index 000000000..0d9e7a23a --- /dev/null +++ b/go-cloud/server/requestlog/requestlog.go @@ -0,0 +1,240 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 requestlog provides an http.Handler that logs information +// about requests. +package requestlog // import "gocloud.dev/server/requestlog" + +import ( + "bufio" + "errors" + "io" + "net" + "net/http" + "strconv" + "time" + + "go.opentelemetry.io/otel/trace" +) + +// Logger wraps the Log method. Log must be safe to call from multiple +// goroutines. Log must not hold onto an Entry after it returns. +type Logger interface { + Log(*Entry) +} + +// A Handler emits request information to a Logger. +type Handler struct { + log Logger + h http.Handler +} + +// NewHandler returns a handler that emits information to log and calls +// h.ServeHTTP. +func NewHandler(log Logger, h http.Handler) *Handler { + return &Handler{ + log: log, + h: h, + } +} + +// ServeHTTP calls its underlying handler's ServeHTTP method, then calls +// Log after the handler returns. +func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + start := time.Now() + span := trace.SpanFromContext(r.Context()) + sc := span.SpanContext() + ent := &Entry{ + Request: cloneRequestWithoutBody(r), + ReceivedTime: start, + RequestMethod: r.Method, + RequestURL: r.URL.String(), + RequestHeaderSize: headerSize(r.Header), + UserAgent: r.UserAgent(), + Referer: r.Referer(), + Proto: r.Proto, + RemoteIP: ipFromHostPort(r.RemoteAddr), + TraceID: sc.TraceID(), + SpanID: sc.SpanID(), + } + if addr, ok := r.Context().Value(http.LocalAddrContextKey).(net.Addr); ok { + ent.ServerIP = ipFromHostPort(addr.String()) + } + r2 := new(http.Request) + *r2 = *r + rcc := &readCounterCloser{r: r.Body} + r2.Body = rcc + w2 := &responseStats{w: w} + + h.h.ServeHTTP(w2, r2) + + ent.Latency = time.Since(start) + // The handler may or may not have read the entire body. If the request + // includes a Content-Length header, use that for a more accurate + // RequestBodySize. + ent.RequestBodySize = rcc.n + if contentLengthStr := r.Header.Get("Content-Length"); contentLengthStr != "" { + ent.RequestBodySize, _ = strconv.ParseInt(contentLengthStr, 10, 64) + } + ent.Status = w2.code + if ent.Status == 0 { + ent.Status = http.StatusOK + } + ent.ResponseHeaderSize, ent.ResponseBodySize = w2.size() + h.log.Log(ent) +} + +func cloneRequestWithoutBody(r *http.Request) *http.Request { + r = r.Clone(r.Context()) + r.Body = nil + return r +} + +// Entry records information about a completed HTTP request. +type Entry struct { + // Request is the http request that has been completed. + // + // This request's Body is always nil, regardless of the actual request body. + Request *http.Request + + ReceivedTime time.Time + RequestBodySize int64 + + Status int + ResponseHeaderSize int64 + ResponseBodySize int64 + Latency time.Duration + TraceID trace.TraceID + SpanID trace.SpanID + + // Deprecated. This value is available by evaluating Request.Referer(). + Referer string + // Deprecated. This value is available directing in Request.Proto. + Proto string + // Deprecated. This value is available directly in Request.Method. + RequestMethod string + // Deprecated. This value is available directly in Request.URL. + RequestURL string + // Deprecated. This value is available by evaluating Request.Header. + RequestHeaderSize int64 + // Deprecated. This value is available by evaluating Request.Header. + UserAgent string + // Deprecated. This value is available by evaluating Request.RemoteAddr.. + RemoteIP string + // Deprecated. This value is available by evaluating reading the + // http.LocalAddrContextKey value from the context returned by Request.Context(). + ServerIP string +} + +func ipFromHostPort(hp string) string { + h, _, err := net.SplitHostPort(hp) + if err != nil { + return "" + } + if len(h) > 0 && h[0] == '[' { + return h[1 : len(h)-1] + } + return h +} + +type readCounterCloser struct { + r io.ReadCloser + n int64 + err error +} + +func (rcc *readCounterCloser) Read(p []byte) (n int, err error) { + if rcc.err != nil { + return 0, rcc.err + } + n, rcc.err = rcc.r.Read(p) + rcc.n += int64(n) + return n, rcc.err +} + +func (rcc *readCounterCloser) Close() error { + rcc.err = errors.New("read from closed reader") + return rcc.r.Close() +} + +type writeCounter int64 + +func (wc *writeCounter) Write(p []byte) (n int, err error) { + *wc += writeCounter(len(p)) + return len(p), nil +} + +func headerSize(h http.Header) int64 { + var wc writeCounter + _ = h.Write(&wc) + return int64(wc) + 2 // for CRLF +} + +type responseStats struct { + w http.ResponseWriter + hsize int64 + wc writeCounter + code int + hijacked bool +} + +func (r *responseStats) Header() http.Header { + return r.w.Header() +} + +func (r *responseStats) WriteHeader(statusCode int) { + if r.code != 0 { + return + } + r.hsize = headerSize(r.w.Header()) + r.w.WriteHeader(statusCode) + r.code = statusCode +} + +func (r *responseStats) Write(p []byte) (n int, err error) { + if r.code == 0 { + r.WriteHeader(http.StatusOK) + } + n, err = r.w.Write(p) + _, _ = r.wc.Write(p[:n]) + return +} + +func (r *responseStats) size() (hdr, body int64) { + if r.code == 0 { + return headerSize(r.w.Header()), 0 + } + // Use the header size from the time WriteHeader was called. + // The Header map can be mutated after the call to add HTTP Trailers, + // which we don't want to count. + return r.hsize, int64(r.wc) +} + +func (r *responseStats) Hijack() (_ net.Conn, _ *bufio.ReadWriter, err error) { + defer func() { + if err == nil { + r.hijacked = true + } + }() + if hj, ok := r.w.(http.Hijacker); ok { + return hj.Hijack() + } + return nil, nil, errors.New("underlying ResponseWriter does not support hijacking") +} + +func (r *responseStats) Flush() { + if fl, ok := r.w.(http.Flusher); ok { + fl.Flush() + } +} diff --git a/go-cloud/server/requestlog/requestlog_test.go b/go-cloud/server/requestlog/requestlog_test.go new file mode 100644 index 000000000..e86a03c9d --- /dev/null +++ b/go-cloud/server/requestlog/requestlog_test.go @@ -0,0 +1,143 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 requestlog + +import ( + "context" + "fmt" + "go.opentelemetry.io/otel" + "io" + "net" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "go.opentelemetry.io/otel/trace" +) + +func TestHandler(t *testing.T) { + const requestMsg = "Hello, World!" + const responseMsg = "I see you." + const userAgent = "Request Log Test UA" + const referer = "http://www.example.com/" + r, err := http.NewRequest("POST", "http://localhost/foo", strings.NewReader(requestMsg)) + if err != nil { + t.Fatal("NewRequest:", err) + } + r.Header.Set("User-Agent", userAgent) + r.Header.Set("Referer", referer) + requestHdrSize := len(fmt.Sprintf("User-Agent: %s\r\nReferer: %s\r\nContent-Length: %v\r\n", userAgent, referer, len(requestMsg))) + responseHdrSize := len(fmt.Sprintf("Content-Length: %v\r\n", len(responseMsg))) + ent, spanCtx, err := roundTrip(r, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Length", fmt.Sprint(len(responseMsg))) + w.WriteHeader(http.StatusOK) + _, _ = io.WriteString(w, responseMsg) + })) + if err != nil { + t.Fatal("Could not get entry:", err) + } + if want := "test-baggage"; ent.Request.Context().Value(testContextKey) != want { + t.Errorf("Request Context Value = %s; want %s", ent.Request.Context().Value(testContextKey), want) + } + if want := "/foo"; ent.Request.URL.Path != want { + t.Errorf("Request Context Value = %s; want %s", ent.Request.Context().Value(testContextKey), want) + } + if want := "POST"; ent.RequestMethod != want { + t.Errorf("RequestMethod = %q; want %q", ent.RequestMethod, want) + } + if want := "/foo"; ent.RequestURL != want { + t.Errorf("RequestURL = %q; want %q", ent.RequestURL, want) + } + if ent.RequestHeaderSize < int64(requestHdrSize) { + t.Errorf("RequestHeaderSize = %d; want >=%d", ent.RequestHeaderSize, requestHdrSize) + } + if ent.RequestBodySize != int64(len(requestMsg)) { + t.Errorf("RequestBodySize = %d; want %d", ent.RequestBodySize, len(requestMsg)) + } + if ent.UserAgent != userAgent { + t.Errorf("UserAgent = %q; want %q", ent.UserAgent, userAgent) + } + if ent.Referer != referer { + t.Errorf("Referer = %q; want %q", ent.Referer, referer) + } + if want := "HTTP/1.1"; ent.Proto != want { + t.Errorf("Proto = %q; want %q", ent.Proto, want) + } + if ent.Status != http.StatusOK { + t.Errorf("Status = %d; want %d", ent.Status, http.StatusOK) + } + if ent.ResponseHeaderSize < int64(responseHdrSize) { + t.Errorf("ResponseHeaderSize = %d; want >=%d", ent.ResponseHeaderSize, responseHdrSize) + } + if ent.ResponseBodySize != int64(len(responseMsg)) { + t.Errorf("ResponseBodySize = %d; want %d", ent.ResponseBodySize, len(responseMsg)) + } + if ent.TraceID != spanCtx.TraceID() { + t.Errorf("TraceID = %v; want %v", ent.TraceID, spanCtx.TraceID()) + } + if ent.SpanID != spanCtx.SpanID() { + t.Errorf("SpanID = %v; want %v", ent.SpanID, spanCtx.SpanID()) + } +} + +type testSpanHandler struct { + h http.Handler + spanCtx *trace.SpanContext +} + +func (sh *testSpanHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + tracer := otel.Tracer("test") + ctx, span := tracer.Start(r.Context(), "test") + defer span.End() + sc := trace.SpanContextFromContext(ctx) + + sh.spanCtx = &sc + r = r.WithContext(ctx) + + sh.h.ServeHTTP(w, r) +} + +type contextKey string + +const testContextKey = contextKey("baggage") + +func roundTrip(r *http.Request, h http.Handler) (*Entry, *trace.SpanContext, error) { + capture := new(captureLogger) + hh := NewHandler(capture, h) + handler := &testSpanHandler{h: hh} + s := httptest.NewUnstartedServer(handler) + s.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context { + ctx = context.WithValue(ctx, testContextKey, "test-baggage") + return ctx + } + s.Start() + defer s.Close() + r.URL.Host = s.URL[len("http://"):] + resp, err := http.DefaultClient.Do(r) + if err != nil { + return nil, nil, err + } + resp.Body.Close() + return &capture.ent, handler.spanCtx, nil +} + +type captureLogger struct { + ent Entry +} + +func (cl *captureLogger) Log(ent *Entry) { + cl.ent = *ent +} diff --git a/go-cloud/server/requestlog/stackdriver.go b/go-cloud/server/requestlog/stackdriver.go new file mode 100644 index 000000000..ee8e5127d --- /dev/null +++ b/go-cloud/server/requestlog/stackdriver.go @@ -0,0 +1,115 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 requestlog + +import ( + "bytes" + "encoding/json" + "io" + "strconv" + "sync" + "time" +) + +// A StackdriverLogger writes log entries in the Stackdriver forward JSON +// format. The record's fields are suitable for consumption by +// Stackdriver Logging. +type StackdriverLogger struct { + onErr func(error) + + mu sync.Mutex + w io.Writer + buf bytes.Buffer + enc *json.Encoder +} + +// NewStackdriverLogger returns a new logger that writes to w. +// A nil onErr is treated the same as func(error) {}. +func NewStackdriverLogger(w io.Writer, onErr func(error)) *StackdriverLogger { + l := &StackdriverLogger{ + w: w, + onErr: onErr, + } + l.enc = json.NewEncoder(&l.buf) + return l +} + +// Log writes a record to its writer. Multiple concurrent calls will +// produce sequential writes to its writer. +func (l *StackdriverLogger) Log(ent *Entry) { + if err := l.log(ent); err != nil && l.onErr != nil { + l.onErr(err) + } +} + +func (l *StackdriverLogger) log(ent *Entry) error { + defer l.mu.Unlock() + l.mu.Lock() + + l.buf.Reset() + // r represents the fluent-plugin-google-cloud format + // See https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud/blob/f93046d92f7722db2794a042c3f2dde5df91a90b/lib/fluent/plugin/out_google_cloud.rb#L145 + // to check json tags + var r struct { + HTTPRequest struct { + RequestMethod string `json:"requestMethod"` + RequestURL string `json:"requestUrl"` + RequestSize int64 `json:"requestSize,string"` + Status int `json:"status"` + ResponseSize int64 `json:"responseSize,string"` + UserAgent string `json:"userAgent"` + RemoteIP string `json:"remoteIp"` + Referer string `json:"referer"` + Latency string `json:"latency"` + } `json:"httpRequest"` + Timestamp struct { + Seconds int64 `json:"seconds"` + Nanos int `json:"nanos"` + } `json:"timestamp"` + TraceID string `json:"logging.googleapis.com/trace"` + SpanID string `json:"logging.googleapis.com/spanId"` + } + r.HTTPRequest.RequestMethod = ent.RequestMethod + r.HTTPRequest.RequestURL = ent.RequestURL + // TODO(light): determine whether this is the formula LogEntry expects. + r.HTTPRequest.RequestSize = ent.RequestHeaderSize + ent.RequestBodySize + r.HTTPRequest.Status = ent.Status + // TODO(light): determine whether this is the formula LogEntry expects. + r.HTTPRequest.ResponseSize = ent.ResponseHeaderSize + ent.ResponseBodySize + r.HTTPRequest.UserAgent = ent.UserAgent + r.HTTPRequest.RemoteIP = ent.RemoteIP + r.HTTPRequest.Referer = ent.Referer + r.HTTPRequest.Latency = string(appendLatency(nil, ent.Latency)) + + t := ent.ReceivedTime.Add(ent.Latency) + r.Timestamp.Seconds = t.Unix() + r.Timestamp.Nanos = t.Nanosecond() + r.TraceID = ent.TraceID.String() + r.SpanID = ent.SpanID.String() + if err := l.enc.Encode(r); err != nil { + return err + } + _, err := l.w.Write(l.buf.Bytes()) + + return err +} + +func appendLatency(b []byte, d time.Duration) []byte { + // Parses format understood by google-fluentd (which is looser than the documented LogEntry format). + // See the comment at https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud/blob/e2f60cdd1d97e79ffe4e91bdbf6bd84837f27fa5/lib/fluent/plugin/out_google_cloud.rb#L1539 + b = strconv.AppendFloat(b, d.Seconds(), 'f', 9, 64) + b = append(b, 's') + return b +} diff --git a/go-cloud/server/requestlog/stackdriver_test.go b/go-cloud/server/requestlog/stackdriver_test.go new file mode 100644 index 000000000..8a55859f5 --- /dev/null +++ b/go-cloud/server/requestlog/stackdriver_test.go @@ -0,0 +1,218 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 requestlog + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" +) + +func TestStackdriverLog(t *testing.T) { + const ( + startTime = 1507914000 + startTimeNanos = 512 + + latencySec = 5 + latencyNanos = 123456789 + + endTime = startTime + latencySec + endTimeNanos = startTimeNanos + latencyNanos + ) + tracer := otel.Tracer("test") + ctx, span := tracer.Start(context.Background(), "test") + defer span.End() + sc := trace.SpanContextFromContext(ctx) + buf := new(bytes.Buffer) + var logErr error + l := NewStackdriverLogger(buf, func(e error) { logErr = e }) + want := &Entry{ + ReceivedTime: time.Unix(startTime, startTimeNanos), + RequestMethod: "POST", + RequestURL: "/foo/bar", + RequestHeaderSize: 456, + RequestBodySize: 123000, + UserAgent: "Chrome proxied through Firefox and Edge", + Referer: "http://www.example.com/", + Proto: "HTTP/1.1", + RemoteIP: "12.34.56.78", + ServerIP: "127.0.0.1", + Status: 404, + ResponseHeaderSize: 555, + ResponseBodySize: 789000, + Latency: latencySec*time.Second + latencyNanos*time.Nanosecond, + TraceID: sc.TraceID(), + SpanID: sc.SpanID(), + } + ent := *want // copy in case Log accidentally mutates + l.Log(&ent) + if logErr != nil { + t.Error("Logger called error callback:", logErr) + } + + var got json.RawMessage + if err := json.Unmarshal(buf.Bytes(), &got); err != nil { + t.Fatal("Unmarshal:", err) + } + + var r map[string]any + if err := json.Unmarshal(got, &r); err != nil { + t.Error("Unmarshal record:", err) + } else { + rr, _ := r["httpRequest"].(map[string]any) + if rr == nil { + t.Error("httpRequest does not exist in record or is not a JSON object") + } + if got, want := jsonString(rr, "requestMethod"), ent.RequestMethod; got != want { + t.Errorf("httpRequest.requestMethod = %q; want %q", got, want) + } + if got, want := jsonString(rr, "requestUrl"), ent.RequestURL; got != want { + t.Errorf("httpRequest.requestUrl = %q; want %q", got, want) + } + if got, want := jsonString(rr, "requestSize"), "123456"; got != want { + t.Errorf("httpRequest.requestSize = %q; want %q", got, want) + } + if got, want := jsonNumber(rr, "status"), float64(ent.Status); got != want { + t.Errorf("httpRequest.status = %d; want %d", int64(got), int64(want)) + } + if got, want := jsonString(rr, "responseSize"), "789555"; got != want { + t.Errorf("httpRequest.responseSize = %q; want %q", got, want) + } + if got, want := jsonString(rr, "userAgent"), ent.UserAgent; got != want { + t.Errorf("httpRequest.userAgent = %q; want %q", got, want) + } + if got, want := jsonString(rr, "remoteIp"), ent.RemoteIP; got != want { + t.Errorf("httpRequest.remoteIp = %q; want %q", got, want) + } + if got, want := jsonString(rr, "referer"), ent.Referer; got != want { + t.Errorf("httpRequest.referer = %q; want %q", got, want) + } + if got, want := jsonString(rr, "latency"), "5.123456789"; parseLatency(got) != want { + t.Errorf("httpRequest.latency = %q; want %q", got, want+"s") + } + ts, _ := r["timestamp"].(map[string]any) + if ts == nil { + t.Error("timestamp does not exist in record or is not a JSON object") + } + if got, want := jsonNumber(ts, "seconds"), float64(endTime); got != want { + t.Errorf("timestamp.seconds = %g; want %g", got, want) + } + if got, want := jsonNumber(ts, "nanos"), float64(endTimeNanos); got != want { + t.Errorf("timestamp.nanos = %g; want %g", got, want) + } + if got, want := jsonString(r, "logging.googleapis.com/trace"), ent.TraceID.String(); got != want { + t.Errorf("traceID = %q; want %q", got, want) + } + if got, want := jsonString(r, "logging.googleapis.com/spanId"), ent.SpanID.String(); got != want { + t.Errorf("spanID = %q; want %q", got, want) + } + } +} + +func parseLatency(s string) string { + s = strings.TrimSpace(s) + if !strings.HasSuffix(s, "s") { + return "" + } + s = strings.TrimSpace(s[:len(s)-1]) + for _, c := range s { + if !(c >= '0' && c <= '9') && c != '.' { + return "" + } + } + return s +} + +func jsonString(obj map[string]any, k string) string { + v, _ := obj[k].(string) + return v +} + +func jsonNumber(obj map[string]any, k string) float64 { + v, _ := obj[k].(float64) + return v +} + +func BenchmarkStackdriverLog(b *testing.B) { + ent := &Entry{ + ReceivedTime: time.Date(2017, time.October, 13, 17, 0, 0, 512, time.UTC), + RequestMethod: "POST", + RequestURL: "/foo/bar", + RequestHeaderSize: 456, + RequestBodySize: 123000, + UserAgent: "Chrome proxied through Firefox and Edge", + Referer: "http://www.example.com/", + Proto: "HTTP/1.1", + RemoteIP: "12.34.56.78", + ServerIP: "127.0.0.1", + Status: 404, + ResponseHeaderSize: 555, + ResponseBodySize: 789000, + Latency: 5 * time.Second, + } + var buf bytes.Buffer + l := NewStackdriverLogger(&buf, func(error) {}) + l.Log(ent) + b.ReportAllocs() + b.SetBytes(int64(buf.Len())) + buf.Reset() + b.ResetTimer() + + l = NewStackdriverLogger(io.Discard, func(error) {}) + for i := 0; i < b.N; i++ { + l.Log(ent) + } +} + +func BenchmarkE2E(b *testing.B) { + run := func(b *testing.B, handler http.Handler) { + b.Helper() + + s := httptest.NewServer(handler) + defer s.Close() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + resp, err := http.Get(s.URL) + if err != nil { + b.Fatal(err) + } + _, _ = io.Copy(io.Discard, resp.Body) + _ = resp.Body.Close() + } + } + b.Run("Baseline", func(b *testing.B) { + run(b, http.HandlerFunc(benchHandler)) + }) + b.Run("WithLog", func(b *testing.B) { + l := NewStackdriverLogger(io.Discard, func(error) {}) + run(b, NewHandler(l, http.HandlerFunc(benchHandler))) + }) +} + +func benchHandler(w http.ResponseWriter, r *http.Request) { + const msg = "Hello, World!" + w.Header().Set("Content-Length", fmt.Sprint(len(msg))) + _, _ = io.WriteString(w, msg) +} diff --git a/go-cloud/server/sdserver/server.go b/go-cloud/server/sdserver/server.go new file mode 100644 index 000000000..5f83d5567 --- /dev/null +++ b/go-cloud/server/sdserver/server.go @@ -0,0 +1,148 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 sdserver provides the diagnostic hooks for a server using +// Stackdriver. +package sdserver // import "gocloud.dev/server/sdserver" + +import ( + "context" + "fmt" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" + "go.opentelemetry.io/otel/trace" + "github.com/DataDog/iceberg-go/go-cloud/server" + "os" + + gcpmex "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric" + gcptex "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" + gcppropagator "github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator" + "github.com/google/wire" + gcpres "go.opentelemetry.io/contrib/detectors/gcp" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "github.com/DataDog/iceberg-go/go-cloud/gcp" + "github.com/DataDog/iceberg-go/go-cloud/server/requestlog" +) + +// Set is a Wire provider set that provides the diagnostic hooks for +// *server.Server given a GCP token source and a GCP project ID. +var Set = wire.NewSet( + server.Set, + NewTextMapPropagator, + NewTraceSampler, + NewTraceExporter, + NewTraceProvider, + wire.Bind(new(trace.TracerProvider), new(*sdktrace.TracerProvider)), + NewMetricsReader, + NewMeterProvider, + wire.Bind(new(metric.MeterProvider), new(*sdkmetric.MeterProvider)), + + NewRequestLogger, + wire.Bind(new(requestlog.Logger), new(*requestlog.StackdriverLogger)), +) + +func NewResource(ctx context.Context) (*resource.Resource, error) { + + res, err := resource.New(ctx, + resource.WithDetectors(gcpres.NewDetector()), + resource.WithTelemetrySDK(), + resource.WithProcess(), + resource.WithOS(), + resource.WithContainer(), + resource.WithHost(), + ) + if err != nil { + return nil, err + } + + return resource.Merge(resource.Default(), res) +} + +func NewTextMapPropagator() propagation.TextMapPropagator { + return propagation.NewCompositeTextMapPropagator( + gcppropagator.CloudTraceOneWayPropagator{}, + propagation.TraceContext{}, + propagation.Baggage{}, + ) +} + +// NewTraceSampler returns a new OpenTelemetry trace sampler. +func NewTraceSampler(ctx context.Context) sdktrace.Sampler { + return sdktrace.AlwaysSample() +} + +// NewTraceExporter returns a new OpenTelemetry gcp trace exporter. +func NewTraceExporter(projectID gcp.ProjectID) (sdktrace.SpanExporter, error) { + exporter, err := gcptex.New(gcptex.WithProjectID(string(projectID))) + if err != nil { + return nil, err + } + + return exporter, nil +} + +// NewTraceProvider returns a new trace provider for our service to utilise. +// +// The second return value is a Wire cleanup function that calls Close on the provider, +func NewTraceProvider(ctx context.Context, exporter sdktrace.SpanExporter, sampler sdktrace.Sampler) (*sdktrace.TracerProvider, func(), error) { + + res, err := NewResource(ctx) + if err != nil { + return nil, nil, err + } + + tp := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(exporter), + sdktrace.WithSampler(sampler), + sdktrace.WithResource(res), + ) + + return tp, func() { _ = tp.Shutdown(ctx) }, nil +} + +// NewMetricsReader returns a new OpenTelemetry gcp metrics reader and exporter. +func NewMetricsReader(projectID gcp.ProjectID) (sdkmetric.Reader, error) { + metricExporter, err := gcpmex.New(gcpmex.WithProjectID(string(projectID))) + if err != nil { + return nil, err + } + + return sdkmetric.NewPeriodicReader(metricExporter), nil +} + +// NewMeterProvider returns a new metric provider for our service to utilise. +// +// The second return value is a Wire cleanup function that calls Close on the provider. +func NewMeterProvider(ctx context.Context, reader sdkmetric.Reader) (*sdkmetric.MeterProvider, func(), error) { + + res, err := NewResource(ctx) + if err != nil { + return nil, nil, err + } + + meterProvider := sdkmetric.NewMeterProvider( + sdkmetric.WithResource(res), + sdkmetric.WithReader(reader), + ) + return meterProvider, func() { _ = meterProvider.Shutdown(ctx) }, nil +} + +// NewRequestLogger returns a request logger that sends entries to stdout. +func NewRequestLogger() *requestlog.StackdriverLogger { + // For now, request logs are written to stdout and get picked up by fluentd. + // This also works when running locally. + return requestlog.NewStackdriverLogger(os.Stdout, func(e error) { fmt.Println(e) }) +} diff --git a/go-cloud/server/server.go b/go-cloud/server/server.go new file mode 100644 index 000000000..82749ae51 --- /dev/null +++ b/go-cloud/server/server.go @@ -0,0 +1,208 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 server provides a preconfigured HTTP server with diagnostic hooks. +package server // import "gocloud.dev/server" + +import ( + "context" + "fmt" + "net/http" + "sync" + "time" + + "github.com/google/wire" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/trace" + + "github.com/DataDog/iceberg-go/go-cloud/server/driver" + "github.com/DataDog/iceberg-go/go-cloud/server/health" + "github.com/DataDog/iceberg-go/go-cloud/server/requestlog" +) + +// Set is a Wire provider set that produces a *Server given the fields of +// Options. +var Set = wire.NewSet( + New, + wire.Struct(new(Options), "RequestLogger", "HealthChecks", + "TraceTextMapPropagator", "TraceProvider", "MetricsProvider", "Driver"), + wire.Value(&DefaultDriver{}), + wire.Bind(new(driver.Server), new(*DefaultDriver)), +) + +// Server is a preconfigured HTTP server with diagnostic hooks. +// The zero value is a server with the default options. +type Server struct { + reqlog requestlog.Logger + handler http.Handler + wrappedHandler http.Handler + healthHandler health.Handler + textMapPropagator propagation.TextMapPropagator + traceProvider trace.TracerProvider + meterProvider metric.MeterProvider + once sync.Once + driver driver.Server +} + +// Options is the set of optional parameters. +type Options struct { + // RequestLogger specifies the logger that will be used to log requests. + RequestLogger requestlog.Logger + + // HealthChecks specifies the health checks to be run when the + // /healthz/readiness endpoint is requested. + HealthChecks []health.Checker + + // TraceTextMapPropagator decides the format of trace text propagated. + TraceTextMapPropagator propagation.TextMapPropagator + + // TraceProvider handles sampled trace spans. + TraceProvider trace.TracerProvider + + // MetricsProvider handles application metrics. + MetricsProvider metric.MeterProvider + + // Driver serves HTTP requests. + Driver driver.Server +} + +// New creates a new server. New(nil, nil) is the same as new(Server). +func New(h http.Handler, opts *Options) *Server { + srv := &Server{handler: h} + if opts != nil { + srv.reqlog = opts.RequestLogger + srv.textMapPropagator = opts.TraceTextMapPropagator + srv.traceProvider = opts.TraceProvider + srv.meterProvider = opts.MetricsProvider + for _, c := range opts.HealthChecks { + srv.healthHandler.Add(c) + } + srv.driver = opts.Driver + } + return srv +} + +func (srv *Server) init() { + srv.once.Do(func() { + + if srv.textMapPropagator != nil { + otel.SetTextMapPropagator(srv.textMapPropagator) + } + + if srv.traceProvider != nil { + otel.SetTracerProvider(srv.traceProvider) + } + + if srv.meterProvider != nil { + otel.SetMeterProvider(srv.meterProvider) + } + + if srv.driver == nil { + srv.driver = NewDefaultDriver() + } + if srv.handler == nil { + srv.handler = http.DefaultServeMux + } + // Setup health checks, /healthz route is taken by health checks by default. + // Note: App Engine Flex uses /_ah/health by default, which can be changed + // in app.yaml. We may want to do an auto-detection for flex in future. + const healthPrefix = "/healthz/" + + mux := http.NewServeMux() + mux.HandleFunc(healthPrefix+"liveness", health.HandleLive) + mux.Handle(healthPrefix+"readiness", &srv.healthHandler) + h := srv.handler + if srv.reqlog != nil { + h = requestlog.NewHandler(srv.reqlog, h) + } + // Wrap with OpenTelemetry HTTP handler. + h = otelhttp.NewHandler(h, "", otelhttp.WithPublicEndpoint()) + mux.Handle("/", h) + srv.wrappedHandler = mux + }) +} + +// ListenAndServe is a wrapper to use wherever http.ListenAndServe is used. +// It wraps the http.Handler provided to New with a handler that handles tracing and +// request logging. If the handler is nil, then http.DefaultServeMux will be used. +// A configured Requestlogger will log all requests except HealthChecks. +func (srv *Server) ListenAndServe(addr string) error { + srv.init() + return srv.driver.ListenAndServe(addr, srv.wrappedHandler) +} + +// ListenAndServeTLS is a wrapper to use wherever http.ListenAndServeTLS is used. +// It wraps the http.Handler provided to New with a handler that handles tracing and +// request logging. If the handler is nil, then http.DefaultServeMux will be used. +// A configured Requestlogger will log all requests except HealthChecks. +func (srv *Server) ListenAndServeTLS(addr, certFile, keyFile string) error { + // Check if the driver implements the optional interface. + tlsDriver, ok := srv.driver.(driver.TLSServer) + if !ok { + return fmt.Errorf("driver %T does not support ListenAndServeTLS", srv.driver) + } + srv.init() + return tlsDriver.ListenAndServeTLS(addr, certFile, keyFile, srv.wrappedHandler) +} + +// Shutdown gracefully shuts down the server without interrupting any active connections. +func (srv *Server) Shutdown(ctx context.Context) error { + if srv.driver == nil { + return nil + } + return srv.driver.Shutdown(ctx) +} + +// DefaultDriver implements the driver.Server interface. The zero value is a valid http.Server. +type DefaultDriver struct { + Server http.Server +} + +// NewDefaultDriver creates a driver with an http.Server with default timeouts. +func NewDefaultDriver() *DefaultDriver { + return &DefaultDriver{ + Server: http.Server{ + ReadTimeout: 30 * time.Second, + WriteTimeout: 30 * time.Second, + IdleTimeout: 120 * time.Second, + }, + } +} + +// ListenAndServe sets the address and handler on DefaultDriver's http.Server, +// then calls ListenAndServe on it. +func (dd *DefaultDriver) ListenAndServe(addr string, h http.Handler) error { + dd.Server.Addr = addr + dd.Server.Handler = h + return dd.Server.ListenAndServe() +} + +// ListenAndServeTLS sets the address and handler on DefaultDriver's http.Server, +// then calls ListenAndServeTLS on it. +// +// DefaultDriver.Server.TLSConfig may be set to configure additional TLS settings. +func (dd *DefaultDriver) ListenAndServeTLS(addr, certFile, keyFile string, h http.Handler) error { + dd.Server.Addr = addr + dd.Server.Handler = h + return dd.Server.ListenAndServeTLS(certFile, keyFile) +} + +// Shutdown gracefully shuts down the server without interrupting any active connections, +// by calling Shutdown on DefaultDriver's http.Server +func (dd *DefaultDriver) Shutdown(ctx context.Context) error { + return dd.Server.Shutdown(ctx) +} diff --git a/go-cloud/server/server_test.go b/go-cloud/server/server_test.go new file mode 100644 index 000000000..9371e93d7 --- /dev/null +++ b/go-cloud/server/server_test.go @@ -0,0 +1,169 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 server + +import ( + "context" + "errors" + "net/http" + "net/http/httptest" + "testing" + + "github.com/DataDog/iceberg-go/go-cloud/server/requestlog" +) + +const ( + certFile = "my-cert" + keyFile = "my-key" +) + +func TestListenAndServe(t *testing.T) { + td := new(testDriver) + s := New(http.NotFoundHandler(), &Options{Driver: td}) + err := s.ListenAndServe(":8080") + if err != nil { + t.Fatal(err) + } + if !td.listenAndServeCalled { + t.Error("ListenAndServe was not called from the supplied driver") + } + if td.certFile != "" || td.keyFile != "" { + t.Errorf("ListenAndServe got non-empty certFile or keyFile (%q, %q), wanted empty", td.certFile, td.keyFile) + } + if td.handler == nil { + t.Error("testDriver must set handler, got nil") + } +} + +func TestListenAndServeTLSNoSupported(t *testing.T) { + td := new(testDriverNoTLS) + s := New(http.NotFoundHandler(), &Options{Driver: td}) + err := s.ListenAndServeTLS(":8080", certFile, keyFile) + if err == nil { + t.Fatal("expected TLS not supported error") + } +} + +func TestListenAndServeTLS(t *testing.T) { + td := new(testDriver) + s := New(http.NotFoundHandler(), &Options{Driver: td}) + err := s.ListenAndServeTLS(":8080", certFile, keyFile) + if err != nil { + t.Fatal(err) + } + if !td.listenAndServeCalled { + t.Error("ListenAndServe was not called from the supplied driver") + } + if td.certFile != certFile { + t.Errorf("ListenAndServe got certFile %q, want %q", td.certFile, certFile) + } + if td.keyFile != keyFile { + t.Errorf("ListenAndServe got keyFile %q, want %q", td.keyFile, keyFile) + } + if td.handler == nil { + t.Error("testDriver must set handler, got nil") + } +} + +func TestMiddleware(t *testing.T) { + onLogCalled := 0 + + tl := &testLogger{ + onLog: func(ent *requestlog.Entry) { + onLogCalled++ + if ent.TraceID.String() == "" { + t.Error("TraceID is empty") + } + if ent.SpanID.String() == "" { + t.Error("SpanID is empty") + } + }, + } + + td := new(testDriver) + s := New(http.NotFoundHandler(), &Options{Driver: td, RequestLogger: tl}) + err := s.ListenAndServe(":8080") + if err != nil { + t.Fatal(err) + } + + req, err := http.NewRequest("GET", "/", nil) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + td.handler.ServeHTTP(rr, req) + if onLogCalled != 1 { + t.Fatal("logging middleware was not called") + } + + // Repeat with TLS. + err = s.ListenAndServeTLS(":8081", certFile, keyFile) + if err != nil { + t.Fatal(err) + } + + req, err = http.NewRequest("GET", "/", nil) + if err != nil { + t.Fatal(err) + } + td.handler.ServeHTTP(rr, req) + if onLogCalled != 2 { + t.Fatal("logging middleware was not called for TLS") + } +} + +type testDriverNoTLS string + +func (td *testDriverNoTLS) ListenAndServe(addr string, h http.Handler) error { + return errors.New("this is a method for satisfying the interface") +} + +func (td *testDriverNoTLS) Shutdown(ctx context.Context) error { + return errors.New("this is a method for satisfying the interface") +} + +type testDriver struct { + listenAndServeCalled bool + certFile, keyFile string + handler http.Handler +} + +func (td *testDriver) ListenAndServe(addr string, h http.Handler) error { + td.listenAndServeCalled = true + td.handler = h + return nil +} + +func (td *testDriver) ListenAndServeTLS(addr, certFile, keyFile string, h http.Handler) error { + td.listenAndServeCalled = true + td.certFile = certFile + td.keyFile = keyFile + td.handler = h + return nil +} + +func (td *testDriver) Shutdown(ctx context.Context) error { + return errors.New("this is a method for satisfying the interface") +} + +type testLogger struct { + onLog func(ent *requestlog.Entry) +} + +func (tl *testLogger) Log(ent *requestlog.Entry) { + tl.onLog(ent) +} diff --git a/go-cloud/server/xrayserver/server.go b/go-cloud/server/xrayserver/server.go new file mode 100644 index 000000000..d589cfd4f --- /dev/null +++ b/go-cloud/server/xrayserver/server.go @@ -0,0 +1,156 @@ +// Copyright 2018 The Go Cloud Development Kit 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 +// +// https://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 xrayserver provides the diagnostic hooks for a server using +// ADOT collector. +package xrayserver // import "gocloud.dev/server/xrayserver" + +import ( + "context" + "fmt" + ec2res "go.opentelemetry.io/contrib/detectors/aws/ec2" + "go.opentelemetry.io/contrib/propagators/aws/xray" + "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" + "github.com/DataDog/iceberg-go/go-cloud/server" + "github.com/DataDog/iceberg-go/go-cloud/server/requestlog" + "google.golang.org/grpc" + "os" + + "github.com/google/wire" + "go.opentelemetry.io/otel/metric" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/trace" +) + +// Set is a Wire provider set that provides the diagnostic hooks for +// *server.Server using aws specific formats outlined here +// https://aws-otel.github.io/docs/getting-started/go-sdk/manual-instr. +var Set = wire.NewSet( + server.Set, + TracesSet, + MetricsSet, + + NewRequestLogger, + wire.Bind(new(requestlog.Logger), new(*requestlog.NCSALogger)), +) + +// TracesSet is a Wire provider set that provides the open telemetry trace provider given the exporter. +var TracesSet = wire.NewSet( + NewTextMapPropagator, + wire.Bind(new(propagation.TextMapPropagator), new(*xray.Propagator)), + NewTraceSampler, + NewTraceExporter, + NewTraceProvider, + wire.Bind(new(trace.TracerProvider), new(*sdktrace.TracerProvider)), +) + +// MetricsSet is a Wire provider set that provides the open telemetry metrics provider given the exporter. +var MetricsSet = wire.NewSet( + NewMetricsReader, + NewMeterProvider, + wire.Bind(new(metric.MeterProvider), new(*sdkmetric.MeterProvider)), +) + +func NewResource(ctx context.Context) (*resource.Resource, error) { + + res, err := resource.New(ctx, + resource.WithDetectors(ec2res.NewResourceDetector()), + resource.WithTelemetrySDK(), + resource.WithProcess(), + resource.WithOS(), + resource.WithContainer(), + resource.WithHost(), + ) + if err != nil { + return nil, err + } + + return resource.Merge(resource.Default(), res) +} + +func NewTextMapPropagator() *xray.Propagator { + return &xray.Propagator{} +} + +// NewTraceSampler returns a new OpenTelemetry trace sampler. +func NewTraceSampler() sdktrace.Sampler { + return sdktrace.AlwaysSample() +} + +func NewTraceExporter(ctx context.Context) (sdktrace.SpanExporter, error) { + traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithInsecure(), otlptracegrpc.WithEndpoint("0.0.0.0:4317"), otlptracegrpc.WithDialOption(grpc.WithBlock())) + if err != nil { + return nil, err + } + return traceExporter, nil +} + +// NewTraceProvider returns a new trace provider for our service to utilise. +// +// The second return value is a Wire cleanup function that calls Close on the provider. +func NewTraceProvider(ctx context.Context, exp sdktrace.SpanExporter, sampler sdktrace.Sampler) (*sdktrace.TracerProvider, func(), error) { + + res, err := NewResource(ctx) + if err != nil { + return nil, nil, err + } + + idg := xray.NewIDGenerator() + + tp := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(exp), + sdktrace.WithResource(res), + sdktrace.WithSampler(sampler), + sdktrace.WithIDGenerator(idg), + ) + + return tp, func() { _ = tp.Shutdown(ctx) }, nil +} + +func NewMetricsReader(ctx context.Context) (sdkmetric.Reader, error) { + + // Create and start new OTLP metric exporter + metricExporter, err := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithInsecure(), otlpmetricgrpc.WithEndpoint("0.0.0.0:4317"), otlpmetricgrpc.WithDialOption(grpc.WithBlock())) + if err != nil { + return nil, err + } + + return sdkmetric.NewPeriodicReader(metricExporter), nil +} + +// NewMeterProvider returns a new metric provider for our service to utilise. +// +// The second return value is a Wire cleanup function that calls Close on the provider. +func NewMeterProvider(ctx context.Context, reader sdkmetric.Reader) (*sdkmetric.MeterProvider, func(), error) { + + res, err := NewResource(ctx) + if err != nil { + return nil, nil, err + } + + meterProvider := sdkmetric.NewMeterProvider( + sdkmetric.WithResource(res), + sdkmetric.WithReader(reader), + ) + return meterProvider, func() { _ = meterProvider.Shutdown(ctx) }, nil +} + +// NewRequestLogger returns a request logger that sends entries to stdout. +func NewRequestLogger() *requestlog.NCSALogger { + return requestlog.NewNCSALogger(os.Stdout, func(e error) { _, _ = fmt.Fprintln(os.Stderr, e) }) +} diff --git a/go-cloud/wire/README.md b/go-cloud/wire/README.md new file mode 100644 index 000000000..0e67f1fde --- /dev/null +++ b/go-cloud/wire/README.md @@ -0,0 +1,7 @@ +# Wire has moved! + +Wire has moved to its own repository: [github.com/google/wire](https://github.com/google/wire) + +Read the [announcement][] for more details. + +[announcement]: https://groups.google.com/d/msg/go-cloud/4HuWfjDAkOY/Y2tUQdB_BQAJ diff --git a/go.mod b/go.mod index 6e12f669f..221e73ef1 100644 --- a/go.mod +++ b/go.mod @@ -15,28 +15,62 @@ // specific language governing permissions and limitations // under the License. -module github.com/apache/iceberg-go +module github.com/DataDog/iceberg-go go 1.25.5 require ( + cloud.google.com/go/compute/metadata v0.9.0 + cloud.google.com/go/firestore v1.21.0 + cloud.google.com/go/iam v1.7.0 + cloud.google.com/go/kms v1.26.0 + cloud.google.com/go/pubsub v1.50.1 + cloud.google.com/go/secretmanager v1.16.0 cloud.google.com/go/storage v1.62.1 + github.com/Azure/azure-amqp-common-go/v3 v3.2.3 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 + github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 + github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.10.0 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.4 + github.com/Azure/go-amqp v1.5.0 + github.com/Azure/go-autorest/autorest/to v0.4.1 + github.com/GoogleCloudPlatform/cloudsql-proxy v1.37.10 + github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 + github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.30.0 + github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator v0.54.0 + github.com/XSAM/otelsql v0.40.0 github.com/apache/arrow-go/v18 v18.6.0 + github.com/aws/aws-sdk-go v1.55.8 github.com/aws/aws-sdk-go-v2 v1.41.6 github.com/aws/aws-sdk-go-v2/config v1.32.16 github.com/aws/aws-sdk-go-v2/credentials v1.19.15 + github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.20.26 + github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.8.26 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.20.12 + github.com/aws/aws-sdk-go-v2/service/dynamodb v1.53.2 github.com/aws/aws-sdk-go-v2/service/glue v1.139.3 + github.com/aws/aws-sdk-go-v2/service/kms v1.49.1 github.com/aws/aws-sdk-go-v2/service/s3 v1.99.1 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.2 + github.com/aws/aws-sdk-go-v2/service/sns v1.39.7 + github.com/aws/aws-sdk-go-v2/service/sqs v1.42.17 + github.com/aws/aws-sdk-go-v2/service/ssm v1.67.4 github.com/aws/smithy-go v1.25.0 github.com/awsdocs/aws-doc-sdk-examples/gov2/testtools v0.0.0-20250407191926-092f3e54b837 github.com/beltran/gohive v1.8.1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/docker/docker v28.5.2+incompatible github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 + github.com/fsnotify/fsnotify v1.9.0 + github.com/go-sql-driver/mysql v1.9.3 github.com/google/go-cmp v0.7.0 + github.com/google/go-replayers/grpcreplay v1.3.0 + github.com/google/go-replayers/httpreplay v1.2.0 github.com/google/uuid v1.6.0 + github.com/google/wire v0.7.0 + github.com/googleapis/gax-go/v2 v2.21.0 + github.com/lib/pq v1.10.9 github.com/pterm/pterm v0.12.83 github.com/stretchr/testify v1.11.1 github.com/substrait-io/substrait-go/v8 v8.1.0 @@ -51,11 +85,27 @@ require ( github.com/uptrace/bun/dialect/sqlitedialect v1.2.18 github.com/uptrace/bun/driver/sqliteshim v1.2.18 github.com/uptrace/bun/extra/bundebug v1.2.18 - gocloud.dev v0.45.0 + go.opentelemetry.io/contrib/detectors/aws/ec2 v1.38.0 + go.opentelemetry.io/contrib/detectors/gcp v1.39.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 + go.opentelemetry.io/contrib/propagators/aws v1.38.0 + go.opentelemetry.io/otel v1.43.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 + go.opentelemetry.io/otel/metric v1.43.0 + go.opentelemetry.io/otel/sdk v1.43.0 + go.opentelemetry.io/otel/sdk/metric v1.43.0 + go.opentelemetry.io/otel/trace v1.43.0 + golang.org/x/crypto v0.49.0 golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa + golang.org/x/net v0.52.0 golang.org/x/oauth2 v0.36.0 golang.org/x/sync v0.20.0 + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da google.golang.org/api v0.276.0 + google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 + google.golang.org/grpc v1.80.0 + google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 ) @@ -67,19 +117,19 @@ require ( cloud.google.com/go v0.123.0 // indirect cloud.google.com/go/auth v0.20.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect - cloud.google.com/go/compute/metadata v0.9.0 // indirect - cloud.google.com/go/iam v1.7.0 // indirect + cloud.google.com/go/longrunning v0.9.0 // indirect cloud.google.com/go/monitoring v1.24.3 // indirect + cloud.google.com/go/pubsub/v2 v2.3.0 // indirect + cloud.google.com/go/trace v1.11.7 // indirect dario.cat/mergo v1.0.2 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 // indirect + filippo.io/edwards25519 v1.1.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest/to v0.4.1 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect @@ -88,12 +138,13 @@ require ( github.com/apache/thrift v0.22.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.9 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 // indirect - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.20.12 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 // indirect + github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.32.6 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.14 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.14 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.22 // indirect github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 // indirect @@ -151,11 +202,10 @@ require ( github.com/golang-jwt/jwt/v5 v5.3.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/flatbuffers v25.12.19+incompatible // indirect + github.com/google/martian/v3 v3.3.3 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/wire v0.7.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect - github.com/googleapis/gax-go/v2 v2.21.0 // indirect github.com/gookit/color v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -167,6 +217,7 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf // indirect github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jonboulle/clockwork v0.5.0 // indirect github.com/klauspost/compress v1.18.5 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect @@ -239,36 +290,23 @@ require ( github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect - go.opentelemetry.io/otel v1.43.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect - go.opentelemetry.io/otel/metric v1.43.0 // indirect - go.opentelemetry.io/otel/sdk v1.43.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect - go.opentelemetry.io/otel/trace v1.43.0 // indirect go.opentelemetry.io/proto/otlp v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect go.yaml.in/yaml/v4 v4.0.0-rc.4 // indirect - golang.org/x/crypto v0.49.0 // indirect golang.org/x/mod v0.34.0 // indirect - golang.org/x/net v0.52.0 // indirect golang.org/x/sys v0.43.0 // indirect golang.org/x/term v0.41.0 // indirect golang.org/x/text v0.35.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect - google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect - google.golang.org/grpc v1.80.0 // indirect - google.golang.org/protobuf v1.36.11 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gotest.tools/v3 v3.5.2 // indirect modernc.org/libc v1.72.0 // indirect diff --git a/go.sum b/go.sum index 8866fe384..ffaa34388 100644 --- a/go.sum +++ b/go.sum @@ -8,22 +8,70 @@ atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs= atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU= cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +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.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= cloud.google.com/go/auth v0.20.0 h1:kXTssoVb4azsVDoUiF8KvxAqrsQcQtB53DcSgta74CA= cloud.google.com/go/auth v0.20.0/go.mod h1:942/yi/itH1SsmpyrbnTMDgGfdy2BUqIKyd0cyYLc5Q= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= +cloud.google.com/go/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/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +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.21.0 h1:BhopUsx7kh6NFx77ccRsHhrtkbJUmDAxNY3uapWdjcM= +cloud.google.com/go/firestore v1.21.0/go.mod h1:1xH6HNcnkf/gGyR8udd6pFO4Z7GWJSwLKQMx/u6UrP4= cloud.google.com/go/iam v1.7.0 h1:JD3zh0C6LHl16aCn5Akff0+GELdp1+4hmh6ndoFLl8U= cloud.google.com/go/iam v1.7.0/go.mod h1:tetWZW1PD/m6vcuY2Zj/aU0eCHNPuxedbnbRTyKXvdY= +cloud.google.com/go/kms v1.26.0 h1:cK9mN2cf+9V63D3H1f6koxTatWy39aTI/hCjz1I+adU= +cloud.google.com/go/kms v1.26.0/go.mod h1:pHKOdFJm63hxBsiPkYtowZPltu9dW0MWvBa6IA4HM58= cloud.google.com/go/logging v1.13.2 h1:qqlHCBvieJT9Cdq4QqYx1KPadCQ2noD4FK02eNqHAjA= cloud.google.com/go/logging v1.13.2/go.mod h1:zaybliM3yun1J8mU2dVQ1/qDzjbOqEijZCn6hSBtKak= cloud.google.com/go/longrunning v0.9.0 h1:0EzbDEGsAvOZNbqXopgniY0w0a1phvu5IdUFq8grmqY= cloud.google.com/go/longrunning v0.9.0/go.mod h1:pkTz846W7bF4o2SzdWJ40Hu0Re+UoNT6Q5t+igIcb8E= cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE= cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI= +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= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.50.1 h1:fzbXpPyJnSGvWXF1jabhQeXyxdbCIkXTpjXHy7xviBM= +cloud.google.com/go/pubsub v1.50.1/go.mod h1:6YVJv3MzWJUVdvQXG081sFvS0dWQOdnV+oTo++q/xFk= +cloud.google.com/go/pubsub/v2 v2.3.0 h1:DgAN907x+sP0nScYfBzneRiIhWoXcpCD8ZAut8WX9vs= +cloud.google.com/go/pubsub/v2 v2.3.0/go.mod h1:O5f0KHG9zDheZAd3z5rlCRhxt2JQtB+t/IYLKK3Bpvw= +cloud.google.com/go/secretmanager v1.16.0 h1:19QT7ZsLJ8FSP1k+4esQvuCD7npMJml6hYzilxVyT+k= +cloud.google.com/go/secretmanager v1.16.0/go.mod h1://C/e4I8D26SDTz1f3TQcddhcmiC3rMEl0S1Cakvs3Q= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.62.1 h1:Os0G3XbUbjZumkpDUf2Y0rLoXJTCF1kU2kWUujKYXD8= cloud.google.com/go/storage v1.62.1/go.mod h1:cpYz/kRVZ+UQAF1uHeea10/9ewcRbxGoGNKsS9daSXA= cloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U= @@ -32,8 +80,13 @@ cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8= cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw= +filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/Azure/azure-amqp-common-go/v3 v3.2.3 h1:uDF62mbd9bypXWi19V1bN5NZEO84JqgmI5G73ibAmrk= +github.com/Azure/azure-amqp-common-go/v3 v3.2.3/go.mod h1:7rPmbSfszeovxGfc5fSAXE4ehlXQZHpMja2OtxC2Tas= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= @@ -42,30 +95,53 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+ github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 h1:m/sWOGCREuSBqg2htVQTBY8nOZpyajYztF0vUvSZTuM= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0/go.mod h1:Pu5Zksi2KrU7LPbZbNINx6fuVrUp/ffvpxdDj+i8LeE= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 h1:FbH3BbSb4bvGluTesZZ+ttN/MDsnMmQP36OSnDuSXqw= +github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1/go.mod h1:9V2j0jn9jDEkCkv8w/bKTNppX/d0FVA1ud77xCIP4KA= +github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.10.0 h1:kE5kpeiSqu4jcCQ/sWuyggMXJ/pT6oQ99+8hwPmyeJ0= +github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.10.0/go.mod h1:IAN3Z0DMtehoxoQQnfqg1891z1P7GNoDryKtFcAyMBI= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.8.1 h1:/Zt+cDPnpC3OVDm/JKLOs7M2DKmLRIIp3XIx9pHHiig= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.8.1/go.mod h1:Ng3urmn6dYe8gnbCMoHHVl5APYz2txho3koEkV2o2HA= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.4 h1:jWQK1GI+LeGGUKBADtcH2rRqPxYB1Ljwms5gFA2LqrM= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.4/go.mod h1:8mwH4klAm9DUgR2EEHyEEAQlRDvLPyg5fQry3y+cDew= +github.com/Azure/go-amqp v0.17.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= +github.com/Azure/go-amqp v1.5.0 h1:GRiQK1VhrNFbyx5VlmI6BsA1FCp27W5rb9kxOZScnTo= +github.com/Azure/go-amqp v1.5.0/go.mod h1:vZAogwdrkbyK3Mla8m/CxSc/aKdnTZ4IbPxl51Y5WZE= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= 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.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.4.1 h1:CxNHBqdzTr7rLtdrtb5CMjJcDut+WNGCVv7OmS5+lTc= github.com/Azure/go-autorest/autorest/to v0.4.1/go.mod h1:EtaofgU4zmtvn1zT2ARsjRFdq9vXx0YWtmElwL+GZ9M= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs= github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e h1:rd4bOvKmDIx0WeTv9Qz+hghsgyjikFiPrseXHlKepO0= github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e/go.mod h1:blbwPQh4DTlCZEfk1BLU4oMIhLda2U+A840Uag9DsZw= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.37.10 h1:0jDrC5r/G+L/p715lTXEYRQ6sET0lzPxwTQlMTy9XfQ= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.37.10/go.mod h1:gij9WLu9mdiAFCM2EB+fwnbrVvc7cLr/klV1eEcFwbQ= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 h1:UnDZ/zFfG1JhH/DqxIZYU/1CUAlTUScoXD/LcM2Ykk8= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0/go.mod h1:IA1C1U7jO/ENqm/vhi7V9YYpBsp+IMyqNrEN94N7tVc= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.30.0 h1:5eCqTd9rTwMlE62z0xFdzPJ+3pji75hJrwq1jrCjo5w= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.30.0/go.mod h1:4BcvJy7WxY8X2eX49z2VO1ByhO+CcQK8lKPCH/QlZvo= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0 h1:7t/qx5Ost0s0wbA/VDrByOooURhp+ikYwv20i9Y07TQ= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 h1:0s6TxfCu2KHkkZPnBfsQ2y5qia0jl3MMrmBhu3nCOYk= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator v0.54.0 h1:mQdVn6c25/S2MHfJTWGSK3NwGoI/w9Ad7tzyLWbjAQI= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/propagator v0.54.0/go.mod h1:8W5IW/jylevlBQKSWkh5ZMP2oy7yT9Pnfug6Y6W/9D8= github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= @@ -81,6 +157,8 @@ github.com/Microsoft/hcsshim v0.14.0-rc.1 h1:qAPXKwGOkVn8LlqgBN8GS0bxZ83hOJpcjxz github.com/Microsoft/hcsshim v0.14.0-rc.1/go.mod h1:hTKFGbnDtQb1wHiOWv4v0eN+7boSWAHyK/tNAaYZL0c= github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= +github.com/XSAM/otelsql v0.40.0 h1:8jaiQ6KcoEXF46fBmPEqb+pp29w2xjWfuXjZXTXBjaA= +github.com/XSAM/otelsql v0.40.0/go.mod h1:/7F+1XKt3/sTlYtwKtkHQ5Gzoom+EerXmD1VdnTqfB4= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/anchore/go-struct-converter v0.1.0 h1:2rDRssAl6mgKBSLNiVCMADgZRhoqtw9dedlWa0OhD30= @@ -96,6 +174,8 @@ github.com/apache/thrift v0.22.0/go.mod h1:1e7J/O1Ae6ZQMTYdy9xa3w9k+XHWPfRvdPyJe 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/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= +github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ= +github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk= github.com/aws/aws-sdk-go-v2 v1.41.6 h1:1AX0AthnBQzMx1vbmir3Y4WsnJgiydmnJjiLu+LvXOg= github.com/aws/aws-sdk-go-v2 v1.41.6/go.mod h1:dy0UzBIfwSeot4grGvY1AqFWN5zgziMmWGzysDnHFcQ= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.9 h1:adBsCIIpLbLmYnkQU+nAChU5yhVTvu5PerROm+/Kq2A= @@ -104,6 +184,10 @@ github.com/aws/aws-sdk-go-v2/config v1.32.16 h1:Q0iQ7quUgJP0F/SCRTieScnaMdXr9h/2 github.com/aws/aws-sdk-go-v2/config v1.32.16/go.mod h1:duCCnJEFqpt2RC6no1iK6q+8HpwOAkiUua0pY507dQc= github.com/aws/aws-sdk-go-v2/credentials v1.19.15 h1:fyvgWTszojq8hEnMi8PPBTvZdTtEVmAVyo+NFLHBhH4= github.com/aws/aws-sdk-go-v2/credentials v1.19.15/go.mod h1:gJiYyMOjNg8OEdRWOf3CrFQxM2a98qmrtjx1zuiQfB8= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.20.26 h1:khdgzmb6QKweEAnjBhg/Ikcn0VguyOyg0gMSVyK8ddI= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.20.26/go.mod h1:P5lKM3+laQ9v0KAOLhxOkClj4UbBwXJ2QcQc2sKSOYo= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.8.26 h1:tHmqvPzeKaCIlD4kdQVP+7v5GdHHtu9olhvweho5zr8= +github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.8.26/go.mod h1:qEScmjwld3lw08e6CIWbPIgfcCKBdw2htqqBtSOSINQ= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 h1:IOGsJ1xVWhsi+ZO7/NW8OuZZBtMJLZbk4P5HDjJO0jQ= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22/go.mod h1:b+hYdbU+jGKfXE8kKM6g1+h+L/Go3vMvzlxBsiuGsxg= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.20.12 h1:Zy6Tme1AA13kX8x3CnkHx5cqdGWGaj/anwOiWGnA0Xo= @@ -114,20 +198,36 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22 h1:dY4kWZiSaXIzxnKlj1 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22/go.mod h1:KIpEUx0JuRZLO7U6cbV204cWAEco2iC3l061IxlwLtI= github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 h1:FPXsW9+gMuIeKmz7j6ENWcWtBGTe1kH8r9thNt5Uxx4= github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23/go.mod h1:7J8iGMdRKk6lw2C+cMIphgAnT8uTwBwNOsGkyOCm80U= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.53.2 h1:+/HEQj1fQGr17AQ0fAKpefDHw2hxQ3f0q96hY39J8Ao= +github.com/aws/aws-sdk-go-v2/service/dynamodb v1.53.2/go.mod h1:bz4cZH7uK5fLxQbj7hL4MFDL+pjReC9en/nM2Wfwxsk= +github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.32.6 h1:m8Odxvyy7nirivpiI0VLwqd3lUkVRgeKPQgdJ9YhvcQ= +github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.32.6/go.mod h1:r2DJVcbGPv7oJGoPICCQJ+4ci5oSGjdXtdscnJIQBfk= github.com/aws/aws-sdk-go-v2/service/glue v1.139.3 h1:2awAOXxGrBdC53fTI7P40kkDVz0mCIU1+3beKypTrIo= github.com/aws/aws-sdk-go-v2/service/glue v1.139.3/go.mod h1:mDg5wTmo9ElbuHNOerghTunsyjUS8PUtdIFVAFMON88= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8 h1:HtOTYcbVcGABLOVuPYaIihj6IlkqubBwFj10K5fxRek= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8/go.mod h1:VsK9abqQeGlzPgUr+isNWzPlK2vKe9INMLWnY65f5Xs= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.14 h1:xnvDEnw+pnj5mctWiYuFbigrEzSm35x7k4KS/ZkCANg= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.14/go.mod h1:yS5rNogD8e0Wu9+l3MUwr6eENBzEeGejvINpN5PAYfY= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.14 h1:3exo28cClRTVnxdj/LULxkESZSSv74RUIjZ7tfHXfWQ= +github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.11.14/go.mod h1:yLon9pByjyB6JZq5IAmwnjE3ObIhD0QibfRWH7tUhLU= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22 h1:PUmZeJU6Y1Lbvt9WFuJ0ugUK2xn6hIWUBBbKuOWF30s= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22/go.mod h1:nO6egFBoAaoXze24a2C0NjQCvdpk8OueRoYimvEB9jo= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.22 h1:SE+aQ4DEqG53RRCAIHlCf//B2ycxGH7jFkpnAh/kKPM= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.22/go.mod h1:ES3ynECd7fYeJIL6+oax+uIEljmfps0S70BaQzbMd/o= +github.com/aws/aws-sdk-go-v2/service/kms v1.49.1 h1:U0asSZ3ifpuIehDPkRI2rxHbmFUMplDA2VeR9Uogrmw= +github.com/aws/aws-sdk-go-v2/service/kms v1.49.1/go.mod h1:NZo9WJqQ0sxQ1Yqu1IwCHQFQunTms2MlVgejg16S1rY= github.com/aws/aws-sdk-go-v2/service/s3 v1.99.1 h1:kU/eBN5+MWNo/LcbNa4hWDdN76hdcd7hocU5kvu7IsU= github.com/aws/aws-sdk-go-v2/service/s3 v1.99.1/go.mod h1:Fw9aqhJicIVee1VytBBjH+l+5ov6/PhbtIK/u3rt/ls= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.2 h1:p0tPbc1uXSAYs9ACiVB9WxlV6AY5TBVNadXdvGrtOHA= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.2/go.mod h1:c6Vg0BRiU7v0MVhHupw90RyL120QBwAMLbDCzptGeMk= github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 h1:a1Fq/KXn75wSzoJaPQTgZO0wHGqE9mjFnylnqEPTchA= github.com/aws/aws-sdk-go-v2/service/signin v1.0.10/go.mod h1:p6+MXNxW7IA6dMgHfTAzljuwSKD0NCm/4lbS4t6+7vI= +github.com/aws/aws-sdk-go-v2/service/sns v1.39.7 h1:fovS7qGMT+BBSuifkySdVaMWxXTyaYT6qaBx/1y6Ij4= +github.com/aws/aws-sdk-go-v2/service/sns v1.39.7/go.mod h1:gFahrattA8ulEtiS4XL/fQiQ77l+Urc52Y96/r1e6ks= +github.com/aws/aws-sdk-go-v2/service/sqs v1.42.17 h1:ZNMxVFPayuHe14u/vn+BwLi3wxQvxcNTw8WdPv2gqBc= +github.com/aws/aws-sdk-go-v2/service/sqs v1.42.17/go.mod h1:ZxqweFQ2w6NNznWMUvWV9AvkAfM6J8F/MC250Mb4n1I= +github.com/aws/aws-sdk-go-v2/service/ssm v1.67.4 h1:pOwUUY5FzKUsxtxGR6qsczZP7MuZMVlMbAOPQOcmJlo= +github.com/aws/aws-sdk-go-v2/service/ssm v1.67.4/go.mod h1:+nlWvcgDPQ56mChEBzTC0puAMck+4onOFaHg5cE+Lgg= github.com/aws/aws-sdk-go-v2/service/sso v1.30.16 h1:x6bKbmDhsgSZwv6q19wY/u3rLk/3FGjJWyqKcIRufpE= github.com/aws/aws-sdk-go-v2/service/sso v1.30.16/go.mod h1:CudnEVKRtLn0+3uMV0yEXZ+YZOKnAtUJ5DmDhilVnIw= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 h1:oK/njaL8GtyEihkWMD4k3VgHCT64RQKkZwh0DG5j8ak= @@ -154,18 +254,28 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3 github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= +github.com/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= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= +github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE= +github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/compose-spec/compose-go/v2 v2.10.2 h1:USa1NUbDcl/cjb8T9iwnuFsnO79H+2ho2L5SjFKz3uI= github.com/compose-spec/compose-go/v2 v2.10.2/go.mod h1:ZU6zlcweCZKyiB7BVfCizQT9XmkEIMFE+PRZydVcsZg= github.com/containerd/cgroups/v3 v3.1.3 h1:eUNflyMddm18+yrDmZPn3jI7C5hJ9ahABE5q6dyLYXQ= @@ -215,6 +325,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= 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-20231217203849-220c5c2851b7 h1:lxmTCgmHE1GUYL7P0MlNa00M67axePTq+9nBSGddR8I= @@ -249,22 +360,37 @@ github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203 h1:XBBHcIb256gUJtLmY22n99HaZTz+r2Z51xUPi01m3wg= github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203/go.mod h1:E1jcSv8FaEny+OP/5k9UxZVw9YFWGj7eI4KR/iOBqCg= +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= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4= github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fsnotify/fsevents v0.2.0 h1:BRlvlqjvNTfogHfeBOFvSC9N0Ddy+wzQCQukyoD7o/c= github.com/fsnotify/fsevents v0.2.0/go.mod h1:B3eEk39i4hz8y1zaWS/wPrAP4O6wkIl7HQwKBr1qH/w= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -316,6 +442,8 @@ github.com/go-openapi/swag/yamlutils v0.25.5 h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT github.com/go-openapi/swag/yamlutils v0.25.5/go.mod h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ= github.com/go-openapi/validate v0.25.2 h1:12NsfLAwGegqbGWr2CnvT65X/Q2USJipmJ9b7xDJZz0= github.com/go-openapi/validate v0.25.2/go.mod h1:Pgl1LpPPGFnZ+ys4/hTlDiRYQdI1ocKypgE+8Q8BLfY= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-zookeeper/zk v1.0.4 h1:DPzxraQx7OrPyXq2phlGlNSIyWEsAox0RJmjTseMV6I= @@ -330,14 +458,61 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +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/certificate-transparency-go v1.3.2 h1:9ahSNZF2o7SYMaKaXhAumVEzXB2QaayzII9C8rv7v+A= github.com/google/certificate-transparency-go v1.3.2/go.mod h1:H5FpMUaGa5Ab2+KCYsxg6sELw3Flkl7pGZzWdBoYLXs= github.com/google/flatbuffers v25.12.19+incompatible h1:haMV2JRRJCe1998HeW/p0X9UaMTK6SDo0ffLn2+DbLs= github.com/google/flatbuffers v25.12.19+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +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= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -347,20 +522,40 @@ github.com/google/go-replayers/grpcreplay v1.3.0 h1:1Keyy0m1sIpqstQmgz307zhiJ1pV github.com/google/go-replayers/grpcreplay v1.3.0/go.mod h1:v6NgKtkijC0d3e3RW8il6Sy5sqRVUwoQa4mHOGEy8DI= github.com/google/go-replayers/httpreplay v1.2.0 h1:VM1wEyyjaoU53BwrOnaf9VhAyQQEEioJvFYxYcLRKzk= github.com/google/go-replayers/httpreplay v1.2.0/go.mod h1:WahEFFZZ7a1P4VM1qEeHy+tME4bwyqPcwWbNlUI1Mcg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY= github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.7.0 h1:JxUKI6+CVBgCO2WToKy/nQk0sS+amI9z9EjVmdaocj4= github.com/google/wire v0.7.0/go.mod h1:n6YbUQD9cPKTnHXEBN2DXlOp/mVADhVErcMFb0v3J18= github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA6RlzjJaT4hi3kII+zYw8wmLb8= github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= +github.com/googleapis/gax-go/v2 v2.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.21.0 h1:h45NjjzEO3faG9Lg/cFrBh2PgegVVgzqKzuZl/wMbiI= github.com/googleapis/gax-go/v2 v2.21.0/go.mod h1:But/NJU6TnZsrLai/xBAQLLz+Hc7fHZJt/hsCz3Fih4= github.com/gookit/assert v0.1.1 h1:lh3GcawXe/p+cU7ESTZ5Ui3Sm/x8JWpIis4/1aF0mY0= @@ -382,8 +577,13 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA= github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/in-toto/attestation v1.1.2 h1:MBFn6lsMq6dptQZJBhalXTcWMb/aJy3V+GX3VYj/V1E= github.com/in-toto/attestation v1.1.2/go.mod h1:gYFddHMZj3DiQ0b62ltNi1Vj5rC879bTmBbrv9CRHpM= github.com/in-toto/in-toto-golang v0.10.0 h1:+s2eZQSK3WmWfYV85qXVSBfqgawi/5L02MaqA4o/tpM= @@ -394,8 +594,16 @@ github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaB github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +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/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -507,6 +715,7 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= @@ -527,6 +736,7 @@ github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPK github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -570,6 +780,7 @@ github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= @@ -642,8 +853,11 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= @@ -651,10 +865,19 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/detectors/aws/ec2 v1.38.0 h1:gSqtaXUzONG+J3PutTnKpLVLpKLsX+FztJwxSFQ15PU= +go.opentelemetry.io/contrib/detectors/aws/ec2 v1.38.0/go.mod h1:AqLDNPbKVFwdXy2/Xu2EYElVHO7ghhbEhKCCWymjpMI= go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE= go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 h1:yI1/OhfEPy7J9eoa6Sj051C7n5dvpj0QX8g4sRchg04= @@ -663,6 +886,8 @@ go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0. go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0/go.mod h1:rjbQTDEPQymPE0YnRQp9/NuPwwtL0sesz/fnqRW/v84= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= +go.opentelemetry.io/contrib/propagators/aws v1.38.0 h1:eRZ7asSbLc5dH7+TBzL6hFKb1dabz0IV51uUUwYRZts= +go.opentelemetry.io/contrib/propagators/aws v1.38.0/go.mod h1:wXqc9NTGcXapBExHBDVLEZlByu6quiQL8w7Tjgv8TCg= go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 h1:MdKucPl/HbzckWWEisiNqMPhRrAOQX8r4jTuGr636gk= @@ -691,55 +916,179 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go.yaml.in/yaml/v4 v4.0.0-rc.4 h1:UP4+v6fFrBIb1l934bDl//mmnoIZEDK0idg1+AIvX5U= go.yaml.in/yaml/v4 v4.0.0-rc.4/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= -gocloud.dev v0.45.0 h1:WknIK8IbRdmynDvara3Q7G6wQhmEiOGwpgJufbM39sY= -gocloud.dev v0.45.0/go.mod h1:0kXKmkCLG6d31N7NyLZWzt7jDSQura9zD/mWgiB6THI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +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-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= +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= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +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-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= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/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.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-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.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -759,19 +1108,74 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.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.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= @@ -784,32 +1188,149 @@ golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhS golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +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.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.276.0 h1:nVArUtfLEihtW+b0DdcqRGK1xoEm2+ltAihyztq7MKY= google.golang.org/api v0.276.0/go.mod h1:Fnag/EWUPIcJXuIkP1pjoTgS5vdxlk3eeemL7Do6bvw= +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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +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= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0= google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I= google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA= google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M= google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg= google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +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= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +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.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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= modernc.org/cc/v4 v4.27.3 h1:uNCgn37E5U09mTv1XgskEVUJ8ADKpmFMPxzGJ0TSo+U= modernc.org/cc/v4 v4.27.3/go.mod h1:3YjcbCqhoTTHPycJDRl2WZKKFj0nwcOIPBfEZK0Hdk8= modernc.org/ccgo/v4 v4.32.4 h1:L5OB8rpEX4ZsXEQwGozRfJyJSFHbbNVOoQ59DU9/KuU= @@ -840,5 +1361,8 @@ modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= tags.cncf.io/container-device-interface v1.1.0 h1:RnxNhxF1JOu6CJUVpetTYvrXHdxw9j9jFYgZpI+anSY= tags.cncf.io/container-device-interface v1.1.0/go.mod h1:76Oj0Yqp9FwTx/pySDc8Bxjpg+VqXfDb50cKAXVJ34Q= diff --git a/initialize-fork.sh b/initialize-fork.sh new file mode 100755 index 000000000..15475eb87 --- /dev/null +++ b/initialize-fork.sh @@ -0,0 +1,30 @@ +#!/bin/zsh + +if [ ! -d "./go-cloud" ]; then + # Update the version if it gets updated upstream + git subtree add --prefix=go-cloud git@github.com:google/go-cloud.git v0.43.0 + # Remove the go module definition to make go-cloud dev a sub-package + git rm go-cloud/go.* +fi + +# Delete some workflows because that don't apply to the fork +git rm .github/workflows/rc.yml +git rm .github/workflows/license_check.yml +git rm .github/workflows/go-release-docs.yml +git rm .github/workflows/labeler.yml +git rm .github/labeler.yml + +# Rename module and update all self-referencing imports +go mod edit -module github.com/DataDog/iceberg-go +go run github.com/sirkon/go-imports-rename@latest --save 'github.com/apache/iceberg-go => github.com/DataDog/iceberg-go' + +# Apply a patch for link directives +find . -name '*.go' -print0 | while IFS= read -r -d '' file; do + sed -i '' '/^\/\/go:linkname/ s,github.com/apache/iceberg-go,github.com/DataDog/iceberg-go,g' "$file" +done + +# Replace all gocloud.dev import paths to the inlined subtree of the repo (effectivement vendoring gocloud.dev) +go run github.com/sirkon/go-imports-rename@latest --save 'gocloud.dev => github.com/DataDog/iceberg-go/go-cloud' + +# Tidy up the dependencies +go mod tidy diff --git a/internal/mock_fs.go b/internal/mock_fs.go index 8e55fe085..85626b43d 100644 --- a/internal/mock_fs.go +++ b/internal/mock_fs.go @@ -23,7 +23,7 @@ import ( sio "io" "io/fs" - "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go/io" "github.com/stretchr/testify/mock" ) diff --git a/internal/utils_test.go b/internal/utils_test.go index 236c5b1d7..a9d9ce907 100644 --- a/internal/utils_test.go +++ b/internal/utils_test.go @@ -21,7 +21,7 @@ import ( "math" "testing" - "github.com/apache/iceberg-go/internal" + "github.com/DataDog/iceberg-go/internal" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/io/gocloud/azure.go b/io/gocloud/azure.go index 06da2e2c9..96ab0c85c 100644 --- a/io/gocloud/azure.go +++ b/io/gocloud/azure.go @@ -28,9 +28,9 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container" - "github.com/apache/iceberg-go/io" - "gocloud.dev/blob" - "gocloud.dev/blob/azureblob" + "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/azureblob" ) // adlsURIPattern is taken from the Java implementation: diff --git a/io/gocloud/azure_integration_test.go b/io/gocloud/azure_integration_test.go index cd6998400..5edbff9a6 100644 --- a/io/gocloud/azure_integration_test.go +++ b/io/gocloud/azure_integration_test.go @@ -26,14 +26,14 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - sqlcat "github.com/apache/iceberg-go/catalog/sql" - "github.com/apache/iceberg-go/io" - _ "github.com/apache/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + sqlcat "github.com/DataDog/iceberg-go/catalog/sql" + "github.com/DataDog/iceberg-go/io" + _ "github.com/DataDog/iceberg-go/io/gocloud" "github.com/stretchr/testify/suite" "github.com/uptrace/bun/driver/sqliteshim" - "gocloud.dev/blob/azureblob" + "github.com/DataDog/iceberg-go/go-cloud/blob/azureblob" ) const ( diff --git a/io/gocloud/blob.go b/io/gocloud/blob.go index 8fdf8b2ff..8f17b39a5 100644 --- a/io/gocloud/blob.go +++ b/io/gocloud/blob.go @@ -27,9 +27,9 @@ import ( "path/filepath" "strings" - icebergio "github.com/apache/iceberg-go/io" - "gocloud.dev/blob" - "gocloud.dev/gcerrors" + icebergio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/gcerrors" ) // blobOpenFile describes a single open blob as a File. diff --git a/io/gocloud/blob_test.go b/io/gocloud/blob_test.go index be4109107..ef1bfb7d7 100644 --- a/io/gocloud/blob_test.go +++ b/io/gocloud/blob_test.go @@ -26,8 +26,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - icebergio "github.com/apache/iceberg-go/io" - "gocloud.dev/blob/memblob" + icebergio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/go-cloud/blob/memblob" ) func TestDefaultKeyExtractor(t *testing.T) { diff --git a/io/gocloud/gcs.go b/io/gocloud/gcs.go index 96e5e1dc4..da534cf1c 100644 --- a/io/gocloud/gcs.go +++ b/io/gocloud/gcs.go @@ -23,10 +23,10 @@ import ( "cloud.google.com/go/storage" - "github.com/apache/iceberg-go/io" - "gocloud.dev/blob" - "gocloud.dev/blob/gcsblob" - "gocloud.dev/gcp" + "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/gcsblob" + "github.com/DataDog/iceberg-go/go-cloud/gcp" "google.golang.org/api/option" ) diff --git a/io/gocloud/gcs_integration_test.go b/io/gocloud/gcs_integration_test.go index 0b86628df..ffd4f87ad 100644 --- a/io/gocloud/gcs_integration_test.go +++ b/io/gocloud/gcs_integration_test.go @@ -28,11 +28,11 @@ import ( "net/url" "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - sqlcat "github.com/apache/iceberg-go/catalog/sql" - "github.com/apache/iceberg-go/io" - _ "github.com/apache/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + sqlcat "github.com/DataDog/iceberg-go/catalog/sql" + "github.com/DataDog/iceberg-go/io" + _ "github.com/DataDog/iceberg-go/io/gocloud" "github.com/stretchr/testify/suite" "github.com/uptrace/bun/driver/sqliteshim" ) diff --git a/io/gocloud/mem_test.go b/io/gocloud/mem_test.go index a7d536ba2..6eef72b3a 100644 --- a/io/gocloud/mem_test.go +++ b/io/gocloud/mem_test.go @@ -22,8 +22,8 @@ import ( "io" "testing" - icebergio "github.com/apache/iceberg-go/io" - _ "github.com/apache/iceberg-go/io/gocloud" + icebergio "github.com/DataDog/iceberg-go/io" + _ "github.com/DataDog/iceberg-go/io/gocloud" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/io/gocloud/register.go b/io/gocloud/register.go index 7c2b48580..bb2b94143 100644 --- a/io/gocloud/register.go +++ b/io/gocloud/register.go @@ -21,8 +21,8 @@ import ( "context" "net/url" - icebergio "github.com/apache/iceberg-go/io" - "gocloud.dev/blob/memblob" + icebergio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/go-cloud/blob/memblob" ) func init() { diff --git a/io/gocloud/s3.go b/io/gocloud/s3.go index 52d7e60ca..eaa9be1a9 100644 --- a/io/gocloud/s3.go +++ b/io/gocloud/s3.go @@ -27,16 +27,16 @@ import ( "slices" "strconv" - "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/utils" + "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/utils" "github.com/aws/aws-sdk-go-v2/aws" awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/smithy-go/auth/bearer" - "gocloud.dev/blob" - "gocloud.dev/blob/s3blob" + "github.com/DataDog/iceberg-go/go-cloud/blob" + "github.com/DataDog/iceberg-go/go-cloud/blob/s3blob" ) var unsupportedS3Props = []string{ diff --git a/io/gocloud/s3_integration_test.go b/io/gocloud/s3_integration_test.go index c3197edda..a3dd5e2ce 100644 --- a/io/gocloud/s3_integration_test.go +++ b/io/gocloud/s3_integration_test.go @@ -23,13 +23,13 @@ import ( "context" "testing" - "github.com/apache/iceberg-go/internal/recipe" + "github.com/DataDog/iceberg-go/internal/recipe" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - sqlcat "github.com/apache/iceberg-go/catalog/sql" - "github.com/apache/iceberg-go/io" - _ "github.com/apache/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + sqlcat "github.com/DataDog/iceberg-go/catalog/sql" + "github.com/DataDog/iceberg-go/io" + _ "github.com/DataDog/iceberg-go/io/gocloud" "github.com/stretchr/testify/require" "github.com/uptrace/bun/driver/sqliteshim" ) diff --git a/io/gocloud/s3_test.go b/io/gocloud/s3_test.go index 73d744de9..55ff762cc 100644 --- a/io/gocloud/s3_test.go +++ b/io/gocloud/s3_test.go @@ -21,7 +21,7 @@ import ( "context" "testing" - "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go/io" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/io/registry_test.go b/io/registry_test.go index bb257daa2..cdfdc52e9 100644 --- a/io/registry_test.go +++ b/io/registry_test.go @@ -22,8 +22,8 @@ import ( "net/url" "testing" - "github.com/apache/iceberg-go/io" - _ "github.com/apache/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go/io" + _ "github.com/DataDog/iceberg-go/io/gocloud" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/literals_test.go b/literals_test.go index 3ba9f3964..c7de3091a 100644 --- a/literals_test.go +++ b/literals_test.go @@ -25,7 +25,7 @@ import ( "github.com/apache/arrow-go/v18/arrow" "github.com/apache/arrow-go/v18/arrow/decimal128" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/manifest.go b/manifest.go index da781c8f8..2e0fe16bc 100644 --- a/manifest.go +++ b/manifest.go @@ -32,8 +32,8 @@ import ( "time" "github.com/apache/arrow-go/v18/arrow/decimal128" - "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" "github.com/google/uuid" "github.com/twmb/avro" "github.com/twmb/avro/atype" diff --git a/manifest_test.go b/manifest_test.go index 64407b749..3567ed26b 100644 --- a/manifest_test.go +++ b/manifest_test.go @@ -27,7 +27,7 @@ import ( "testing" "time" - "github.com/apache/iceberg-go/internal" + "github.com/DataDog/iceberg-go/internal" "github.com/stretchr/testify/suite" "github.com/twmb/avro" "github.com/twmb/avro/ocf" diff --git a/name_mapping.go b/name_mapping.go index e87f6c5e3..6bb79738d 100644 --- a/name_mapping.go +++ b/name_mapping.go @@ -23,7 +23,7 @@ import ( "strconv" "strings" - "github.com/apache/iceberg-go/internal" + "github.com/DataDog/iceberg-go/internal" ) type MappedField struct { diff --git a/name_mapping_test.go b/name_mapping_test.go index 973225218..5107d9814 100644 --- a/name_mapping_test.go +++ b/name_mapping_test.go @@ -21,7 +21,7 @@ import ( "encoding/json" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/partitions_bench_test.go b/partitions_bench_test.go index 794ce8e1d..7d7bbf08e 100644 --- a/partitions_bench_test.go +++ b/partitions_bench_test.go @@ -20,7 +20,7 @@ package iceberg_test import ( "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" ) // BenchmarkPartitionToPath benchmarks the optimized PartitionToPath function diff --git a/partitions_test.go b/partitions_test.go index 05b0546bf..6ab08d7b6 100644 --- a/partitions_test.go +++ b/partitions_test.go @@ -21,7 +21,7 @@ import ( "encoding/json" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/puffin/puffin_test.go b/puffin/puffin_test.go index 2752e15fd..21c40b46d 100644 --- a/puffin/puffin_test.go +++ b/puffin/puffin_test.go @@ -24,7 +24,7 @@ import ( "path" "testing" - "github.com/apache/iceberg-go/puffin" + "github.com/DataDog/iceberg-go/puffin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/puffin/puffin_writer.go b/puffin/puffin_writer.go index fd0a39dd9..3675398ec 100644 --- a/puffin/puffin_writer.go +++ b/puffin/puffin_writer.go @@ -24,7 +24,7 @@ import ( "io" "math" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" ) // Writer writes blobs and metadata to a Puffin file. diff --git a/schema_conversions.go b/schema_conversions.go index 705634266..dd225619e 100644 --- a/schema_conversions.go +++ b/schema_conversions.go @@ -20,7 +20,7 @@ package iceberg import ( "fmt" - "github.com/apache/iceberg-go/internal" + "github.com/DataDog/iceberg-go/internal" "github.com/twmb/avro" "github.com/twmb/avro/atype" ) diff --git a/schema_conversions_test.go b/schema_conversions_test.go index 74d32a12b..d2bba0c5a 100644 --- a/schema_conversions_test.go +++ b/schema_conversions_test.go @@ -21,7 +21,7 @@ import ( "fmt" "testing" - "github.com/apache/iceberg-go/internal" + "github.com/DataDog/iceberg-go/internal" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/twmb/avro" diff --git a/schema_test.go b/schema_test.go index 0ae676b32..d06fcaeb6 100644 --- a/schema_test.go +++ b/schema_test.go @@ -22,7 +22,7 @@ import ( "strings" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/table/addfiles_merge_regression_test.go b/table/addfiles_merge_regression_test.go index 00ab419b1..ae8a3c83d 100644 --- a/table/addfiles_merge_regression_test.go +++ b/table/addfiles_merge_regression_test.go @@ -43,9 +43,9 @@ import ( "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/arrow_scanner.go b/table/arrow_scanner.go index 51c85c12b..cc81de128 100644 --- a/table/arrow_scanner.go +++ b/table/arrow_scanner.go @@ -30,11 +30,11 @@ import ( "github.com/apache/arrow-go/v18/arrow/compute" "github.com/apache/arrow-go/v18/arrow/compute/exprs" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" - iceinternal "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table/internal" - "github.com/apache/iceberg-go/table/substrait" + "github.com/DataDog/iceberg-go" + iceinternal "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go/table/substrait" "github.com/substrait-io/substrait-go/v8/expr" "golang.org/x/sync/errgroup" ) diff --git a/table/arrow_utils.go b/table/arrow_utils.go index 1b3a742f9..2674c6869 100644 --- a/table/arrow_utils.go +++ b/table/arrow_utils.go @@ -36,11 +36,11 @@ import ( "github.com/apache/arrow-go/v18/arrow/extensions" "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/arrow/scalar" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/config" - "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" - tblutils "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/config" + "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" + tblutils "github.com/DataDog/iceberg-go/table/internal" "github.com/google/uuid" "github.com/pterm/pterm" "golang.org/x/sync/errgroup" diff --git a/table/arrow_utils_internal_test.go b/table/arrow_utils_internal_test.go index ed646e0d5..4681cdac9 100644 --- a/table/arrow_utils_internal_test.go +++ b/table/arrow_utils_internal_test.go @@ -30,8 +30,8 @@ import ( "github.com/apache/arrow-go/v18/parquet/file" "github.com/apache/arrow-go/v18/parquet/metadata" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table/internal" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" diff --git a/table/arrow_utils_test.go b/table/arrow_utils_test.go index 5e3aea2eb..f3dd10237 100644 --- a/table/arrow_utils_test.go +++ b/table/arrow_utils_test.go @@ -31,8 +31,8 @@ import ( "github.com/apache/arrow-go/v18/arrow/decimal128" "github.com/apache/arrow-go/v18/arrow/extensions" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/table/commit_retry_test.go b/table/commit_retry_test.go index 59dcadc47..7e9385bb6 100644 --- a/table/commit_retry_test.go +++ b/table/commit_retry_test.go @@ -26,8 +26,8 @@ import ( "testing" "time" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/commit_test.go b/table/commit_test.go index 4f0abdd8a..f7eecd982 100644 --- a/table/commit_test.go +++ b/table/commit_test.go @@ -20,8 +20,8 @@ package table_test import ( "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/commit_validation_test.go b/table/commit_validation_test.go index 232d8ebb6..98ebba519 100644 --- a/table/commit_validation_test.go +++ b/table/commit_validation_test.go @@ -29,8 +29,8 @@ import ( "sync/atomic" "testing" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/compaction/analyze.go b/table/compaction/analyze.go index 9513836a3..14ee34a4f 100644 --- a/table/compaction/analyze.go +++ b/table/compaction/analyze.go @@ -21,7 +21,7 @@ import ( "context" "fmt" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go/table" ) // Analyze scans the table and produces a compaction Plan without diff --git a/table/compaction/analyze_test.go b/table/compaction/analyze_test.go index 3609b91eb..a484b3035 100644 --- a/table/compaction/analyze_test.go +++ b/table/compaction/analyze_test.go @@ -29,10 +29,10 @@ import ( "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/parquet" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/table/compaction" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/table/compaction" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/compaction/compaction.go b/table/compaction/compaction.go index ed3ddb1fc..e26ef24c3 100644 --- a/table/compaction/compaction.go +++ b/table/compaction/compaction.go @@ -21,8 +21,8 @@ package compaction import ( "fmt" - "github.com/apache/iceberg-go/internal" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go/internal" + "github.com/DataDog/iceberg-go/table" ) // Config holds tunable thresholds for bin-pack compaction. diff --git a/table/compaction/compaction_test.go b/table/compaction/compaction_test.go index 766249fa1..8c53b551a 100644 --- a/table/compaction/compaction_test.go +++ b/table/compaction/compaction_test.go @@ -22,9 +22,9 @@ import ( "strconv" "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/table/compaction" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/table/compaction" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/conflict_validation.go b/table/conflict_validation.go index f0d89f95e..78586f0fa 100644 --- a/table/conflict_validation.go +++ b/table/conflict_validation.go @@ -51,8 +51,8 @@ import ( "fmt" "sort" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" ) // IsolationLevel controls how strictly a commit rejects concurrent diff --git a/table/conflict_validation_test.go b/table/conflict_validation_test.go index 767a1d57a..aecc9ca45 100644 --- a/table/conflict_validation_test.go +++ b/table/conflict_validation_test.go @@ -21,7 +21,7 @@ import ( "errors" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/dv_scan_planning_test.go b/table/dv_scan_planning_test.go index fe6ebe686..919d538a4 100644 --- a/table/dv_scan_planning_test.go +++ b/table/dv_scan_planning_test.go @@ -20,7 +20,7 @@ package table import ( "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" ) diff --git a/table/equality_delete_reader.go b/table/equality_delete_reader.go index 17edb342a..4e3ef7bc1 100644 --- a/table/equality_delete_reader.go +++ b/table/equality_delete_reader.go @@ -29,10 +29,10 @@ import ( "github.com/apache/arrow-go/v18/arrow/bitutil" "github.com/apache/arrow-go/v18/arrow/compute" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" - iceinternal "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + iceinternal "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table/internal" "golang.org/x/sync/errgroup" ) diff --git a/table/equality_delete_reader_test.go b/table/equality_delete_reader_test.go index fe07771de..a553b4748 100644 --- a/table/equality_delete_reader_test.go +++ b/table/equality_delete_reader_test.go @@ -23,9 +23,9 @@ import ( "testing" "github.com/apache/arrow-go/v18/arrow/array" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/equality_delete_writer.go b/table/equality_delete_writer.go index 18ec9ebd2..75ea57fc9 100644 --- a/table/equality_delete_writer.go +++ b/table/equality_delete_writer.go @@ -24,10 +24,10 @@ import ( "iter" "github.com/apache/arrow-go/v18/arrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/config" - "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/config" + "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" "github.com/google/uuid" ) diff --git a/table/equality_delete_writer_test.go b/table/equality_delete_writer_test.go index 9621e0ba9..19ccaaf66 100644 --- a/table/equality_delete_writer_test.go +++ b/table/equality_delete_writer_test.go @@ -29,9 +29,9 @@ import ( "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/parquet/file" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/evaluator_race_test.go b/table/evaluator_race_test.go index 5984ea017..95701aaab 100644 --- a/table/evaluator_race_test.go +++ b/table/evaluator_race_test.go @@ -14,7 +14,7 @@ import ( "sync" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" ) // TestManifestEvalVisitorEvalRace fans out 256 goroutines that all call the diff --git a/table/evaluators.go b/table/evaluators.go index 40aaad843..4099a1a5d 100644 --- a/table/evaluators.go +++ b/table/evaluators.go @@ -24,8 +24,8 @@ import ( "slices" "github.com/apache/arrow-go/v18/parquet/metadata" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table/internal" "github.com/google/uuid" ) diff --git a/table/evaluators_test.go b/table/evaluators_test.go index d949bd0e1..a50c55ce5 100644 --- a/table/evaluators_test.go +++ b/table/evaluators_test.go @@ -21,7 +21,7 @@ import ( "math" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" diff --git a/table/fanout_memory_bench_test.go b/table/fanout_memory_bench_test.go index 673a50e22..fa69f42bd 100644 --- a/table/fanout_memory_bench_test.go +++ b/table/fanout_memory_bench_test.go @@ -28,9 +28,9 @@ import ( "github.com/apache/arrow-go/v18/arrow" "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/table" ) // gatedReader is a RecordReader whose Next() blocks on a channel, giving diff --git a/table/internal/interfaces.go b/table/internal/interfaces.go index a38d70bea..b7c09728c 100644 --- a/table/internal/interfaces.go +++ b/table/internal/interfaces.go @@ -26,8 +26,8 @@ import ( "github.com/apache/arrow-go/v18/arrow" "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/compute" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" ) // GetFile opens the given file using the provided file system. diff --git a/table/internal/parquet_files.go b/table/internal/parquet_files.go index 72e0ef1ce..1c79a0762 100644 --- a/table/internal/parquet_files.go +++ b/table/internal/parquet_files.go @@ -39,9 +39,9 @@ import ( "github.com/apache/arrow-go/v18/parquet/file" "github.com/apache/arrow-go/v18/parquet/metadata" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" "github.com/google/uuid" ) diff --git a/table/internal/parquet_files_test.go b/table/internal/parquet_files_test.go index c2fb1a315..0eefc9b14 100644 --- a/table/internal/parquet_files_test.go +++ b/table/internal/parquet_files_test.go @@ -36,10 +36,10 @@ import ( "github.com/apache/arrow-go/v18/parquet/metadata" "github.com/apache/arrow-go/v18/parquet/pqarrow" "github.com/apache/arrow-go/v18/parquet/schema" - "github.com/apache/iceberg-go" - internal2 "github.com/apache/iceberg-go/internal" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + internal2 "github.com/DataDog/iceberg-go/internal" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/table/internal" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/table/internal/utils.go b/table/internal/utils.go index 4b13c0779..aa9974bd2 100644 --- a/table/internal/utils.go +++ b/table/internal/utils.go @@ -34,7 +34,7 @@ import ( "github.com/apache/arrow-go/v18/arrow/decimal" "github.com/apache/arrow-go/v18/arrow/decimal128" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/twmb/avro/atype" "golang.org/x/sync/errgroup" ) diff --git a/table/internal/utils_test.go b/table/internal/utils_test.go index 38bdbb54e..02b1e50d5 100644 --- a/table/internal/utils_test.go +++ b/table/internal/utils_test.go @@ -24,8 +24,8 @@ import ( "testing" "time" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table/internal" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/locations.go b/table/locations.go index 1047b46c6..4e9f742a8 100644 --- a/table/locations.go +++ b/table/locations.go @@ -24,7 +24,7 @@ import ( "strconv" "strings" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/google/uuid" "github.com/twmb/murmur3" ) diff --git a/table/locations_test.go b/table/locations_test.go index 8fa08bcf8..227e0fc14 100644 --- a/table/locations_test.go +++ b/table/locations_test.go @@ -21,8 +21,8 @@ import ( "strings" "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/table/metadata.go b/table/metadata.go index 48d667b59..0ce520a8e 100644 --- a/table/metadata.go +++ b/table/metadata.go @@ -30,8 +30,8 @@ import ( "strconv" "time" - "github.com/apache/iceberg-go" - iceinternal "github.com/apache/iceberg-go/internal" + "github.com/DataDog/iceberg-go" + iceinternal "github.com/DataDog/iceberg-go/internal" "github.com/google/uuid" ) diff --git a/table/metadata_builder_internal_test.go b/table/metadata_builder_internal_test.go index 4f8011275..0ae675707 100644 --- a/table/metadata_builder_internal_test.go +++ b/table/metadata_builder_internal_test.go @@ -23,7 +23,7 @@ import ( "testing" "time" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/davecgh/go-spew/spew" "github.com/google/uuid" "github.com/stretchr/testify/require" diff --git a/table/metadata_internal_test.go b/table/metadata_internal_test.go index 93571e40c..90911ec52 100644 --- a/table/metadata_internal_test.go +++ b/table/metadata_internal_test.go @@ -25,7 +25,7 @@ import ( "strings" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/davecgh/go-spew/spew" "github.com/google/go-cmp/cmp" "github.com/google/uuid" diff --git a/table/metadata_schema_compatibility.go b/table/metadata_schema_compatibility.go index 91fdb0cf0..449600a32 100644 --- a/table/metadata_schema_compatibility.go +++ b/table/metadata_schema_compatibility.go @@ -24,7 +24,7 @@ import ( "strconv" "strings" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" ) type ErrIncompatibleSchema struct { diff --git a/table/metadata_schema_compatibility_test.go b/table/metadata_schema_compatibility_test.go index 2fc5aca7a..ffa2a8e89 100644 --- a/table/metadata_schema_compatibility_test.go +++ b/table/metadata_schema_compatibility_test.go @@ -20,7 +20,7 @@ package table import ( "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/orphan_cleanup.go b/table/orphan_cleanup.go index 28e0adac1..fabaa9a79 100644 --- a/table/orphan_cleanup.go +++ b/table/orphan_cleanup.go @@ -30,7 +30,7 @@ import ( "sync" "time" - iceio "github.com/apache/iceberg-go/io" + iceio "github.com/DataDog/iceberg-go/io" ) // PrefixMismatchMode defines how to handle cases where candidate files have different diff --git a/table/orphan_cleanup_integration_test.go b/table/orphan_cleanup_integration_test.go index cce3fd0bb..0b2a37947 100644 --- a/table/orphan_cleanup_integration_test.go +++ b/table/orphan_cleanup_integration_test.go @@ -30,12 +30,12 @@ import ( "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/rest" - "github.com/apache/iceberg-go/io" - _ "github.com/apache/iceberg-go/io/gocloud" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/rest" + "github.com/DataDog/iceberg-go/io" + _ "github.com/DataDog/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/suite" ) diff --git a/table/orphan_cleanup_test.go b/table/orphan_cleanup_test.go index a3b2cb236..ca620e17a 100644 --- a/table/orphan_cleanup_test.go +++ b/table/orphan_cleanup_test.go @@ -23,7 +23,7 @@ import ( "testing" "time" - "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go/io" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/partitioned_fanout_writer.go b/table/partitioned_fanout_writer.go index a11c37eaa..c7f5156cd 100644 --- a/table/partitioned_fanout_writer.go +++ b/table/partitioned_fanout_writer.go @@ -28,7 +28,7 @@ import ( "github.com/apache/arrow-go/v18/arrow/compute" "github.com/apache/arrow-go/v18/arrow/decimal128" "github.com/apache/arrow-go/v18/arrow/extensions" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "golang.org/x/sync/errgroup" ) diff --git a/table/partitioned_fanout_writer_test.go b/table/partitioned_fanout_writer_test.go index 0e602359b..1fc035d4d 100644 --- a/table/partitioned_fanout_writer_test.go +++ b/table/partitioned_fanout_writer_test.go @@ -31,10 +31,10 @@ import ( arrowdecimal "github.com/apache/arrow-go/v18/arrow/decimal" "github.com/apache/arrow-go/v18/arrow/extensions" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/config" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/config" - iceio "github.com/apache/iceberg-go/io" + iceio "github.com/DataDog/iceberg-go/io" "github.com/google/uuid" "github.com/stretchr/testify/suite" ) diff --git a/table/partitioned_throughput_bench_test.go b/table/partitioned_throughput_bench_test.go index c85432775..c4aec4cb6 100644 --- a/table/partitioned_throughput_bench_test.go +++ b/table/partitioned_throughput_bench_test.go @@ -26,10 +26,10 @@ import ( "github.com/apache/arrow-go/v18/arrow" "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/table/internal" ) // Common benchmark configuration diff --git a/table/pos_delete_partitioned_fanout_writer.go b/table/pos_delete_partitioned_fanout_writer.go index fe54dba98..ad860711c 100644 --- a/table/pos_delete_partitioned_fanout_writer.go +++ b/table/pos_delete_partitioned_fanout_writer.go @@ -24,7 +24,7 @@ import ( "github.com/apache/arrow-go/v18/arrow" "github.com/apache/arrow-go/v18/arrow/array" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "golang.org/x/sync/errgroup" ) diff --git a/table/pos_delete_partitioned_fanout_writer_test.go b/table/pos_delete_partitioned_fanout_writer_test.go index 0b379700c..2d3f6a39f 100644 --- a/table/pos_delete_partitioned_fanout_writer_test.go +++ b/table/pos_delete_partitioned_fanout_writer_test.go @@ -29,9 +29,9 @@ import ( "time" "github.com/apache/arrow-go/v18/arrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/internal" - "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/internal" + "github.com/DataDog/iceberg-go/io" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/table/producer_validate_test.go b/table/producer_validate_test.go index 65bd6c1a8..ddf6b59a4 100644 --- a/table/producer_validate_test.go +++ b/table/producer_validate_test.go @@ -27,7 +27,7 @@ package table import ( "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/properties.go b/table/properties.go index 196a402e9..163d1b7c0 100644 --- a/table/properties.go +++ b/table/properties.go @@ -20,7 +20,7 @@ package table import ( "math" - "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go/table/internal" ) const ( diff --git a/table/read_perf_deletes_test.go b/table/read_perf_deletes_test.go index 350edeed1..c99fd0470 100644 --- a/table/read_perf_deletes_test.go +++ b/table/read_perf_deletes_test.go @@ -28,9 +28,9 @@ import ( "github.com/apache/arrow-go/v18/arrow" "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/require" ) diff --git a/table/refs_test.go b/table/refs_test.go index afbde119d..5c28522d2 100644 --- a/table/refs_test.go +++ b/table/refs_test.go @@ -21,7 +21,7 @@ import ( "encoding/json" "testing" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" ) diff --git a/table/replace_files_test.go b/table/replace_files_test.go index c97eb1b34..ea2187e16 100644 --- a/table/replace_files_test.go +++ b/table/replace_files_test.go @@ -23,9 +23,9 @@ import ( "path/filepath" "testing" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/requirement_test.go b/table/requirement_test.go index 2fe4e23bc..f457da613 100644 --- a/table/requirement_test.go +++ b/table/requirement_test.go @@ -21,7 +21,7 @@ import ( "encoding/json" "testing" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go/table" "github.com/google/uuid" "github.com/stretchr/testify/assert" ) diff --git a/table/rewrite_data_files.go b/table/rewrite_data_files.go index 0e36ca07e..5c13dd767 100644 --- a/table/rewrite_data_files.go +++ b/table/rewrite_data_files.go @@ -21,7 +21,7 @@ import ( "context" "fmt" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" ) // RewriteResult summarizes a completed compaction. diff --git a/table/rewrite_data_files_test.go b/table/rewrite_data_files_test.go index 3db69760c..a9395a2e5 100644 --- a/table/rewrite_data_files_test.go +++ b/table/rewrite_data_files_test.go @@ -27,10 +27,10 @@ import ( "github.com/apache/arrow-go/v18/arrow" "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/table/compaction" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/table/compaction" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/rolling_data_writer.go b/table/rolling_data_writer.go index 3bec7cbb8..aa2b363b4 100644 --- a/table/rolling_data_writer.go +++ b/table/rolling_data_writer.go @@ -27,9 +27,9 @@ import ( "sync/atomic" "github.com/apache/arrow-go/v18/arrow" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" - tblutils "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" + tblutils "github.com/DataDog/iceberg-go/table/internal" "github.com/google/uuid" ) diff --git a/table/rolling_data_writer_test.go b/table/rolling_data_writer_test.go index fc5c00612..509febe4b 100644 --- a/table/rolling_data_writer_test.go +++ b/table/rolling_data_writer_test.go @@ -26,9 +26,9 @@ import ( "github.com/apache/arrow-go/v18/arrow" "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" - tblutils "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" + tblutils "github.com/DataDog/iceberg-go/table/internal" "github.com/google/uuid" "github.com/stretchr/testify/suite" ) diff --git a/table/row_delta.go b/table/row_delta.go index f73b45a3c..3913f424f 100644 --- a/table/row_delta.go +++ b/table/row_delta.go @@ -22,8 +22,8 @@ import ( "errors" "fmt" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" ) // RowDelta encodes a set of row-level changes to a table: new data files diff --git a/table/row_delta_test.go b/table/row_delta_test.go index 054895610..7fe41814a 100644 --- a/table/row_delta_test.go +++ b/table/row_delta_test.go @@ -30,9 +30,9 @@ import ( "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/parquet" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/scanner.go b/table/scanner.go index a38116824..7d9fffcf3 100644 --- a/table/scanner.go +++ b/table/scanner.go @@ -28,8 +28,8 @@ import ( "github.com/apache/arrow-go/v18/arrow" "github.com/apache/arrow-go/v18/arrow/array" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/io" "golang.org/x/sync/errgroup" ) diff --git a/table/scanner_internal_test.go b/table/scanner_internal_test.go index d5808728f..ff224de2a 100644 --- a/table/scanner_internal_test.go +++ b/table/scanner_internal_test.go @@ -27,7 +27,7 @@ import ( "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/compute" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/scanner_test.go b/table/scanner_test.go index 11c8e205d..ef2385e51 100644 --- a/table/scanner_test.go +++ b/table/scanner_test.go @@ -33,13 +33,13 @@ import ( "github.com/apache/arrow-go/v18/arrow/compute" "github.com/apache/arrow-go/v18/arrow/extensions" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/rest" - "github.com/apache/iceberg-go/internal/recipe" - "github.com/apache/iceberg-go/io" - _ "github.com/apache/iceberg-go/io/gocloud" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/rest" + "github.com/DataDog/iceberg-go/internal/recipe" + "github.com/DataDog/iceberg-go/io" + _ "github.com/DataDog/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" ) diff --git a/table/snapshot_producers.go b/table/snapshot_producers.go index c98b7cb7f..4b0e2160c 100644 --- a/table/snapshot_producers.go +++ b/table/snapshot_producers.go @@ -27,11 +27,11 @@ import ( "sync/atomic" "time" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/config" - "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" - tblutils "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/config" + "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" + tblutils "github.com/DataDog/iceberg-go/table/internal" "github.com/google/uuid" "golang.org/x/sync/errgroup" ) diff --git a/table/snapshot_producers_test.go b/table/snapshot_producers_test.go index f43ea4c2f..4343f49d2 100644 --- a/table/snapshot_producers_test.go +++ b/table/snapshot_producers_test.go @@ -28,10 +28,10 @@ import ( "testing" "time" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" - _ "github.com/apache/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" + _ "github.com/DataDog/iceberg-go/io/gocloud" "github.com/stretchr/testify/require" ) diff --git a/table/snapshots.go b/table/snapshots.go index ef109b258..7bef62d54 100644 --- a/table/snapshots.go +++ b/table/snapshots.go @@ -27,9 +27,9 @@ import ( "strconv" "strings" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" ) type Operation string diff --git a/table/snapshots_internal_test.go b/table/snapshots_internal_test.go index 488287f81..d794ee110 100644 --- a/table/snapshots_internal_test.go +++ b/table/snapshots_internal_test.go @@ -20,7 +20,7 @@ package table import ( "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/snapshots_test.go b/table/snapshots_test.go index 0e4d3b7e7..3dde9ef33 100644 --- a/table/snapshots_test.go +++ b/table/snapshots_test.go @@ -21,7 +21,7 @@ import ( "encoding/json" "testing" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/sorting.go b/table/sorting.go index 09c198f10..f1384ce4a 100644 --- a/table/sorting.go +++ b/table/sorting.go @@ -25,7 +25,7 @@ import ( "slices" "strings" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" ) type SortDirection string diff --git a/table/sorting_test.go b/table/sorting_test.go index baeae0936..93fa485d5 100644 --- a/table/sorting_test.go +++ b/table/sorting_test.go @@ -21,8 +21,8 @@ import ( "encoding/json" "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/table/substrait/substrait.go b/table/substrait/substrait.go index 8bcc80c3f..8ef44661e 100644 --- a/table/substrait/substrait.go +++ b/table/substrait/substrait.go @@ -23,7 +23,7 @@ import ( "strings" "github.com/apache/arrow-go/v18/arrow/compute/exprs" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/substrait-io/substrait-go/v8/expr" "github.com/substrait-io/substrait-go/v8/extensions" "github.com/substrait-io/substrait-go/v8/types" diff --git a/table/substrait/substrait_test.go b/table/substrait/substrait_test.go index 6168b604a..8d5c36581 100644 --- a/table/substrait/substrait_test.go +++ b/table/substrait/substrait_test.go @@ -21,8 +21,8 @@ import ( "fmt" "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table/substrait" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table/substrait" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/substrait-io/substrait-go/v8/types" diff --git a/table/table.go b/table/table.go index 779f70fcb..48f3a3348 100644 --- a/table/table.go +++ b/table/table.go @@ -33,10 +33,10 @@ import ( "github.com/apache/arrow-go/v18/arrow" "github.com/apache/arrow-go/v18/arrow/array" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/internal" - icebergio "github.com/apache/iceberg-go/io" - tblutils "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/internal" + icebergio "github.com/DataDog/iceberg-go/io" + tblutils "github.com/DataDog/iceberg-go/table/internal" "golang.org/x/sync/errgroup" ) diff --git a/table/table_test.go b/table/table_test.go index 6913ea4bf..742e4a66b 100644 --- a/table/table_test.go +++ b/table/table_test.go @@ -43,12 +43,12 @@ import ( "github.com/apache/arrow-go/v18/arrow/compute" "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/sql" - "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/sql" + "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" "github.com/google/uuid" "github.com/pterm/pterm" "github.com/stretchr/testify/require" diff --git a/table/time_travel_test.go b/table/time_travel_test.go index d20548d1e..f9d556154 100644 --- a/table/time_travel_test.go +++ b/table/time_travel_test.go @@ -25,7 +25,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" ) func TestSnapshotAsOf(t *testing.T) { diff --git a/table/transaction.go b/table/transaction.go index 5a11ce598..800b6d403 100644 --- a/table/transaction.go +++ b/table/transaction.go @@ -32,10 +32,10 @@ import ( "github.com/apache/arrow-go/v18/arrow" "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/compute/exprs" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table/internal" - "github.com/apache/iceberg-go/table/substrait" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go/table/substrait" "github.com/google/uuid" "golang.org/x/sync/errgroup" ) diff --git a/table/transaction_test.go b/table/transaction_test.go index e0818fa71..e1f538569 100644 --- a/table/transaction_test.go +++ b/table/transaction_test.go @@ -30,13 +30,13 @@ import ( "github.com/apache/arrow-go/v18/arrow/memory" "github.com/apache/arrow-go/v18/parquet" "github.com/apache/arrow-go/v18/parquet/pqarrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/catalog" - "github.com/apache/iceberg-go/catalog/rest" - "github.com/apache/iceberg-go/internal/recipe" - iceio "github.com/apache/iceberg-go/io" - _ "github.com/apache/iceberg-go/io/gocloud" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/catalog" + "github.com/DataDog/iceberg-go/catalog/rest" + "github.com/DataDog/iceberg-go/internal/recipe" + iceio "github.com/DataDog/iceberg-go/io" + _ "github.com/DataDog/iceberg-go/io/gocloud" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/suite" "github.com/testcontainers/testcontainers-go/modules/compose" ) diff --git a/table/update_schema.go b/table/update_schema.go index d5bcc195a..ff4f3f5c4 100644 --- a/table/update_schema.go +++ b/table/update_schema.go @@ -24,7 +24,7 @@ import ( "slices" "strings" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" ) const TableRootID = -1 diff --git a/table/update_schema_test.go b/table/update_schema_test.go index 4ebd9f146..e907d069e 100644 --- a/table/update_schema_test.go +++ b/table/update_schema_test.go @@ -20,7 +20,7 @@ package table import ( "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" ) diff --git a/table/update_spec.go b/table/update_spec.go index 76aa19fb6..f799afb05 100644 --- a/table/update_spec.go +++ b/table/update_spec.go @@ -21,7 +21,7 @@ import ( "errors" "fmt" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" ) // UpdateSpec implements a builder for evolving a table's partition specification. diff --git a/table/update_spec_test.go b/table/update_spec_test.go index 0359490bc..3242707ba 100644 --- a/table/update_spec_test.go +++ b/table/update_spec_test.go @@ -20,8 +20,8 @@ package table_test import ( "testing" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" "github.com/stretchr/testify/assert" ) diff --git a/table/updates.go b/table/updates.go index dda9a5323..491d9c26f 100644 --- a/table/updates.go +++ b/table/updates.go @@ -25,8 +25,8 @@ import ( "maps" "slices" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/io" "github.com/google/uuid" ) diff --git a/table/updates_test.go b/table/updates_test.go index 480caf2fa..a988081f1 100644 --- a/table/updates_test.go +++ b/table/updates_test.go @@ -22,7 +22,7 @@ import ( "encoding/json" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/table/write_records.go b/table/write_records.go index f937e999f..7beeda01f 100644 --- a/table/write_records.go +++ b/table/write_records.go @@ -24,9 +24,9 @@ import ( "strconv" "github.com/apache/arrow-go/v18/arrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" "github.com/google/uuid" ) diff --git a/table/write_records_test.go b/table/write_records_test.go index 710c57689..e1b0dfb79 100644 --- a/table/write_records_test.go +++ b/table/write_records_test.go @@ -27,9 +27,9 @@ import ( "github.com/apache/arrow-go/v18/arrow/array" "github.com/apache/arrow-go/v18/arrow/compute" "github.com/apache/arrow-go/v18/arrow/memory" - "github.com/apache/iceberg-go" - iceio "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + iceio "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" "github.com/google/uuid" "github.com/stretchr/testify/suite" ) diff --git a/table/writer.go b/table/writer.go index 5e616f903..015017c83 100644 --- a/table/writer.go +++ b/table/writer.go @@ -24,10 +24,10 @@ import ( "strings" "github.com/apache/arrow-go/v18/arrow" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/config" - "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table/internal" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/config" + "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table/internal" "github.com/google/uuid" ) diff --git a/transforms_test.go b/transforms_test.go index d06ef262c..d39d5becc 100644 --- a/transforms_test.go +++ b/transforms_test.go @@ -27,7 +27,7 @@ import ( "github.com/apache/arrow-go/v18/arrow/decimal" "github.com/apache/arrow-go/v18/arrow/decimal128" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/types_test.go b/types_test.go index f3735343a..7ea41c915 100644 --- a/types_test.go +++ b/types_test.go @@ -21,7 +21,7 @@ import ( "encoding/json" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/view/metadata.go b/view/metadata.go index 06590c71d..948c7b1ac 100644 --- a/view/metadata.go +++ b/view/metadata.go @@ -29,10 +29,10 @@ import ( "sync" "time" - "github.com/apache/iceberg-go" - iceinternal "github.com/apache/iceberg-go/internal" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/view/internal" + "github.com/DataDog/iceberg-go" + iceinternal "github.com/DataDog/iceberg-go/internal" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/view/internal" "github.com/google/uuid" ) diff --git a/view/metadata_builder.go b/view/metadata_builder.go index 85b21b4df..dc0314ecd 100644 --- a/view/metadata_builder.go +++ b/view/metadata_builder.go @@ -26,8 +26,8 @@ import ( "strings" "time" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/view/internal" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/view/internal" "github.com/google/uuid" ) diff --git a/view/metadata_builder_test.go b/view/metadata_builder_test.go index 418fb05d0..68128e343 100644 --- a/view/metadata_builder_test.go +++ b/view/metadata_builder_test.go @@ -24,9 +24,9 @@ import ( "testing" "time" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/table" - "github.com/apache/iceberg-go/view/internal" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/table" + "github.com/DataDog/iceberg-go/view/internal" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/view/metadata_test.go b/view/metadata_test.go index 7561ac741..4b1b64551 100644 --- a/view/metadata_test.go +++ b/view/metadata_test.go @@ -24,7 +24,7 @@ import ( "slices" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/view/requirements.go b/view/requirements.go index 91af305ff..b33f14c59 100644 --- a/view/requirements.go +++ b/view/requirements.go @@ -23,7 +23,7 @@ import ( "fmt" "io" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go/table" "github.com/google/uuid" ) diff --git a/view/requirements_test.go b/view/requirements_test.go index 03865a832..88aee4ba2 100644 --- a/view/requirements_test.go +++ b/view/requirements_test.go @@ -21,7 +21,7 @@ import ( "encoding/json" "testing" - "github.com/apache/iceberg-go/view" + "github.com/DataDog/iceberg-go/view" "github.com/google/uuid" "github.com/stretchr/testify/assert" ) diff --git a/view/updates.go b/view/updates.go index e7c303a16..c3b632926 100644 --- a/view/updates.go +++ b/view/updates.go @@ -21,7 +21,7 @@ import ( "encoding/json" "fmt" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/google/uuid" ) diff --git a/view/updates_test.go b/view/updates_test.go index eb3b48f8d..5db178ae7 100644 --- a/view/updates_test.go +++ b/view/updates_test.go @@ -21,7 +21,7 @@ import ( "encoding/json" "testing" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/view/view.go b/view/view.go index 679d84264..dc353adac 100644 --- a/view/view.go +++ b/view/view.go @@ -24,10 +24,10 @@ import ( "fmt" "slices" - "github.com/apache/iceberg-go" - "github.com/apache/iceberg-go/internal" - "github.com/apache/iceberg-go/io" - "github.com/apache/iceberg-go/table" + "github.com/DataDog/iceberg-go" + "github.com/DataDog/iceberg-go/internal" + "github.com/DataDog/iceberg-go/io" + "github.com/DataDog/iceberg-go/table" "github.com/google/uuid" ) diff --git a/view/view_test.go b/view/view_test.go index 49b6fecb8..302836090 100644 --- a/view/view_test.go +++ b/view/view_test.go @@ -22,8 +22,8 @@ import ( "context" "testing" - "github.com/apache/iceberg-go/internal" - iceio "github.com/apache/iceberg-go/io" + "github.com/DataDog/iceberg-go/internal" + iceio "github.com/DataDog/iceberg-go/io" "github.com/stretchr/testify/suite" ) diff --git a/visitors_test.go b/visitors_test.go index ed18b48cd..d666f95f4 100644 --- a/visitors_test.go +++ b/visitors_test.go @@ -23,7 +23,7 @@ import ( "testing" "github.com/apache/arrow-go/v18/arrow/decimal128" - "github.com/apache/iceberg-go" + "github.com/DataDog/iceberg-go" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require"